def _get_webactions(self):
     if 'Manager' in api.user.get_roles():
         # Manager may always list all actions
         return get_storage().list()
     else:
         # Other users may only see their own
         return get_storage().list(owner=api.user.get_current().id)
 def _get_webactions(self):
     if 'Manager' in api.user.get_roles():
         # Manager may always list all actions
         return get_storage().list()
     else:
         # Other users may only see their own
         return get_storage().list(owner=api.user.get_current().id)
 def test_delete_webaction(self):
     storage = get_storage()
     action = create(Builder('webaction'))
     self.assertEqual(1, len(storage._actions))
     storage.delete(action['action_id'])
     self.assertEqual(0, len(storage._actions))
     self.assertEqual({}, dict(storage._actions))
    def test_update_webaction(self):
        self.login(self.manager)

        storage = get_storage()
        with freeze(datetime(2019, 12, 31, 17, 45)):
            action = create(Builder('webaction').titled(u'Open in ExternalApp')
                            .having(
                                title=u'Open in ExternalApp',
                                target_url='http://example.org/endpoint',
            ))
        action_id = action['action_id']
        self.assertEqual(action, storage.get(action_id))

        with freeze(datetime(2020, 7, 31, 19, 15)):
            storage.update(action_id, {'title': u'My new title'})

        self.assertIsInstance(storage.get(action_id), dict)
        self.assertEqual({
            'action_id': 0,
            'title': u'My new title',
            'target_url': 'http://example.org/endpoint',
            'display': 'actions-menu',
            'mode': 'self',
            'order': 0,
            'scope': 'global',
            'created': datetime(2019, 12, 31, 17, 45),
            'modified': datetime(2020, 7, 31, 19, 15),
            'owner': 'admin',
        }, storage.get(action_id))
    def test_can_update_webaction(self, browser):
        self.login(self.webaction_manager, browser=browser)

        with freeze(datetime(2019, 12, 31, 17, 45)):
            action = create(Builder('webaction')
                            .having(
                                title=u'Open in ExternalApp',
                                target_url='http://example.org/endpoint',
            ))
        url = '%s/@webactions/%s' % (self.portal.absolute_url(), action['action_id'])

        with freeze(datetime(2020, 7, 31, 19, 15)):
            browser.open(url, method='PATCH',
                         data=json.dumps({'title': u'My new title'}),
                         headers=self.HEADERS)

        self.assertEqual(204, browser.status_code)
        self.assertEqual('', browser.contents)

        storage = get_storage()
        self.assertEqual({
            'action_id': 0,
            'title': u'My new title',
            'target_url': 'http://example.org/endpoint',
            'display': 'actions-menu',
            'mode': 'self',
            'order': 0,
            'scope': 'global',
            'created': datetime(2019, 12, 31, 17, 45),
            'modified': datetime(2020, 7, 31, 19, 15),
            'owner': 'webaction.manager',
        }, storage.get(action['action_id']))
    def update(self, action):
        action_delta = json_body(self.request)

        # Reject any fields that aren't user-controlled or unknown
        errors = get_unknown_fields(action_delta, IWebActionSchema)
        if errors:
            raise BadRequest(errors)

        scrub_json_payload(action_delta)

        # Validate on a copy
        action_copy = action.copy()
        action_copy.update(action_delta)
        errors = get_validation_errors(action_copy, IPersistedWebActionSchema)
        if errors:
            raise BadRequest(errors)

        # If validation succeeded, update actual action
        storage = get_storage()

        try:
            storage.update(action['action_id'], action_delta)
        except ActionAlreadyExists as exc:
            raise BadRequest([('unique_name', exc)])

        self.request.response.setStatus(204)
        return _no_content_marker
