示例#1
0
    def test_bare(self, db_session):
        # By default, no "bare" templates are used:
        api = self.make()
        assert api.bare is None

        # We can ask for "bare" templates explicitely:
        api = self.make(bare=True)
        assert api.bare is True

        # An XHR request will always result in bare master templates:
        request = DummyRequest()
        request.is_xhr = True
        api = self.make(request=request)
        assert api.bare is True

        # unless overridden:
        api = self.make(request=request, bare=False)
        assert api.bare is False
示例#2
0
    def test_bare(self):
        # By default, no "bare" templates are used:
        api = self.make()
        self.assertEqual(api.bare, None)

        # We can ask for "bare" templates explicitely:
        api = self.make(bare=True)
        self.assertEqual(api.bare, True)

        # An XHR request will always result in bare master templates:
        request = DummyRequest()
        request.is_xhr = True
        api = self.make(request=request)
        self.assertEqual(api.bare, True)

        # unless overridden:
        api = self.make(request=request, bare=False)
        self.assertEqual(api.bare, False)
示例#3
0
    def test_deleted_group_removed_from_localgroups(self, events, extra_principals):
        from kotti import DBSession
        from kotti.resources import get_root
        from kotti.security import set_groups
        from kotti.resources import LocalGroup
        from kotti.views.users import user_delete

        root = get_root()
        request = DummyRequest()
        set_groups(u'group:bobsgroup', root, ['role:admin'])
        local_group = DBSession.query(LocalGroup).first()
        assert local_group.principal_name == u'group:bobsgroup'
        assert local_group.node == root

        request.params['name'] = u'group:bobsgroup'
        request.params['delete'] = u'delete'
        user_delete(root, request)
        assert DBSession.query(LocalGroup).first() == None
示例#4
0
    def test_move_down(self, root):
        from kotti.resources import Document
        from kotti.views.edit.actions import NodeActions

        root['child1'] = Document(title=u"Child 1")
        root['child2'] = Document(title=u"Child 2")
        root['child3'] = Document(title=u"Child 3")
        assert root['child1'].position < root['child3'].position
        assert root['child2'].position < root['child3'].position

        request = DummyRequest()
        ids = [str(root['child1'].id), str(root['child2'].id)]
        request.session['kotti.selected-children'] = ids
        NodeActions(root, request).down()
        assert request.session.pop_flash('success') ==\
            [u'${title} was moved.', u'${title} was moved.']
        assert root['child1'].position > root['child3'].position
        assert root['child2'].position > root['child3'].position
示例#5
0
    def test_paste_without_edit_permission(self, config, root):
        from kotti.views.edit.actions import NodeActions

        request = DummyRequest()
        request.params['paste'] = u'on'
        config.testing_securitypolicy(permissive=False)

        # We need to have the 'edit' permission on the original object
        # to be able to cut and paste:
        request.session['kotti.paste'] = ([1], 'cut')
        view = NodeActions(root, request)
        with raises(Forbidden):
            view.paste_nodes()

        # We don't need 'edit' permission if we're just copying:
        request.session['kotti.paste'] = ([1], 'copy')
        response = NodeActions(root, request).paste_nodes()
        assert response.status == '302 Found'
示例#6
0
    def test_copy_and_paste_content_copy_tags(self, root, events):
        from kotti.resources import Tag, TagsToContents, Content
        from kotti.views.edit.actions import NodeActions

        root["folder_1"] = Content()
        root["content_1"] = Content()
        root["content_1"].tags = ["my tag"]
        assert Tag.query.count() == 1
        assert TagsToContents.query.count() == 1

        request = DummyRequest()
        request.params["paste"] = "on"
        request.session["kotti.paste"] = ([root["content_1"].id], "copy")
        NodeActions(root["folder_1"], request).paste_nodes()
        assert root["content_1"].tags == ["my tag"]
        assert root["folder_1"]["content_1"].tags == ["my tag"]
        assert Tag.query.count() == 1
        assert TagsToContents.query.count() == 2
示例#7
0
    def test_delete_content_delete_tags_and_assignments(self, root, events):
        from kotti.resources import Tag, TagsToContents, Content
        from kotti.views.edit.actions import NodeActions

        root["folder_1"] = Content()
        root["folder_1"].tags = ["first tag"]
        root["folder_1"]["content_1"] = Content()
        root["folder_1"]["content_1"].tags = ["second tag"]
        root["folder_1"]["content_2"] = Content()
        root["folder_1"]["content_2"].tags = ["third tag"]
        assert Tag.query.count() == 3
        assert TagsToContents.query.count() == 3

        request = DummyRequest()
        request.POST["delete"] = "delete"
        NodeActions(root["folder_1"], request).delete_node()
        assert Tag.query.count() == 0
        assert TagsToContents.query.count() == 0
