243 lines
8.8 KiB
Python
243 lines
8.8 KiB
Python
# -*- coding: utf-8; -*-
|
|
|
|
from unittest.mock import patch
|
|
|
|
from sqlalchemy import orm
|
|
|
|
import colander
|
|
|
|
from wuttaweb.views import roles as mod
|
|
from tests.util import WebTestCase
|
|
|
|
|
|
class TestRoleView(WebTestCase):
|
|
|
|
def make_view(self):
|
|
return mod.RoleView(self.request)
|
|
|
|
def test_includeme(self):
|
|
self.pyramid_config.include('wuttaweb.views.roles')
|
|
|
|
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.Role)
|
|
self.assertFalse(grid.is_linked('name'))
|
|
view.configure_grid(grid)
|
|
self.assertTrue(grid.is_linked('name'))
|
|
|
|
def test_is_editable(self):
|
|
model = self.app.model
|
|
auth = self.app.get_auth_handler()
|
|
blokes = model.Role(name="Blokes")
|
|
self.session.add(blokes)
|
|
self.session.commit()
|
|
view = self.make_view()
|
|
|
|
admin = auth.get_role_administrator(self.session)
|
|
authed = auth.get_role_authenticated(self.session)
|
|
anon = auth.get_role_anonymous(self.session)
|
|
|
|
# editable by default
|
|
self.assertTrue(view.is_editable(blokes))
|
|
|
|
# built-in roles not editable by default
|
|
self.assertFalse(view.is_editable(admin))
|
|
self.assertFalse(view.is_editable(authed))
|
|
self.assertFalse(view.is_editable(anon))
|
|
|
|
# reset
|
|
del self.request.user_permissions
|
|
|
|
barney = model.User(username='barney')
|
|
self.session.add(barney)
|
|
barney.roles.append(blokes)
|
|
auth.grant_permission(blokes, 'roles.edit_builtin')
|
|
self.session.commit()
|
|
|
|
# user with perms can edit *some* built-in
|
|
self.request.user = barney
|
|
self.assertTrue(view.is_editable(authed))
|
|
self.assertTrue(view.is_editable(anon))
|
|
# nb. not this one yet
|
|
self.assertFalse(view.is_editable(admin))
|
|
|
|
def test_is_deletable(self):
|
|
model = self.app.model
|
|
auth = self.app.get_auth_handler()
|
|
blokes = model.Role(name="Blokes")
|
|
self.session.add(blokes)
|
|
self.session.commit()
|
|
view = self.make_view()
|
|
|
|
# deletable by default
|
|
self.assertTrue(view.is_deletable(blokes))
|
|
|
|
# built-in roles not deletable
|
|
self.assertFalse(view.is_deletable(auth.get_role_administrator(self.session)))
|
|
self.assertFalse(view.is_deletable(auth.get_role_authenticated(self.session)))
|
|
self.assertFalse(view.is_deletable(auth.get_role_anonymous(self.session)))
|
|
|
|
def test_configure_form(self):
|
|
model = self.app.model
|
|
role = model.Role(name="Foo")
|
|
view = self.make_view()
|
|
form = view.make_form(model_instance=role)
|
|
self.assertNotIn('name', form.validators)
|
|
view.configure_form(form)
|
|
self.assertIsNotNone(form.validators['name'])
|
|
|
|
def test_unique_name(self):
|
|
model = self.app.model
|
|
view = self.make_view()
|
|
|
|
role = model.Role(name='Foo')
|
|
self.session.add(role)
|
|
self.session.commit()
|
|
|
|
with patch.object(mod, 'Session', return_value=self.session):
|
|
|
|
# invalid if same name in data
|
|
node = colander.SchemaNode(colander.String(), name='name')
|
|
self.assertRaises(colander.Invalid, view.unique_name, node, 'Foo')
|
|
|
|
# but not if name belongs to current role
|
|
view.editing = True
|
|
self.request.matchdict = {'uuid': role.uuid}
|
|
node = colander.SchemaNode(colander.String(), name='name')
|
|
self.assertIsNone(view.unique_name(node, 'Foo'))
|
|
|
|
def get_permissions(self):
|
|
return {
|
|
'widgets': {
|
|
'label': "Widgets",
|
|
'perms': {
|
|
'widgets.list': {
|
|
'label': "List widgets",
|
|
},
|
|
'widgets.polish': {
|
|
'label': "Polish the widgets",
|
|
},
|
|
'widgets.view': {
|
|
'label': "View widget",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
def test_get_available_permissions(self):
|
|
model = self.app.model
|
|
auth = self.app.get_auth_handler()
|
|
blokes = model.Role(name="Blokes")
|
|
auth.grant_permission(blokes, 'widgets.list')
|
|
self.session.add(blokes)
|
|
barney = model.User(username='barney')
|
|
barney.roles.append(blokes)
|
|
self.session.add(barney)
|
|
self.session.commit()
|
|
view = self.make_view()
|
|
all_perms = self.get_permissions()
|
|
self.request.registry.settings['wutta_permissions'] = all_perms
|
|
|
|
def has_perm(perm):
|
|
if perm == 'widgets.list':
|
|
return True
|
|
return False
|
|
|
|
with patch.object(self.request, 'has_perm', new=has_perm, create=True):
|
|
|
|
# sanity check; current request has 1 perm
|
|
self.assertTrue(self.request.has_perm('widgets.list'))
|
|
self.assertFalse(self.request.has_perm('widgets.polish'))
|
|
self.assertFalse(self.request.has_perm('widgets.view'))
|
|
|
|
# when editing, user sees only the 1 perm
|
|
with patch.object(view, 'editing', new=True):
|
|
perms = view.get_available_permissions()
|
|
self.assertEqual(list(perms), ['widgets'])
|
|
self.assertEqual(list(perms['widgets']['perms']), ['widgets.list'])
|
|
|
|
# but when viewing, same user sees all perms
|
|
with patch.object(view, 'viewing', new=True):
|
|
perms = view.get_available_permissions()
|
|
self.assertEqual(list(perms), ['widgets'])
|
|
self.assertEqual(list(perms['widgets']['perms']),
|
|
['widgets.list', 'widgets.polish', 'widgets.view'])
|
|
|
|
# also, when admin user is editing, sees all perms
|
|
self.request.is_admin = True
|
|
with patch.object(view, 'editing', new=True):
|
|
perms = view.get_available_permissions()
|
|
self.assertEqual(list(perms), ['widgets'])
|
|
self.assertEqual(list(perms['widgets']['perms']),
|
|
['widgets.list', 'widgets.polish', 'widgets.view'])
|
|
|
|
def test_objectify(self):
|
|
model = self.app.model
|
|
auth = self.app.get_auth_handler()
|
|
blokes = model.Role(name="Blokes")
|
|
self.session.add(blokes)
|
|
barney = model.User(username='barney')
|
|
barney.roles.append(blokes)
|
|
self.session.add(barney)
|
|
self.session.commit()
|
|
view = self.make_view()
|
|
permissions = self.get_permissions()
|
|
|
|
# sanity check, role has just 1 perm
|
|
auth.grant_permission(blokes, 'widgets.list')
|
|
self.session.commit()
|
|
self.assertEqual(blokes.permissions, ['widgets.list'])
|
|
|
|
# form can update role perms
|
|
view.editing = True
|
|
self.request.matchdict = {'uuid': blokes.uuid}
|
|
with patch.object(view, 'get_available_permissions', return_value=permissions):
|
|
form = view.make_model_form(model_instance=blokes)
|
|
form.validated = {'name': 'Blokes',
|
|
'permissions': {'widgets.list', 'widgets.polish', 'widgets.view'}}
|
|
role = view.objectify(form)
|
|
self.session.commit()
|
|
self.assertIs(role, blokes)
|
|
self.assertEqual(blokes.permissions, ['widgets.list', 'widgets.polish', 'widgets.view'])
|
|
|
|
def test_update_permissions(self):
|
|
model = self.app.model
|
|
auth = self.app.get_auth_handler()
|
|
blokes = model.Role(name="Blokes")
|
|
auth.grant_permission(blokes, 'widgets.list')
|
|
self.session.add(blokes)
|
|
barney = model.User(username='barney')
|
|
barney.roles.append(blokes)
|
|
self.session.add(barney)
|
|
self.session.commit()
|
|
view = self.make_view()
|
|
permissions = self.get_permissions()
|
|
|
|
with patch.object(view, 'get_available_permissions', return_value=permissions):
|
|
|
|
# no error if data is missing perms
|
|
form = view.make_model_form(model_instance=blokes)
|
|
form.validated = {'name': 'BloX'}
|
|
role = view.objectify(form)
|
|
self.session.commit()
|
|
self.assertIs(role, blokes)
|
|
self.assertEqual(blokes.name, 'BloX')
|
|
|
|
# sanity check, role has just 1 perm
|
|
self.assertEqual(blokes.permissions, ['widgets.list'])
|
|
|
|
# role perms are updated
|
|
form = view.make_model_form(model_instance=blokes)
|
|
form.validated = {'name': 'Blokes',
|
|
'permissions': {'widgets.polish', 'widgets.view'}}
|
|
role = view.objectify(form)
|
|
self.session.commit()
|
|
self.assertIs(role, blokes)
|
|
self.assertEqual(blokes.permissions, ['widgets.polish', 'widgets.view'])
|