Example #7
0
    def applyChanges(self, data):
        # Based on z3c.form.form.applyChanges, but without firing events
        # and modifying the webaction in its storage.
        webaction = self.get_webaction()
        changes = {}
        webaction_data = {}
        for name, field in self.fields.items():
            # If the field is not in the data, then go on to the next one
            try:
                new_value = data[name]
            except KeyError:
                continue
            # If the value is NOT_CHANGED, ignore it, since the
            # widget/converter sent a strong message not to do so.
            if new_value is NOT_CHANGED:
                continue
            if self.field_value_has_changed(field.field, new_value, webaction):
                # Only update the data if it changed
                # TODO: Should we possibly be using toFieldValue here?
                webaction_data[name] = new_value

                # Record the change using information required later
                changes.setdefault(field.interface, []).append(name)
        if changes:
            storage = get_storage()
            storage.update(self.get_action_id(), webaction_data)
        return changes
    def test_only_saves_modified_fields(self, browser):
        self.login(self.webaction_manager, browser)

        webaction_before = get_storage().list()[0]
        with freeze(datetime(2018, 4, 22)):
            browser.open(self.get_edit_url())
            browser.fill({"Title": "changed title"})
            browser.click_on("Save")

        webaction = get_storage().list()[0]
        self.assertEqual(['Data successfully updated.'], info_messages())
        self.assertNotEqual(webaction_before.pop("title"), webaction.get("title"))
        self.assertEqual("changed title", webaction.pop("title"))
        self.assertNotEqual(webaction_before.pop("modified"), webaction.get("modified"))
        self.assertEqual(datetime(2018, 4, 22), webaction.pop("modified"))
        self.assertDictEqual(webaction_before, webaction)
    def test_cant_add_webaction_with_same_unique_name_twice(self):
        storage = get_storage()
        new_action = {
            'title': u'Open in ExternalApp',
            'target_url': 'http://example.org/endpoint',
            'display': 'actions-menu',
            'mode': 'self',
            'order': 0,
            'scope': 'global',
            'unique_name': u'open-in-external-app-title-action',
        }

        with freeze(datetime(2019, 12, 31, 17, 45)):
            action_id = storage.add(new_action)

        self.assertEqual(1, len(storage.list()))
        action_from_storage = storage.get(action_id)
        self.assertEqual(u'Open in ExternalApp', action_from_storage['title'])

        # Same unique_name, just a different title. Should be rejected.
        new_action['title'] = u'Launch in ExternalApp'
        with self.assertRaises(ActionAlreadyExists) as cm:
            storage.add(new_action)

        self.assertEqual(
            "An action with the unique_name u'open-in-external-app-title-action' already exists",
            str(cm.exception))
    def test_cant_add_webaction_with_same_unique_name_twice(self):
        storage = get_storage()
        new_action = {
            'title': u'Open in ExternalApp',
            'target_url': 'http://example.org/endpoint',
            'display': 'actions-menu',
            'mode': 'self',
            'order': 0,
            'scope': 'global',
            'unique_name': u'open-in-external-app-title-action',
        }

        with freeze(datetime(2019, 12, 31, 17, 45)):
            action_id = storage.add(new_action)

        self.assertEqual(1, len(storage.list()))
        action_from_storage = storage.get(action_id)
        self.assertEqual(u'Open in ExternalApp', action_from_storage['title'])

        # Same unique_name, just a different title. Should be rejected.
        new_action['title'] = u'Launch in ExternalApp'
        with self.assertRaises(ActionAlreadyExists) as cm:
            storage.add(new_action)

        self.assertEqual(
            "An action with the unique_name u'open-in-external-app-title-action' already exists",
            cm.exception.message)
