feat: overhaul some User/Person form fields etc.
hoping this is more intuitive to use..
This commit is contained in:
parent
70ed2dc78c
commit
5b2d1dad53
8 changed files with 289 additions and 217 deletions
|
@ -8,6 +8,8 @@ from pyramid.httpexceptions import HTTPNotFound
|
|||
|
||||
from wuttaweb.views import people
|
||||
from wuttaweb.testing import WebTestCase
|
||||
from wuttaweb.forms.widgets import GridWidget
|
||||
from wuttaweb.grids import Grid
|
||||
|
||||
|
||||
class TestPersonView(WebTestCase):
|
||||
|
@ -34,27 +36,59 @@ class TestPersonView(WebTestCase):
|
|||
def test_configure_form(self):
|
||||
model = self.app.model
|
||||
view = self.make_view()
|
||||
|
||||
# full_name
|
||||
form = view.make_form(model_class=model.Person)
|
||||
|
||||
# required fields
|
||||
self.assertIn('full_name', form)
|
||||
with patch.object(view, 'creating', new=True):
|
||||
form.set_fields(form.get_model_fields())
|
||||
self.assertEqual(form.required_fields, {})
|
||||
view.configure_form(form)
|
||||
self.assertTrue(form.required_fields)
|
||||
self.assertFalse(form.required_fields['middle_name'])
|
||||
self.assertNotIn('full_name', form)
|
||||
|
||||
person = model.Person(full_name="Barney Rubble")
|
||||
user = model.User(username='barney', person=person)
|
||||
self.session.add(user)
|
||||
self.session.commit()
|
||||
|
||||
# users field
|
||||
# users
|
||||
person = model.Person()
|
||||
form = view.make_form(model_instance=person)
|
||||
self.assertNotIn('users', form.widgets)
|
||||
with patch.object(view, 'viewing', new=True):
|
||||
form = view.make_form(model_instance=person)
|
||||
self.assertEqual(form.defaults, {})
|
||||
view.configure_form(form)
|
||||
self.assertIn('_users', form.defaults)
|
||||
self.assertIn('users', form.widgets)
|
||||
self.assertIsInstance(form.widgets['users'], GridWidget)
|
||||
|
||||
def test_make_users_grid(self):
|
||||
model = self.app.model
|
||||
view = self.make_view()
|
||||
person = model.Person(full_name="John Doe")
|
||||
|
||||
# basic
|
||||
grid = view.make_users_grid(person)
|
||||
self.assertIsInstance(grid, Grid)
|
||||
self.assertFalse(grid.linked_columns)
|
||||
self.assertFalse(grid.actions)
|
||||
|
||||
# view + edit actions
|
||||
with patch.object(self.request, 'is_root', new=True):
|
||||
grid = view.make_users_grid(person)
|
||||
self.assertIsInstance(grid, Grid)
|
||||
self.assertIn('username', grid.linked_columns)
|
||||
self.assertEqual(len(grid.actions), 2)
|
||||
self.assertEqual(grid.actions[0].key, 'view')
|
||||
self.assertEqual(grid.actions[1].key, 'edit')
|
||||
|
||||
def test_objectify(self):
|
||||
model = self.app.model
|
||||
view = self.make_view()
|
||||
|
||||
# creating
|
||||
form = view.make_model_form()
|
||||
form.validated = {'first_name': 'Barney', 'last_name': 'Rubble'}
|
||||
person = view.objectify(form)
|
||||
self.assertEqual(person.full_name, 'Barney Rubble')
|
||||
|
||||
# editing
|
||||
form = view.make_model_form(model_instance=person)
|
||||
form.validated = {'first_name': 'Betty', 'last_name': 'Rubble'}
|
||||
person2 = view.objectify(form)
|
||||
self.assertEqual(person2.full_name, 'Betty Rubble')
|
||||
self.assertIs(person2, person)
|
||||
|
||||
def test_autocomplete_query(self):
|
||||
model = self.app.model
|
||||
|
|
|
@ -64,17 +64,51 @@ class TestUserView(WebTestCase):
|
|||
|
||||
def test_configure_form(self):
|
||||
model = self.app.model
|
||||
barney = model.User(username='barney')
|
||||
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 is *not* required
|
||||
with patch.object(view, 'creating', new=True):
|
||||
form = view.make_form(model_class=model.User)
|
||||
self.assertIsNone(form.is_required('person'))
|
||||
# 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.assertFalse(form.is_required('person'))
|
||||
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):
|
||||
|
@ -96,7 +130,7 @@ class TestUserView(WebTestCase):
|
|||
self.session.add(user)
|
||||
self.session.commit()
|
||||
|
||||
with patch.object(mod, 'Session', return_value=self.session):
|
||||
with patch.object(view, 'Session', return_value=self.session):
|
||||
|
||||
# invalid if same username in data
|
||||
node = colander.SchemaNode(colander.String(), name='username')
|
||||
|
@ -111,6 +145,8 @@ class TestUserView(WebTestCase):
|
|||
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")
|
||||
|
@ -120,30 +156,90 @@ class TestUserView(WebTestCase):
|
|||
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")
|
||||
with patch.object(self.request, 'matchdict', new={'uuid': barney.uuid}):
|
||||
with patch.object(view, 'editing', new=True):
|
||||
|
||||
# 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'))
|
||||
# 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 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")
|
||||
# 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
|
||||
|
@ -166,7 +262,7 @@ class TestUserView(WebTestCase):
|
|||
# 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)
|
||||
user = view.objectify(form)
|
||||
self.assertIs(user, barney)
|
||||
self.assertEqual(barney.username, 'barneyx')
|
||||
|
||||
|
@ -182,7 +278,8 @@ class TestUserView(WebTestCase):
|
|||
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)
|
||||
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")
|
||||
|
@ -194,7 +291,8 @@ class TestUserView(WebTestCase):
|
|||
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)
|
||||
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])
|
||||
|
@ -205,7 +303,8 @@ class TestUserView(WebTestCase):
|
|||
form = view.make_model_form(model_instance=barney)
|
||||
form.validated = {'username': 'barney',
|
||||
'roles': {blokes.uuid, others.uuid}}
|
||||
user = view.objectify(form, session=self.session)
|
||||
with patch.object(view, 'Session', return_value=self.session):
|
||||
user = view.objectify(form)
|
||||
self.assertIs(user, barney)
|
||||
self.assertEqual(len(user.roles), 3)
|
||||
|
||||
|
@ -214,6 +313,7 @@ class TestUserView(WebTestCase):
|
|||
form = view.make_model_form(model_instance=barney)
|
||||
form.validated = {'username': 'barney',
|
||||
'roles': {blokes.uuid, others.uuid}}
|
||||
user = view.objectify(form, session=self.session)
|
||||
with patch.object(view, 'Session', return_value=self.session):
|
||||
user = view.objectify(form)
|
||||
self.assertIs(user, barney)
|
||||
self.assertEqual(len(user.roles), 2)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue