# -*- coding: utf-8; -*- from unittest.mock import patch from sqlalchemy import orm import colander from wuttaweb.views import users as mod from tests.util import WebTestCase class TestUserView(WebTestCase): def make_view(self): return mod.UserView(self.request) def test_includeme(self): self.pyramid_config.include('wuttaweb.views.users') def test_get_query(self): view = self.make_view() query = view.get_query(session=self.session) self.assertIsInstance(query, orm.Query) def test_configure_grid(self): model = self.app.model view = self.make_view() grid = view.make_grid(model_class=model.User) self.assertFalse(grid.is_linked('person')) view.configure_grid(grid) self.assertTrue(grid.is_linked('person')) def test_configure_form(self): model = self.app.model barney = model.User(username='barney') self.session.add(barney) self.session.commit() view = self.make_view() # person is *not* required with patch.object(view, 'creating', new=True): form = view.make_form(model_class=model.User) self.assertIsNone(form.is_required('person')) view.configure_form(form) self.assertFalse(form.is_required('person')) # password removed (always, for now) with patch.object(view, 'viewing', new=True): form = view.make_form(model_instance=barney) self.assertIn('password', form) view.configure_form(form) self.assertNotIn('password', form) with patch.object(view, 'editing', new=True): form = view.make_form(model_instance=barney) self.assertIn('password', form) view.configure_form(form) self.assertNotIn('password', form) def test_unique_username(self): model = self.app.model view = self.make_view() user = model.User(username='foo') self.session.add(user) self.session.commit() with patch.object(mod, 'Session', return_value=self.session): # invalid if same username in data node = colander.SchemaNode(colander.String(), name='username') self.assertRaises(colander.Invalid, view.unique_username, node, 'foo') # but not if username belongs to current user view.editing = True self.request.matchdict = {'uuid': user.uuid} node = colander.SchemaNode(colander.String(), name='username') self.assertIsNone(view.unique_username(node, 'foo')) def test_objectify(self): model = self.app.model auth = self.app.get_auth_handler() blokes = model.Role(name="Blokes") self.session.add(blokes) others = model.Role(name="Others") self.session.add(others) barney = model.User(username='barney') auth.set_user_password(barney, 'testpass') barney.roles.append(blokes) self.session.add(barney) self.session.commit() view = self.make_view() view.editing = True self.request.matchdict = {'uuid': barney.uuid} # sanity check, user is just in 'blokes' role self.session.refresh(barney) self.assertEqual(len(barney.roles), 1) self.assertEqual(barney.roles[0].name, "Blokes") # form can update user password self.assertTrue(auth.check_user_password(barney, 'testpass')) form = view.make_model_form(model_instance=barney) form.validated = {'username': 'barney', 'set_password': 'testpass2'} user = view.objectify(form, session=self.session) self.assertIs(user, barney) self.assertTrue(auth.check_user_password(barney, 'testpass2')) # form can update user roles form = view.make_model_form(model_instance=barney) form.validated = {'username': 'barney', 'roles': {others.uuid}} user = view.objectify(form, session=self.session) self.assertIs(user, barney) self.assertEqual(len(user.roles), 1) self.assertEqual(user.roles[0].name, "Others") def test_update_roles(self): model = self.app.model auth = self.app.get_auth_handler() admin = auth.get_role_administrator(self.session) authed = auth.get_role_authenticated(self.session) anon = auth.get_role_anonymous(self.session) blokes = model.Role(name="Blokes") self.session.add(blokes) others = model.Role(name="Others") self.session.add(others) barney = model.User(username='barney') barney.roles.append(blokes) self.session.add(barney) self.session.commit() view = self.make_view() view.editing = True self.request.matchdict = {'uuid': barney.uuid} # no error if data is missing roles form = view.make_model_form(model_instance=barney) form.validated = {'username': 'barneyx'} user = view.objectify(form, session=self.session) self.assertIs(user, barney) self.assertEqual(barney.username, 'barneyx') # sanity check, user is just in 'blokes' role self.session.refresh(barney) self.assertEqual(len(barney.roles), 1) self.assertEqual(barney.roles[0].name, "Blokes") # let's test a bunch at once to ensure: # - user roles are updated # - authed / anon roles are not added # - admin role not added if current user is not root form = view.make_model_form(model_instance=barney) form.validated = {'username': 'barney', 'roles': {admin.uuid, authed.uuid, anon.uuid, others.uuid}} user = view.objectify(form, session=self.session) self.assertIs(user, barney) self.assertEqual(len(user.roles), 1) self.assertEqual(user.roles[0].name, "Others") # let's test a bunch at once to ensure: # - user roles are updated # - admin role is added if current user is root self.request.is_root = True form = view.make_model_form(model_instance=barney) form.validated = {'username': 'barney', 'roles': {admin.uuid, blokes.uuid, others.uuid}} user = view.objectify(form, session=self.session) self.assertIs(user, barney) self.assertEqual(len(user.roles), 3) role_uuids = set([role.uuid for role in user.roles]) self.assertEqual(role_uuids, {admin.uuid, blokes.uuid, others.uuid}) # admin role not removed if current user is not root self.request.is_root = False form = view.make_model_form(model_instance=barney) form.validated = {'username': 'barney', 'roles': {blokes.uuid, others.uuid}} user = view.objectify(form, session=self.session) self.assertIs(user, barney) self.assertEqual(len(user.roles), 3) # admin role is removed if current user is root self.request.is_root = True form = view.make_model_form(model_instance=barney) form.validated = {'username': 'barney', 'roles': {blokes.uuid, others.uuid}} user = view.objectify(form, session=self.session) self.assertIs(user, barney) self.assertEqual(len(user.roles), 2)