Example #11
0
    def update(self, action):
        action_delta = json_body(self.request)

        # Reject any fields that aren't user-controlled or unknown
        errors = get_unknown_fields(action_delta, IWebActionSchema)
        if errors:
            raise BadRequest(errors)

        scrub_json_payload(action_delta)

        # Validate on a copy
        action_copy = action.copy()
        action_copy.update(action_delta)
        errors = get_validation_errors(action_copy, IPersistedWebActionSchema)
        if errors:
            raise BadRequest(errors)

        # If validation succeeded, update actual action
        storage = get_storage()

        try:
            storage.update(action['action_id'], action_delta)
        except ActionAlreadyExists as exc:
            raise BadRequest([('unique_name', exc)])

        self.request.response.setStatus(204)
        return _no_content_marker
    def test_webaction_provider_respects_portal_type(self):
        self.login(self.regular_user)
        storage = get_storage()
        storage.update(0, {"types": ['opengever.document.document']})
        storage.update(1, {"types": ['opengever.document.document',
                                     'opengever.dossier.businesscasedossier']})

        provider = getMultiAdapter((self.dossier, self.request),
                                   IWebActionsProvider)

        expected_data = {'actions-menu': [self.action2_data, self.action3_data]}
        self.assertItemsEqual(expected_data, provider.get_webactions())

        self.clear_request_cache()
        provider = getMultiAdapter((self.document, self.request),
                                   IWebActionsProvider)

        expected_data = {'actions-menu': [self.action1_data,
                                          self.action2_data,
                                          self.action3_data]}
        self.assertDictEqual(expected_data, provider.get_webactions())

        self.clear_request_cache()
        provider = getMultiAdapter((self.leaf_repofolder, self.request),
                                   IWebActionsProvider)

        expected_data = {'actions-menu': [self.action3_data]}
        self.assertDictEqual(expected_data, provider.get_webactions())
Example #13
0
    def applyChanges(self, data):
        # Based on z3c.form.form.applyChanges, but without firing events
        # and modifying the webaction in its storage.
        webaction = self.get_webaction()
        changes = {}
        webaction_data = {}
        for name, field in self.fields.items():
            # If the field is not in the data, then go on to the next one
            try:
                new_value = data[name]
            except KeyError:
                continue
            # If the value is NOT_CHANGED, ignore it, since the
            # widget/converter sent a strong message not to do so.
            if new_value is NOT_CHANGED:
                continue
            if self.field_value_has_changed(field.field, new_value, webaction):
                # Only update the data if it changed
                # TODO: Should we possibly be using toFieldValue here?
                webaction_data[name] = new_value

                # Record the change using information required later
                changes.setdefault(field.interface, []).append(name)
        if changes:
            storage = get_storage()
            storage.update(self.get_action_id(), webaction_data)
        return changes
    def test_update_webaction(self):
        self.login(self.manager)

        storage = get_storage()
        with freeze(datetime(2019, 12, 31, 17, 45)):
            action = create(Builder('webaction').titled(u'Open in ExternalApp')
                            .having(
                                title=u'Open in ExternalApp',
                                target_url='http://example.org/endpoint',
            ))
        action_id = action['action_id']
        self.assertEqual(action, storage.get(action_id))

        with freeze(datetime(2020, 7, 31, 19, 15)):
            storage.update(action_id, {'title': u'My new title'})

        self.assertIsInstance(storage.get(action_id), dict)
        self.assertEqual({
            'action_id': 0,
            'title': u'My new title',
            'target_url': 'http://example.org/endpoint',
            'display': 'actions-menu',
            'mode': 'self',
            'order': 0,
            'scope': 'global',
            'created': datetime(2019, 12, 31, 17, 45),
            'modified': datetime(2020, 7, 31, 19, 15),
            'owner': 'admin',
        }, storage.get(action_id))
 def test_delete_webaction(self):
     storage = get_storage()
     action = create(Builder('webaction'))
     self.assertEqual(1, len(storage._actions))
     storage.delete(action['action_id'])
     self.assertEqual(0, len(storage._actions))
     self.assertEqual({}, dict(storage._actions))