示例#8
0
    def test_delete_content_delete_tags_and_assignments(self, root, events):
        from kotti.resources import Tag, TagsToContents, Content
        from kotti.views.edit.actions import NodeActions

        root[u'folder_1'] = Content()
        root[u'folder_1'].tags = [u'first tag']
        root[u'folder_1'][u'content_1'] = Content()
        root[u'folder_1'][u'content_1'].tags = [u'second tag']
        root[u'folder_1'][u'content_2'] = Content()
        root[u'folder_1'][u'content_2'].tags = [u'third tag']
        assert Tag.query.count() == 3
        assert TagsToContents.query.count() == 3

        request = DummyRequest()
        request.POST['delete'] = 'on'
        NodeActions(root[u'folder_1'], request).delete_node()
        assert Tag.query.count() == 0
        assert TagsToContents.query.count() == 0
示例#9
0
    def test_deleted_group_removed_in_usergroups(self, events,
                                                 extra_principals, root,
                                                 db_session):
        from kotti.security import get_principals
        from kotti.views.users import user_delete

        request = DummyRequest()
        bob = get_principals()[u'bob']
        bob.groups = [u'group:bobsgroup']
        assert bob.groups == [u'group:bobsgroup']

        request.params['name'] = u'group:bobsgroup'
        request.params['delete'] = u'delete'
        user_delete(root, request)
        db_session.expire(bob)
        with pytest.raises(KeyError):
            get_principals()[u'group:bobsgroup']
        assert bob.groups == []
示例#10
0
    def test_copy_and_paste_content_copy_tags(self, root, events):
        from kotti.resources import Tag, TagsToContents, Content
        from kotti.views.edit.actions import NodeActions

        root['folder_1'] = Content()
        root['content_1'] = Content()
        root['content_1'].tags = ['my tag']
        assert Tag.query.count() == 1
        assert TagsToContents.query.count() == 1

        request = DummyRequest()
        request.params['paste'] = 'on'
        request.session['kotti.paste'] = ([root['content_1'].id], 'copy')
        NodeActions(root['folder_1'], request).paste_nodes()
        assert root['content_1'].tags == ['my tag']
        assert root['folder_1']['content_1'].tags == ['my tag']
        assert Tag.query.count() == 1
        assert TagsToContents.query.count() == 2
示例#11
0
    def test_reset_owner_to_none(self):
        from kotti.resources import get_root
        from kotti.resources import Content
        from kotti.views.users import user_delete
        from kotti.tests.test_node_views import TestNodeShare

        root = get_root()
        request = DummyRequest()
        TestNodeShare.add_some_principals()

        root[u'content_1'] = Content()
        root[u'content_1'].owner = u'bob'
        assert root[u'content_1'].owner == u'bob'

        request.params['name'] = u'bob'
        request.params['delete'] = u'delete'
        user_delete(root, request)
        assert root[u'content_1'].owner == None
示例#12
0
    def test_wrong_token(self, root):
        from kotti.security import get_principals
        from kotti.views.login import set_password

        self.form_values({
            "token": "wrongtoken",
            "email": "myemail",
            "password": "******",
            "continue_to": "",
        })
        self.user.confirm_token = "mytoken"
        self.user.password = "******"
        context, request = root, DummyRequest(post={"submit": "submit"})
        res = set_password(context, request)

        assert self.user.confirm_token == "mytoken"
        assert not get_principals().validate_password("mypassword",
                                                      self.user.password)
        assert not request.is_response(res)
示例#13
0
    def test_deleted_group_removed_in_usergroups(self, events,
                                                 extra_principals, root,
                                                 db_session):
        from kotti.security import get_principals
        from kotti.views.users import user_delete

        request = DummyRequest()
        bob = get_principals()["bob"]
        bob.groups = ["group:bobsgroup"]
        assert bob.groups == ["group:bobsgroup"]

        request.params["name"] = "group:bobsgroup"
        request.params["delete"] = "delete"
        user_delete(root, request)
        db_session.expire(bob)
        with pytest.raises(KeyError):
            # noinspection PyStatementEffect
            get_principals()["group:bobsgroup"]
        assert bob.groups == []
