3
0
Fork 0
wuttaweb/tests/views/test_users.py
2025-01-27 17:07:42 -06:00

320 lines
13 KiB
Python

# -*- coding: utf-8; -*-
from unittest.mock import patch
from sqlalchemy import orm
import colander
from wuttaweb.views import users as mod
from wuttaweb.testing 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_grid_row_class(self):
model = self.app.model
user = model.User(username='barney', active=True)
data = dict(user)
view = self.make_view()
self.assertIsNone(view.grid_row_class(user, data, 1))
user.active = False
self.assertEqual(view.grid_row_class(user, data, 1), 'has-background-warning')
def test_is_editable(self):
model = self.app.model
view = self.make_view()
# active user is editable
user = model.User(username='barney', active=True)
self.assertTrue(view.is_editable(user))
# inactive also editable
user = model.User(username='barney', active=False)
self.assertTrue(view.is_editable(user))
# but not if prevent_edit flag is set
user = model.User(username='barney', prevent_edit=True)
self.assertFalse(view.is_editable(user))
# unless request user is root
self.request.is_root = True
self.assertTrue(view.is_editable(user))
def test_configure_form(self):
model = self.app.model
person = model.Person(first_name='Barney', last_name='Rubble', full_name='Barney Rubble')
barney = model.User(username='barney', person=person)
self.session.add(barney)
self.session.commit()
view = self.make_view()
# person replaced with first/last name when creating or editing
with patch.object(view, 'viewing', new=True):
form = view.make_form(model_instance=barney)
self.assertIn('person', form)
self.assertNotIn('first_name', form)
self.assertNotIn('last_name', form)
view.configure_form(form)
self.assertIn('person', form)
self.assertNotIn('first_name', form)
self.assertNotIn('last_name', form)
with patch.object(view, 'creating', new=True):
form = view.make_form(model_instance=barney)
self.assertIn('person', form)
self.assertNotIn('first_name', form)
self.assertNotIn('last_name', form)
view.configure_form(form)
self.assertNotIn('person', form)
self.assertIn('first_name', form)
self.assertIn('last_name', form)
with patch.object(view, 'editing', new=True):
form = view.make_form(model_instance=barney)
self.assertIn('person', form)
self.assertNotIn('first_name', form)
self.assertNotIn('last_name', form)
view.configure_form(form)
self.assertNotIn('person', form)
self.assertIn('first_name', form)
self.assertIn('last_name', form)
# first/last name have default values when editing
with patch.object(view, 'editing', new=True):
form = view.make_form(model_instance=barney)
self.assertNotIn('first_name', form.defaults)
self.assertNotIn('last_name', form.defaults)
view.configure_form(form)
self.assertIn('first_name', form.defaults)
self.assertEqual(form.defaults['first_name'], 'Barney')
self.assertIn('last_name', form.defaults)
self.assertEqual(form.defaults['last_name'], 'Rubble')
# 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(view, '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()
view = self.make_view()
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()
with patch.object(self.request, 'matchdict', new={'uuid': barney.uuid}):
with patch.object(view, 'editing', new=True):
# 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'}
with patch.object(view, 'Session', return_value=self.session):
user = view.objectify(form)
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}}
with patch.object(view, 'Session', return_value=self.session):
user = view.objectify(form)
self.assertIs(user, barney)
self.assertEqual(len(user.roles), 1)
self.assertEqual(user.roles[0].name, "Others")
# person is auto-created
self.assertIsNone(barney.person)
form = view.make_model_form(model_instance=barney)
form.validated = {'username': 'barney', 'first_name': 'Barney', 'last_name': 'Rubble'}
with patch.object(view, 'Session', return_value=self.session):
user = view.objectify(form)
self.assertIsNotNone(barney.person)
self.assertEqual(barney.person.first_name, 'Barney')
self.assertEqual(barney.person.last_name, 'Rubble')
self.assertEqual(barney.person.full_name, 'Barney Rubble')
# person is auto-removed
self.assertIsNotNone(barney.person)
form = view.make_model_form(model_instance=barney)
form.validated = {'username': 'barney', 'first_name': '', 'last_name': ''}
with patch.object(view, 'Session', return_value=self.session):
user = view.objectify(form)
self.assertIsNone(barney.person)
# nb. re-attach the person
barney.person = self.session.query(model.Person).one()
# person name is updated
self.assertEqual(barney.person.first_name, 'Barney')
self.assertEqual(barney.person.last_name, 'Rubble')
self.assertEqual(barney.person.full_name, 'Barney Rubble')
form = view.make_model_form(model_instance=barney)
form.validated = {'username': 'barney', 'first_name': 'Fred', 'last_name': 'Flintstone'}
with patch.object(view, 'Session', return_value=self.session):
user = view.objectify(form)
self.assertIsNotNone(barney.person)
self.assertEqual(barney.person.first_name, 'Fred')
self.assertEqual(barney.person.last_name, 'Flintstone')
self.assertEqual(barney.person.full_name, 'Fred Flintstone')
with patch.object(view, 'creating', new=True):
# person is auto-created when making new user
form = view.make_model_form()
form.validated = {'username': 'betty', 'first_name': 'Betty', 'last_name': 'Boop'}
with patch.object(view, 'Session', return_value=self.session):
user = view.objectify(form)
self.assertIsNotNone(user.person)
self.assertEqual(user.person.first_name, 'Betty')
self.assertEqual(user.person.last_name, 'Boop')
self.assertEqual(user.person.full_name, 'Betty Boop')
# nb. keep ref to last user
last_user = user
# person is *not* auto-created if no name provided
form = view.make_model_form()
form.validated = {'username': 'betty', 'first_name': '', 'last_name': ''}
with patch.object(view, 'Session', return_value=self.session):
user = view.objectify(form)
self.assertIsNone(user.person)
self.assertIsNot(user, last_user)
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)
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}}
with patch.object(view, 'Session', return_value=self.session):
user = view.objectify(form)
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}}
with patch.object(view, 'Session', return_value=self.session):
user = view.objectify(form)
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}}
with patch.object(view, 'Session', return_value=self.session):
user = view.objectify(form)
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}}
with patch.object(view, 'Session', return_value=self.session):
user = view.objectify(form)
self.assertIs(user, barney)
self.assertEqual(len(user.roles), 2)