Example #16
0
    def test_can_update_webaction(self, browser):
        self.login(self.webaction_manager, browser=browser)

        with freeze(datetime(2019, 12, 31, 17, 45)):
            action = create(
                Builder('webaction').having(
                    title=u'Open in ExternalApp',
                    target_url='http://example.org/endpoint',
                ))
        url = '%s/@webactions/%s' % (self.portal.absolute_url(),
                                     action['action_id'])

        with freeze(datetime(2020, 7, 31, 19, 15)):
            browser.open(url,
                         method='PATCH',
                         data=json.dumps({'title': u'My new title'}),
                         headers=self.HEADERS)

        self.assertEqual(204, browser.status_code)
        self.assertEqual('', browser.contents)

        storage = get_storage()
        self.assertEqual(
            {
                'action_id': 0,
                'title': u'My new title',
                'target_url': 'http://example.org/endpoint',
                'display': 'actions-menu',
                'mode': 'self',
                'order': 0,
                'scope': 'global',
                'created': datetime(2019, 12, 31, 17, 45),
                'modified': datetime(2020, 7, 31, 19, 15),
                'owner': 'webaction.manager',
            }, storage.get(action['action_id']))
    def test_only_saves_modified_fields(self, browser):
        self.login(self.webaction_manager, browser)

        webaction_before = get_storage().list()[0]
        with freeze(datetime(2018, 4, 22)):
            browser.open(self.get_edit_url())
            browser.fill({"Title": "changed title"})
            browser.click_on("Save")

        webaction = get_storage().list()[0]
        self.assertEqual(['Data successfully updated.'], info_messages())
        self.assertNotEqual(webaction_before.pop("title"), webaction.get("title"))
        self.assertEqual("changed title", webaction.pop("title"))
        self.assertNotEqual(webaction_before.pop("modified"), webaction.get("modified"))
        self.assertEqual(datetime(2018, 4, 22), webaction.pop("modified"))
        self.assertDictEqual(webaction_before, webaction)
    def delete(self, action):
        storage = get_storage()
        # We can't have a KeyError here because action has already been
        # verified as existing by locator
        storage.delete(action['action_id'])

        self.request.response.setStatus(204)
        return _no_content_marker
Example #19
0
    def delete(self, action):
        storage = get_storage()
        # We can't have a KeyError here because action has already been
        # verified as existing by locator
        storage.delete(action['action_id'])

        self.request.response.setStatus(204)
        return _no_content_marker
    def test_returns_only_actions_owned_by_user(self):
        self.login(self.webaction_manager)

        storage = get_storage()
        storage._actions[1]["owner"] = self.regular_user.id

        expected_data = [self.action1_data, self.action3_data]

        self.assertEqual(expected_data, self.get_webactions())
    def test_webaction_provider_only_returns_enabled_actions(self):
        self.login(self.regular_user)
        provider = getMultiAdapter((self.dossier, self.request), IWebActionsProvider)

        storage = get_storage()
        storage.update(1, {"enabled": False})

        expected_data = {'actions-menu': [self.action1_data, self.action3_data]}
        self.assertDictEqual(expected_data, provider.get_webactions())
    def test_no_modifications(self, browser):
        self.login(self.webaction_manager, browser)

        browser.open(self.get_edit_url())
        browser.click_on("Save")

        webaction = get_storage().list()[0]
        self.assertEqual(['No changes were applied.'], info_messages())
        self.assertEqual(datetime(2018, 4, 20), webaction.get("modified"))
Example #23
0
    def test_returns_only_actions_owned_by_user(self):
        self.login(self.webaction_manager)

        storage = get_storage()
        storage._actions[1]["owner"] = self.regular_user.id

        expected_data = [self.action1_data, self.action3_data]

        self.assertEqual(expected_data, self.get_webactions())
    def test_new_action_id_is_based_on_a_counter_in_storage(self):
        storage = get_storage()

        storage._storage['next_id'] = 42
        self.assertEqual(42, storage.issue_new_action_id())
        self.assertEqual(43, storage._storage['next_id'])

        new_action = create(Builder('webaction'))
        self.assertEqual(43, new_action['action_id'])
    def test_new_action_id_is_based_on_a_counter_in_storage(self):
        storage = get_storage()

        storage._storage['next_id'] = 42
        self.assertEqual(42, storage.issue_new_action_id())
        self.assertEqual(43, storage._storage['next_id'])

        new_action = create(Builder('webaction'))
        self.assertEqual(43, new_action['action_id'])
    def test_no_modifications(self, browser):
        self.login(self.webaction_manager, browser)

        browser.open(self.get_edit_url())
        browser.click_on("Save")

        webaction = get_storage().list()[0]
        self.assertEqual(['No changes were applied.'], info_messages())
        self.assertEqual(datetime(2018, 4, 20), webaction.get("modified"))
    def test_returns_all_actions_for_managers(self):
        self.login(self.manager)

        storage = get_storage()
        storage._actions[1]["owner"] = self.regular_user.id

        self.action2_data["owner"] = self.regular_user.id
        expected_data = [self.action1_data, self.action2_data, self.action3_data]

        self.assertEqual(expected_data, self.get_webactions())
    def test_initialization_is_idempotent(self):
        storage = get_storage()
        action = create(Builder('webaction'))

        # Multiple initializations shouldn't remove existing data
        storage.initialize_storage()

        action_from_storage = storage.get(0)
        self.assertEqual(action, action_from_storage)
        self.assertEqual(1, storage._storage['next_id'])
    def test_initialization_is_idempotent(self):
        storage = get_storage()
        action = create(Builder('webaction'))

        # Multiple initializations shouldn't remove existing data
        storage.initialize_storage()

        action_from_storage = storage.get(0)
        self.assertEqual(action, action_from_storage)
        self.assertEqual(1, storage._storage['next_id'])
    def test_webactions_are_html_escaped(self, browser):
        storage = get_storage()
        storage.update(1, {"title": u"<bold>Action 2 with html</bold>"})

        self.login(self.regular_user, browser=browser)
        browser.open(self.dossier)

        viewlet = browser.css('#webactions-title-buttons').first
        self.assertIn(u"\xc4ction 1", viewlet.innerHTML)
        self.assertIn("&lt;bold&gt;Action 2 with html&lt;/bold&gt;", viewlet.innerHTML)