示例#14
0
    def test_paste_without_edit_permission(self):
        from kotti import DBSession
        from kotti.resources import Node
        from kotti.views.edit import paste_node

        root = DBSession.query(Node).get(1)
        request = DummyRequest()
        request.params['paste'] = u'on'
        self.config.testing_securitypolicy(permissive=False)

        # We need to have the 'edit' permission on the original object
        # to be able to cut and paste:
        request.session['kotti.paste'] = (1, 'cut')
        self.assertRaises(Forbidden, paste_node, root, request)

        # We don't need 'edit' permission if we're just copying:
        request.session['kotti.paste'] = (1, 'copy')
        response = paste_node(root, request)
        self.assertEqual(response.status, '302 Found')
示例#15
0
    def test_show_hide(self, root):
        from kotti.resources import Document
        from kotti.views.edit.actions import NodeActions

        root['child1'] = Document(title="Child 1")
        assert root['child1'].in_navigation is True

        request = DummyRequest()
        request.session['kotti.selected-children'] = [str(root['child1'].id)]
        NodeActions(root, request).hide()
        assert request.session.pop_flash('success') ==\
            ['${title} is no longer visible in the navigation.']
        assert root['child1'].in_navigation is False

        request.session['kotti.selected-children'] = [str(root['child1'].id)]
        NodeActions(root, request).show()
        assert request.session.pop_flash('success') ==\
            ['${title} is now visible in the navigation.']
        assert root['child1'].in_navigation is True
示例#16
0
    def test_caching(self, filedepot, monkeypatch):
        import datetime
        import webob.response

        f = self._create_file()
        d = datetime.datetime(2012, 12, 31, 13)

        class mockdatetime:
            @staticmethod
            def utcnow():
                return d

        monkeypatch.setattr(webob.response, 'datetime', mockdatetime)

        resp = UploadedFileResponse(f.data, DummyRequest(), cache_max_age=10)

        # this is set by filedepot fixture
        assert resp.headers['Last-Modified'] == 'Sun, 30 Dec 2012 00:00:00 GMT'
        assert resp.headers['Expires'] == 'Mon, 31 Dec 2012 13:00:10 GMT'
示例#17
0
    def test_deleted_group_removed_in_usergroups(self):
        from kotti.resources import get_root
        from kotti.security import get_principals
        from kotti.tests.test_node_views import TestNodeShare
        from kotti.views.users import user_delete

        root = get_root()
        request = DummyRequest()
        TestNodeShare.add_some_principals()
        bob = get_principals()[u'bob']
        bob.groups = [u'group:bobsgroup']
        assert bob.groups == [u'group:bobsgroup']

        request.params['name'] = u'group:bobsgroup'
        request.params['delete'] = u'delete'
        user_delete(root, request)
        with pytest.raises(KeyError):
            get_principals()[u'group:bobsgroup']
        assert bob.groups == []
示例#18
0
    def test_wrong_token(self, root):
        from kotti.security import get_principals
        from kotti.views.login import set_password

        self.form_values({
            'token': 'wrongtoken',
            'email': 'myemail',
            'password': '******',
            'continue_to': '',
        })
        self.user.confirm_token = 'mytoken'
        self.user.password = '******'
        context, request = root, DummyRequest(post={'submit': 'submit'})
        res = set_password(context, request)

        assert self.user.confirm_token == 'mytoken'
        assert not get_principals().validate_password('mypassword',
                                                      self.user.password)
        assert not request.is_response(res)
示例#19
0
    def test_move_down(self, root):
        from kotti.resources import Document
        from kotti.views.edit.actions import NodeActions

        root["child1"] = Document(title="Child 1")
        root["child2"] = Document(title="Child 2")
        root["child3"] = Document(title="Child 3")
        assert root["child1"].position < root["child3"].position
        assert root["child2"].position < root["child3"].position

        request = DummyRequest()
        ids = [str(root["child1"].id), str(root["child2"].id)]
        request.session["kotti.selected-children"] = ids
        NodeActions(root, request).down()
        assert request.session.pop_flash("success") == [
            "${title} was moved.",
            "${title} was moved.",
        ]
        assert root["child1"].position > root["child3"].position
        assert root["child2"].position > root["child3"].position
示例#20
0
    def test_success(self):
        from kotti.resources import get_root
        from kotti.security import get_principals
        from kotti.views.login import set_password

        self.form_values({
            'token': 'mytoken',
            'email': 'myemail',
            'password': '******',
            'continue_to': '',
        })
        self.user.confirm_token = 'mytoken'
        self.user.password = '******'
        context, request = get_root(), DummyRequest(post={'submit': 'submit'})
        res = set_password(context, request)

        assert self.user.confirm_token is None
        assert get_principals().validate_password('mypassword',
                                                  self.user.password)
        assert res.status == '302 Found'
