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
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)
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
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
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'
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
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
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
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 == []
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
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
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)
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 == []
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')
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
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'
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 == []
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)
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
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'
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
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"
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
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
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']) )
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))
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
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", }
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)
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