Example #31
0
    def test_only_webactions_with_display_actions_buttons_are_displayed(
            self, browser):
        self.login(self.regular_user, browser)
        storage = get_storage()
        storage.update(0, {"display": "title-buttons"})

        browser.open(self.task, view='tabbedview_view-overview')

        self.assertEquals(['Action 2'],
                          browser.css('ul.webactions_buttons a').text)
Example #32
0
    def test_webactions_are_html_escaped(self, browser):
        self.login(self.regular_user, browser)

        storage = get_storage()
        storage.update(1, {"title": u"<bold>Action with HTML</bold>"})

        browser.open(self.task, view='tabbedview_view-overview')

        self.assertIn('&lt;bold&gt;Action with HTML&lt;/bold&gt;',
                      browser.css('ul.webactions_buttons a').first.innerHTML)
    def test_form_is_prefilled_with_missing_values(self, browser):
        # Enabled has a truthy missing value which needs to be prefilled
        # in the add form.
        self.login(self.webaction_manager, browser)
        storage = get_storage()

        self.assertEqual(0, len(storage.list()))

        browser.open(api.portal.getSite(), view="manage-webactions-add")
        form = browser.find_form_by_field("Enabled")
        self.assertEqual(form.find_field("Enabled").value, 'selected')
    def test_update_rejects_non_user_controlled_fields(self):
        storage = get_storage()

        create(Builder('webaction'))

        with self.assertRaises(ValidationError) as cm:
            storage.update(0, {'action_id': 42})

        self.assertEqual(
            "WebAction doesn't conform to schema (First error: ('action_id', UnknownField('action_id'))).",
            str(cm.exception))
    def test_update_rejects_non_user_controlled_fields(self):
        storage = get_storage()

        create(Builder('webaction'))

        with self.assertRaises(ValidationError) as cm:
            storage.update(0, {'action_id': 42})

        self.assertEqual(
            "WebAction doesn't conform to schema (First error: ('action_id', UnknownField('action_id'))).",
            cm.exception.message)
    def test_webaction_provider_only_returns_actions_with_global_scope(self):
        self.login(self.regular_user)
        provider = getMultiAdapter((self.dossier, self.request), IWebActionsProvider)
        storage = get_storage()
        # XXX We can't use storage.update here, as only the global scope is
        # implemented and allowed for now
        storage._actions[0]["scope"] = "context"
        storage._actions[2]["scope"] = "recursive"

        expected_data = {'actions-menu': [self.action2_data]}
        self.assertDictEqual(expected_data, provider.get_webactions())
    def test_add_webaction_with_missing_fields_raises(self):
        storage = get_storage()
        action = {}

        with self.assertRaises(ValidationError) as cm:
            storage.add(action)

        self.assertEqual(
            "WebAction doesn't conform to schema (First error: "
            "('title', RequiredMissing('title'))).",
            cm.exception.message)
    def test_form_is_prefilled_with_missing_values(self, browser):
        # Enabled has a truthy missing value which needs to be prefilled
        # in the add form.
        self.login(self.webaction_manager, browser)
        storage = get_storage()

        self.assertEqual(0, len(storage.list()))

        browser.open(api.portal.getSite(), view="manage-webactions-add")
        form = browser.find_form_by_field("Enabled")
        self.assertEqual(form.find_field("Enabled").value, 'selected')