示例#21
0
    def test_addable_views_registered_to_some_context(self, config, root):

        from kotti.resources import Document, File

        _saved = Document.type_info.addable_to
        Document.type_info.addable_to = ['File']

        config.testing_securitypolicy(permissive=True)
        config.add_view(
            lambda context, request: {},
            name=Document.type_info.add_view,
            permission='add',
            renderer='kotti:templates/edit/node.pt',
            context=File,
        )
        request = DummyRequest()

        assert Document.type_info.addable(Document(), request) is False
        assert Document.type_info.addable(File(), request) is True

        Document.type_info.addable_to = _saved
示例#22
0
    def test_success(self, root):
        from kotti.security import get_principals
        from kotti.views.login import set_password

        self.form_values({
            "token": "mytoken",
            "email": "myemail",
            "password": "******",
            "continue_to": "",
        })
        self.user.confirm_token = "mytoken"
        self.user.password = "******"
        context, request = root, DummyRequest(post={"submit": "submit"})
        self.user.last_login_date = None
        res = set_password(context, request)

        assert self.user.confirm_token is None
        assert self.user.last_login_date is not None
        assert get_principals().validate_password("mypassword",
                                                  self.user.password)
        assert res.status == "302 Found"
示例#23
0
    def test_cut_and_paste_content_copy_tags(self):
        from kotti import DBSession
        from kotti.resources import get_root
        from kotti.resources import Tag, TagsToContents, Content
        from kotti.views.edit import paste_node

        ses = DBSession
        root = get_root()
        root[u'folder_1'] = Content()
        root[u'content_1'] = Content()
        root[u'content_1'].tags = [u'my tag']
        assert ses.query(Tag).count() == 1
        assert ses.query(TagsToContents).count() == 1

        request = DummyRequest()
        request.params['paste'] = u'on'
        request.session['kotti.paste'] = (root[u'content_1'].id, 'cut')
        paste_node(root[u'folder_1'], request)
        assert root[u'folder_1'][u'content_1'].tags == [u'my tag']
        assert ses.query(Tag).count() == 1
        assert ses.query(TagsToContents).count() == 1
示例#24
0
    def test_copy_and_paste_content_copy_tags(self, db_session, events):
        from kotti import DBSession
        from kotti.resources import get_root
        from kotti.resources import Tag, TagsToContents, Content
        from kotti.views.edit.actions import NodeActions

        ses = DBSession
        root = get_root()
        root[u'folder_1'] = Content()
        root[u'content_1'] = Content()
        root[u'content_1'].tags = [u'my tag']
        assert ses.query(Tag).count() == 1
        assert ses.query(TagsToContents).count() == 1

        request = DummyRequest()
        request.params['paste'] = u'on'
        request.session['kotti.paste'] = ([root[u'content_1'].id], 'copy')
        NodeActions(root[u'folder_1'], request).paste_nodes()
        assert root[u'content_1'].tags == [u'my tag']
        assert root[u'folder_1'][u'content_1'].tags == [u'my tag']
        assert ses.query(Tag).count() == 1
        assert ses.query(TagsToContents).count() == 2
示例#25
0
    def test_apply(self):
        from kotti.resources import get_root
        from kotti.security import list_groups
        from kotti.security import set_groups
        from kotti.views.users import share_node

        root = get_root()
        request = DummyRequest()
        self.add_some_principals()

        request.params['apply'] = u''
        share_node(root, request)
        self.assertEqual(request.session.pop_flash('info'),
                         [u'No changes made.'])
        self.assertEqual(list_groups('bob', root), [])
        set_groups('bob', root, ['role:special'])

        request.params['role::bob::role:owner'] = u'1'
        request.params['role::bob::role:editor'] = u'1'
        request.params['orig-role::bob::role:owner'] = u''
        request.params['orig-role::bob::role:editor'] = u''

        share_node(root, request)
        self.assertEqual(request.session.pop_flash('success'),
                         [u'Your changes have been saved.'])
        self.assertEqual(
            set(list_groups('bob', root)),
            set(['role:owner', 'role:editor', 'role:special'])
            )

        # We cannot set a role that's not displayed, even if we forged
        # the request:
        request.params['role::bob::role:admin'] = u'1'
        request.params['orig-role::bob::role:admin'] = u''
        self.assertRaises(Forbidden, share_node, root, request)
        self.assertEqual(
            set(list_groups('bob', root)),
            set(['role:owner', 'role:editor', 'role:special'])
            )