Example #39
0
    def locate_action(self):
        action_id = self._parse_action_id()
        if action_id is not None:
            storage = get_storage()
            try:
                action = storage.get(action_id)
            except KeyError:
                raise NotFound

            self._check_ownership(action)
            return action
    def locate_action(self):
        action_id = self._parse_action_id()
        if action_id is not None:
            storage = get_storage()
            try:
                action = storage.get(action_id)
            except KeyError:
                raise NotFound

            self._check_ownership(action)
            return action
    def test_add_webaction_with_missing_fields_raises(self):
        storage = get_storage()
        action = {}

        with self.assertRaises(ValidationError) as cm:
            storage.add(action)

        self.assertEqual(
            "WebAction doesn't conform to schema (First error: "
            "('title', RequiredMissing('title'))).",
            str(cm.exception))
    def test_only_webactions_with_display_title_buttons_are_shown(self, browser):
        storage = get_storage()
        storage.update(1, {"display": "action-buttons"})
        self.login(self.regular_user, browser=browser)
        browser.open(self.dossier)

        viewlet = browser.css('#webactions-title-buttons')
        webactions = viewlet.css("a")
        self.assertEqual(len(webactions), 1)
        self.assertEqual([u"\xc4ction 1"],
                         map(lambda action: action.get("title"), webactions))
    def test_only_webactions_with_display_add_menu_are_shown_in_factory_menus(self):
        self.login(self.administrator)

        storage = get_storage()
        storage.update(1, {"display": "action-buttons"})

        for obj in self.contentish_objects:
            menu = FactoriesMenu(obj)
            menu_items = menu.getMenuItems(obj, self.dossier.REQUEST)
            self.assertIn(u'\xc4ction 1', [item.get('title') for item in menu_items])
            self.assertNotIn("Action 2", [item.get('title') for item in menu_items])
    def test_only_webactions_with_display_user_menu_are_shown_in_usermenu(self, browser):
        self.login(self.regular_user, browser)
        storage = get_storage()
        storage.update(0, {"display": "actions-menu"})

        browser.visit(self.dossier)
        webactions = browser.css('#portal-personaltools .category-webactions > a')

        self.assertEqual(1, len(webactions),
                         'Expect 1 webaction link in personal bar')

        self.assertEqual(['Action 2'], webactions.text)
    def test_manager_may_delete_any_action(self, browser):
        self.login(self.manager, browser=browser)

        not_my_action = create(Builder('webaction')
                               .owned_by('someone-else'))
        url = '%s/@webactions/%s' % (self.portal.absolute_url(), not_my_action['action_id'])

        browser.open(url, method='DELETE', headers=self.HEADERS)
        self.assertEqual(204, browser.status_code)

        storage = get_storage()
        self.assertEqual([], storage.list())
Example #46
0
    def test_returns_all_actions_for_managers(self):
        self.login(self.manager)

        storage = get_storage()
        storage._actions[1]["owner"] = self.regular_user.id

        self.action2_data["owner"] = self.regular_user.id
        expected_data = [
            self.action1_data, self.action2_data, self.action3_data
        ]

        self.assertEqual(expected_data, self.get_webactions())
Example #47
0
    def test_manager_may_delete_any_action(self, browser):
        self.login(self.manager, browser=browser)

        not_my_action = create(Builder('webaction').owned_by('someone-else'))
        url = '%s/@webactions/%s' % (self.portal.absolute_url(),
                                     not_my_action['action_id'])

        browser.open(url, method='DELETE', headers=self.HEADERS)
        self.assertEqual(204, browser.status_code)

        storage = get_storage()
        self.assertEqual([], storage.list())
    def test_delete_webaction(self, browser):
        self.login(self.webaction_manager, browser=browser)

        action = create(Builder('webaction'))

        url = '%s/@webactions/%s' % (self.portal.absolute_url(), action['action_id'])
        browser.open(url, method='DELETE', headers=self.HEADERS)

        self.assertEqual(204, browser.status_code)
        self.assertEqual('', browser.contents)

        storage = get_storage()
        self.assertEqual([], storage.list())
    def test_webactions_are_html_escaped(self, browser):
        storage = get_storage()
        storage.update(1, {"title": u"<bold>Action 2 with html</bold>"})

        self.login(self.administrator, browser=browser)
        for obj in self.contentish_objects:
            browser.open(obj)
            action_menu = browser.css('#contentActionMenus a')
            webaction_items = action_menu.css('.webaction')

            self.assertIn(u'\xc4ction 1', webaction_items[0].innerHTML)
            self.assertIn("&lt;bold&gt;Action 2 with html&lt;/bold&gt;",
                          webaction_items[1].innerHTML)
    def test_webactions_are_html_escaped(self, browser):
        storage = get_storage()
        storage.update(1, {"title": u"<bold>Action 2 with html</bold>"})

        self.login(self.regular_user, browser=browser)
        browser.open(self.dossier)

        action_menu = browser.css('#contentActionMenus a')
        webaction_items = action_menu.css('.actionicon-object_webaction')

        self.assertIn(u'\xc4ction 1', webaction_items[1].innerHTML)
        self.assertIn("&lt;bold&gt;Action 2 with html&lt;/bold&gt;",
                      webaction_items[0].innerHTML)
    def test_invariants_are_validated_on_final_resulting_object(self):
        """When updating, we need to make sure that invariants are validated
        on the final object that would result from the change (an invariant
        might impose a constraint that involves a field that already exists
        on the object and isn't touched by the update, and one that is being
        changed by the update).
        """
        self.login(self.manager)

        storage = get_storage()
        # We start with an action in the 'title-buttons' display location,
        # which requires an icon, and an value for icon_name property.
        # This is valid so far, no invariants are violated.
        with freeze(datetime(2019, 12, 31, 17, 45)):
            action = create(Builder('webaction').titled(u'Open in ExternalApp')
                            .having(
                                icon_name='fa-helicopter',
                                display='title-buttons',
            ))
        action_id = action['action_id']

        # But if we now attempt to change the display location to the
        # 'actions-menu', which doesn't allow for an icon, the invariant will
        # be violated.
        with self.assertRaises(ValidationError) as cm:
            storage.update(action_id, {'display': 'actions-menu'})

        self.assertEqual(
            "WebAction doesn't conform to schema (First error: "
            "(None, Invalid(\"Display location 'actions-menu' doesn't allow an icon.\",))).",
            cm.exception.message)

        # If we however change both the properties covered by the invariant in
        # the same update, the change succeeds:
        with freeze(datetime(2020, 7, 31, 19, 15)):
            storage.update(action_id, {'display': 'actions-menu', 'icon_name': None})

        self.assertEqual({
            'action_id': 0,
            'title': u'Open in ExternalApp',
            'target_url': 'http://example.org/endpoint',
            'icon_name': None,
            'display': 'actions-menu',
            'mode': 'self',
            'order': 0,
            'scope': 'global',
            'created': datetime(2019, 12, 31, 17, 45),
            'modified': datetime(2020, 7, 31, 19, 15),
            'owner': 'admin',
        }, storage.get(action_id))
Example #52
0
    def test_delete_webaction(self, browser):
        self.login(self.webaction_manager, browser=browser)

        action = create(Builder('webaction'))

        url = '%s/@webactions/%s' % (self.portal.absolute_url(),
                                     action['action_id'])
        browser.open(url, method='DELETE', headers=self.HEADERS)

        self.assertEqual(204, browser.status_code)
        self.assertEqual('', browser.contents)

        storage = get_storage()
        self.assertEqual([], storage.list())