示例#26
0
    def test_register_submit(self, root):
        from kotti.views.login import register
        from pyramid.httpexceptions import HTTPFound

        request = DummyRequest()
        request.POST['title'] = u'Test User'
        request.POST['name'] = u'test'
        request.POST['email'] = u'*****@*****.**'
        request.POST['register'] = u'register',

        with patch('kotti.views.login.UserAddFormView') as form:
            with patch('kotti.views.login.get_principals'):
                res = register(root, request)
                form.assert_has_calls([call().add_user_success({
                    'name': u'test',
                    'roles': u'',
                    'title': u'Test User',
                    'send_email': True,
                    'groups': u'',
                    'email': u'*****@*****.**'})]
                )
        assert(isinstance(res, HTTPFound))
示例#27
0
    def test_delete_content_delete_tags_and_assignments(self):
        from kotti import DBSession
        from kotti.resources import get_root
        from kotti.resources import Tag, TagsToContents, Content
        from kotti.views.edit import delete_node

        ses = DBSession
        root = get_root()
        root[u'folder_1'] = Content()
        root[u'folder_1'].tags = [u'first tag']
        root[u'folder_1'][u'content_1'] = Content()
        root[u'folder_1'][u'content_1'].tags = [u'second tag']
        root[u'folder_1'][u'content_2'] = Content()
        root[u'folder_1'][u'content_2'].tags = [u'third tag']
        assert ses.query(Tag).count() == 3
        assert ses.query(TagsToContents).count() == 3

        request = DummyRequest()
        request.POST['delete'] = 'on'
        delete_node(root[u'folder_1'], request)
        assert ses.query(Tag).count() == 0
        assert ses.query(TagsToContents).count() == 0
示例#28
0
    def test_apply(self, extra_principals, root):
        from kotti.security import list_groups
        from kotti.security import set_groups
        from kotti.views.users import share_node

        request = DummyRequest()

        request.params["apply"] = ""
        request.params["csrf_token"] = request.session.get_csrf_token()
        share_node(root, request)
        assert request.session.pop_flash("info") == ["No changes were made."]
        assert list_groups("bob", root) == []
        set_groups("bob", root, ["role:special"])

        request.params["role::bob::role:owner"] = "1"
        request.params["role::bob::role:editor"] = "1"
        request.params["orig-role::bob::role:owner"] = ""
        request.params["orig-role::bob::role:editor"] = ""

        share_node(root, request)
        assert request.session.pop_flash("success") == ["Your changes have been saved."]
        assert set(list_groups("bob", root)) == {
            "role:owner",
            "role:editor",
            "role:special",
        }

        # We cannot set a role that's not displayed, even if we forged
        # the request:
        request.params["role::bob::role:admin"] = "1"
        request.params["orig-role::bob::role:admin"] = ""
        with raises(Forbidden):
            share_node(root, request)
        assert set(list_groups("bob", root)) == {
            "role:owner",
            "role:editor",
            "role:special",
        }
示例#29
0
    def test_inactive_user(self, db_session):
        from kotti.resources import get_root
        from kotti.security import get_principals
        from kotti.views.login import set_password

        self.form_values({
            'token': 'mytoken',
            'email': 'myemail',
            'password': '******',
            'continue_to': '',
            })
        self.user.confirm_token = 'mytoken'
        self.user.password = '******'
        context, request = get_root(), DummyRequest(post={'submit': 'submit'})
        self.user.active = False
        self.user.last_login_date = None
        res = set_password(context, request)

        assert self.user.confirm_token == 'mytoken'
        assert self.user.last_login_date is None
        assert not get_principals().validate_password(
            'mypassword', self.user.password)
        assert not request.is_response(res)
示例#30
0
def browser(db_session, request, setup_app):
    """ returns an instance of `zope.testbrowser`.  The `kotti.testing.user`
        pytest marker (or `pytest.mark.user`) can be used to pre-authenticate
        the browser with the given login name: `@user('admin')`.
    """
    from zope.testbrowser.wsgi import Browser
    from kotti.testing import BASE_URL
    host, port = BASE_URL.split(':')[-2:]
    browser = Browser('http://{}:{}/'.format(host[2:], int(port)),
                      wsgi_app=setup_app)
    if 'user' in request.keywords:
        # set auth cookie directly on the browser instance...
        from pyramid.security import remember
        from pyramid.testing import DummyRequest
        login = request.keywords['user'].args[0]
        environ = dict(HTTP_HOST=host[2:])
        for _, value in remember(DummyRequest(environ=environ), login):
            cookie, _ = value.split(';', 1)
            name, value = cookie.split('=')
            if name in browser.cookies:
                del browser.cookies[name]
            browser.cookies.create(name, value.strip('"'), path='/')
    return browser