feat: refactor forms/grids/views/templates per wuttaweb compat
this starts to get things more aligned between wuttaweb and tailbone. the use case in mind so far is for a wuttaweb view to be included in a tailbone app. form and grid classes now have some new methods to match wuttaweb, so templates call the shared method names where possible. templates can no longer assume they have tailbone-native master view, form, grid etc. so must inspect context more closely in some cases.
This commit is contained in:
parent
b53479f8e4
commit
a6ce5eb21d
39 changed files with 1037 additions and 300 deletions
|
@ -12,9 +12,6 @@ class TestCase(unittest.TestCase):
|
|||
|
||||
def setUp(self):
|
||||
self.config = testing.setUp()
|
||||
# TODO: this probably shouldn't (need to) be here
|
||||
self.config.add_directive('add_tailbone_permission_group', 'tailbone.auth.add_permission_group')
|
||||
self.config.add_directive('add_tailbone_permission', 'tailbone.auth.add_permission')
|
||||
|
||||
def tearDown(self):
|
||||
testing.tearDown()
|
||||
|
|
0
tests/forms/__init__.py
Normal file
0
tests/forms/__init__.py
Normal file
153
tests/forms/test_core.py
Normal file
153
tests/forms/test_core.py
Normal file
|
@ -0,0 +1,153 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
import deform
|
||||
from pyramid import testing
|
||||
|
||||
from tailbone.forms import core as mod
|
||||
from tests.util import WebTestCase
|
||||
|
||||
|
||||
class TestForm(WebTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.setup_web()
|
||||
self.config.setdefault('rattail.web.menus.handler_spec', 'tests.util:NullMenuHandler')
|
||||
|
||||
def make_form(self, **kwargs):
|
||||
kwargs.setdefault('request', self.request)
|
||||
return mod.Form(**kwargs)
|
||||
|
||||
def test_basic(self):
|
||||
form = self.make_form()
|
||||
self.assertIsInstance(form, mod.Form)
|
||||
|
||||
def test_vue_tagname(self):
|
||||
|
||||
# default
|
||||
form = self.make_form()
|
||||
self.assertEqual(form.vue_tagname, 'tailbone-form')
|
||||
|
||||
# can override with param
|
||||
form = self.make_form(vue_tagname='something-else')
|
||||
self.assertEqual(form.vue_tagname, 'something-else')
|
||||
|
||||
# can still pass old param
|
||||
form = self.make_form(component='legacy-name')
|
||||
self.assertEqual(form.vue_tagname, 'legacy-name')
|
||||
|
||||
def test_vue_component(self):
|
||||
|
||||
# default
|
||||
form = self.make_form()
|
||||
self.assertEqual(form.vue_component, 'TailboneForm')
|
||||
|
||||
# can override with param
|
||||
form = self.make_form(vue_tagname='something-else')
|
||||
self.assertEqual(form.vue_component, 'SomethingElse')
|
||||
|
||||
# can still pass old param
|
||||
form = self.make_form(component='legacy-name')
|
||||
self.assertEqual(form.vue_component, 'LegacyName')
|
||||
|
||||
def test_component(self):
|
||||
|
||||
# default
|
||||
form = self.make_form()
|
||||
self.assertEqual(form.component, 'tailbone-form')
|
||||
|
||||
# can override with param
|
||||
form = self.make_form(vue_tagname='something-else')
|
||||
self.assertEqual(form.component, 'something-else')
|
||||
|
||||
# can still pass old param
|
||||
form = self.make_form(component='legacy-name')
|
||||
self.assertEqual(form.component, 'legacy-name')
|
||||
|
||||
def test_component_studly(self):
|
||||
|
||||
# default
|
||||
form = self.make_form()
|
||||
self.assertEqual(form.component_studly, 'TailboneForm')
|
||||
|
||||
# can override with param
|
||||
form = self.make_form(vue_tagname='something-else')
|
||||
self.assertEqual(form.component_studly, 'SomethingElse')
|
||||
|
||||
# can still pass old param
|
||||
form = self.make_form(component='legacy-name')
|
||||
self.assertEqual(form.component_studly, 'LegacyName')
|
||||
|
||||
def test_button_label_submit(self):
|
||||
form = self.make_form()
|
||||
|
||||
# default
|
||||
self.assertEqual(form.button_label_submit, "Submit")
|
||||
|
||||
# can set submit_label
|
||||
with patch.object(form, 'submit_label', new="Submit Label", create=True):
|
||||
self.assertEqual(form.button_label_submit, "Submit Label")
|
||||
|
||||
# can set save_label
|
||||
with patch.object(form, 'save_label', new="Save Label"):
|
||||
self.assertEqual(form.button_label_submit, "Save Label")
|
||||
|
||||
# can set button_label_submit
|
||||
form.button_label_submit = "New Label"
|
||||
self.assertEqual(form.button_label_submit, "New Label")
|
||||
|
||||
def test_get_deform(self):
|
||||
model = self.app.model
|
||||
|
||||
# sanity check
|
||||
form = self.make_form(model_class=model.Setting)
|
||||
dform = form.get_deform()
|
||||
self.assertIsInstance(dform, deform.Form)
|
||||
|
||||
def test_render_vue_tag(self):
|
||||
model = self.app.model
|
||||
|
||||
# sanity check
|
||||
form = self.make_form(model_class=model.Setting)
|
||||
html = form.render_vue_tag()
|
||||
self.assertIn('<tailbone-form', html)
|
||||
|
||||
def test_render_vue_template(self):
|
||||
self.pyramid_config.include('tailbone.views.common')
|
||||
model = self.app.model
|
||||
|
||||
# sanity check
|
||||
form = self.make_form(model_class=model.Setting)
|
||||
html = form.render_vue_template(session=self.session)
|
||||
self.assertIn('<form ', html)
|
||||
|
||||
def test_get_vue_field_value(self):
|
||||
model = self.app.model
|
||||
form = self.make_form(model_class=model.Setting)
|
||||
|
||||
# TODO: yikes what a hack (?)
|
||||
dform = form.get_deform()
|
||||
dform.set_appstruct({'name': 'foo', 'value': 'bar'})
|
||||
|
||||
# null for missing field
|
||||
value = form.get_vue_field_value('doesnotexist')
|
||||
self.assertIsNone(value)
|
||||
|
||||
# normal value is returned
|
||||
value = form.get_vue_field_value('name')
|
||||
self.assertEqual(value, 'foo')
|
||||
|
||||
# but not if we remove field from deform
|
||||
# TODO: what is the use case here again?
|
||||
dform.children.remove(dform['name'])
|
||||
value = form.get_vue_field_value('name')
|
||||
self.assertIsNone(value)
|
||||
|
||||
def test_render_vue_field(self):
|
||||
model = self.app.model
|
||||
|
||||
# sanity check
|
||||
form = self.make_form(model_class=model.Setting)
|
||||
html = form.render_vue_field('name', session=self.session)
|
||||
self.assertIn('<b-field ', html)
|
0
tests/grids/__init__.py
Normal file
0
tests/grids/__init__.py
Normal file
139
tests/grids/test_core.py
Normal file
139
tests/grids/test_core.py
Normal file
|
@ -0,0 +1,139 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from tailbone.grids import core as mod
|
||||
from tests.util import WebTestCase
|
||||
|
||||
|
||||
class TestGrid(WebTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.setup_web()
|
||||
self.config.setdefault('rattail.web.menus.handler_spec', 'tests.util:NullMenuHandler')
|
||||
|
||||
def make_grid(self, key, data=[], **kwargs):
|
||||
kwargs.setdefault('request', self.request)
|
||||
return mod.Grid(key, data=data, **kwargs)
|
||||
|
||||
def test_basic(self):
|
||||
grid = self.make_grid('foo')
|
||||
self.assertIsInstance(grid, mod.Grid)
|
||||
|
||||
def test_vue_tagname(self):
|
||||
|
||||
# default
|
||||
grid = self.make_grid('foo')
|
||||
self.assertEqual(grid.vue_tagname, 'tailbone-grid')
|
||||
|
||||
# can override with param
|
||||
grid = self.make_grid('foo', vue_tagname='something-else')
|
||||
self.assertEqual(grid.vue_tagname, 'something-else')
|
||||
|
||||
# can still pass old param
|
||||
grid = self.make_grid('foo', component='legacy-name')
|
||||
self.assertEqual(grid.vue_tagname, 'legacy-name')
|
||||
|
||||
def test_vue_component(self):
|
||||
|
||||
# default
|
||||
grid = self.make_grid('foo')
|
||||
self.assertEqual(grid.vue_component, 'TailboneGrid')
|
||||
|
||||
# can override with param
|
||||
grid = self.make_grid('foo', vue_tagname='something-else')
|
||||
self.assertEqual(grid.vue_component, 'SomethingElse')
|
||||
|
||||
# can still pass old param
|
||||
grid = self.make_grid('foo', component='legacy-name')
|
||||
self.assertEqual(grid.vue_component, 'LegacyName')
|
||||
|
||||
def test_component(self):
|
||||
|
||||
# default
|
||||
grid = self.make_grid('foo')
|
||||
self.assertEqual(grid.component, 'tailbone-grid')
|
||||
|
||||
# can override with param
|
||||
grid = self.make_grid('foo', vue_tagname='something-else')
|
||||
self.assertEqual(grid.component, 'something-else')
|
||||
|
||||
# can still pass old param
|
||||
grid = self.make_grid('foo', component='legacy-name')
|
||||
self.assertEqual(grid.component, 'legacy-name')
|
||||
|
||||
def test_component_studly(self):
|
||||
|
||||
# default
|
||||
grid = self.make_grid('foo')
|
||||
self.assertEqual(grid.component_studly, 'TailboneGrid')
|
||||
|
||||
# can override with param
|
||||
grid = self.make_grid('foo', vue_tagname='something-else')
|
||||
self.assertEqual(grid.component_studly, 'SomethingElse')
|
||||
|
||||
# can still pass old param
|
||||
grid = self.make_grid('foo', component='legacy-name')
|
||||
self.assertEqual(grid.component_studly, 'LegacyName')
|
||||
|
||||
def test_actions(self):
|
||||
|
||||
# default
|
||||
grid = self.make_grid('foo')
|
||||
self.assertEqual(grid.actions, [])
|
||||
|
||||
# main actions
|
||||
grid = self.make_grid('foo', main_actions=['foo'])
|
||||
self.assertEqual(grid.actions, ['foo'])
|
||||
|
||||
# more actions
|
||||
grid = self.make_grid('foo', main_actions=['foo'], more_actions=['bar'])
|
||||
self.assertEqual(grid.actions, ['foo', 'bar'])
|
||||
|
||||
def test_render_vue_tag(self):
|
||||
model = self.app.model
|
||||
|
||||
# standard
|
||||
grid = self.make_grid('settings', model_class=model.Setting)
|
||||
html = grid.render_vue_tag()
|
||||
self.assertIn('<tailbone-grid', html)
|
||||
self.assertNotIn('@deleteActionClicked', html)
|
||||
|
||||
# with delete hook
|
||||
master = MagicMock(deletable=True, delete_confirm='simple')
|
||||
master.has_perm.return_value = True
|
||||
grid = self.make_grid('settings', model_class=model.Setting)
|
||||
html = grid.render_vue_tag(master=master)
|
||||
self.assertIn('<tailbone-grid', html)
|
||||
self.assertIn('@deleteActionClicked', html)
|
||||
|
||||
def test_render_vue_template(self):
|
||||
# self.pyramid_config.include('tailbone.views.common')
|
||||
model = self.app.model
|
||||
|
||||
# sanity check
|
||||
grid = self.make_grid('settings', model_class=model.Setting)
|
||||
html = grid.render_vue_template(session=self.session)
|
||||
self.assertIn('<b-table', html)
|
||||
|
||||
def test_get_vue_columns(self):
|
||||
model = self.app.model
|
||||
|
||||
# sanity check
|
||||
grid = self.make_grid('settings', model_class=model.Setting)
|
||||
columns = grid.get_vue_columns()
|
||||
self.assertEqual(len(columns), 2)
|
||||
self.assertEqual(columns[0]['field'], 'name')
|
||||
self.assertEqual(columns[1]['field'], 'value')
|
||||
|
||||
def test_get_vue_data(self):
|
||||
model = self.app.model
|
||||
|
||||
# sanity check
|
||||
grid = self.make_grid('settings', model_class=model.Setting)
|
||||
data = grid.get_vue_data()
|
||||
self.assertEqual(data, [])
|
||||
|
||||
# calling again returns same data
|
||||
data2 = grid.get_vue_data()
|
||||
self.assertIs(data2, data)
|
|
@ -3,14 +3,14 @@
|
|||
import os
|
||||
from unittest import TestCase
|
||||
|
||||
from sqlalchemy import create_engine
|
||||
from pyramid.config import Configurator
|
||||
|
||||
from wuttjamaican.testing import FileConfigTestCase
|
||||
|
||||
from rattail.config import RattailConfig
|
||||
from rattail.exceptions import ConfigurationError
|
||||
from rattail.db import Session as RattailSession
|
||||
|
||||
from tailbone import app
|
||||
from tailbone.db import Session as TailboneSession
|
||||
from rattail.config import RattailConfig
|
||||
from tailbone import app as mod
|
||||
from tests.util import DataTestCase
|
||||
|
||||
|
||||
class TestRattailConfig(TestCase):
|
||||
|
@ -18,15 +18,34 @@ class TestRattailConfig(TestCase):
|
|||
config_path = os.path.abspath(
|
||||
os.path.join(os.path.dirname(__file__), 'data', 'tailbone.conf'))
|
||||
|
||||
def tearDown(self):
|
||||
# may or may not be necessary depending on test
|
||||
TailboneSession.remove()
|
||||
|
||||
def test_settings_arg_must_include_config_path_by_default(self):
|
||||
# error raised if path not provided
|
||||
self.assertRaises(ConfigurationError, app.make_rattail_config, {})
|
||||
self.assertRaises(ConfigurationError, mod.make_rattail_config, {})
|
||||
# get a config object if path provided
|
||||
result = app.make_rattail_config({'rattail.config': self.config_path})
|
||||
result = mod.make_rattail_config({'rattail.config': self.config_path})
|
||||
# nb. cannot test isinstance(RattailConfig) b/c now uses wrapper!
|
||||
self.assertIsNotNone(result)
|
||||
self.assertTrue(hasattr(result, 'get'))
|
||||
|
||||
|
||||
class TestMakePyramidConfig(DataTestCase):
|
||||
|
||||
def make_config(self):
|
||||
myconf = self.write_file('web.conf', """
|
||||
[rattail.db]
|
||||
default.url = sqlite://
|
||||
""")
|
||||
|
||||
self.settings = {
|
||||
'rattail.config': myconf,
|
||||
'mako.directories': 'tailbone:templates',
|
||||
}
|
||||
return mod.make_rattail_config(self.settings)
|
||||
|
||||
def test_basic(self):
|
||||
model = self.app.model
|
||||
model.Base.metadata.create_all(bind=self.config.appdb_engine)
|
||||
|
||||
# sanity check
|
||||
pyramid_config = mod.make_pyramid_config(self.settings)
|
||||
self.assertIsInstance(pyramid_config, Configurator)
|
||||
|
|
3
tests/test_auth.py
Normal file
3
tests/test_auth.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
from tailbone import auth as mod
|
12
tests/test_config.py
Normal file
12
tests/test_config.py
Normal file
|
@ -0,0 +1,12 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
from tailbone import config as mod
|
||||
from tests.util import DataTestCase
|
||||
|
||||
|
||||
class TestConfigExtension(DataTestCase):
|
||||
|
||||
def test_basic(self):
|
||||
# sanity / coverage check
|
||||
ext = mod.ConfigExtension()
|
||||
ext.configure(self.config)
|
58
tests/test_subscribers.py
Normal file
58
tests/test_subscribers.py
Normal file
|
@ -0,0 +1,58 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from pyramid import testing
|
||||
|
||||
from tailbone import subscribers as mod
|
||||
from tests.util import DataTestCase
|
||||
|
||||
|
||||
class TestNewRequest(DataTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.setup_db()
|
||||
self.request = self.make_request()
|
||||
self.pyramid_config = testing.setUp(request=self.request, settings={
|
||||
'wutta_config': self.config,
|
||||
})
|
||||
|
||||
def tearDown(self):
|
||||
self.teardown_db()
|
||||
testing.tearDown()
|
||||
|
||||
def make_request(self, **kwargs):
|
||||
return testing.DummyRequest(**kwargs)
|
||||
|
||||
def make_event(self):
|
||||
return MagicMock(request=self.request)
|
||||
|
||||
def test_continuum_remote_addr(self):
|
||||
event = self.make_event()
|
||||
|
||||
# nothing happens
|
||||
mod.new_request(event, session=self.session)
|
||||
self.assertFalse(hasattr(self.session, 'continuum_remote_addr'))
|
||||
|
||||
# unless request has client_addr
|
||||
self.request.client_addr = '127.0.0.1'
|
||||
mod.new_request(event, session=self.session)
|
||||
self.assertEqual(self.session.continuum_remote_addr, '127.0.0.1')
|
||||
|
||||
def test_register_component(self):
|
||||
event = self.make_event()
|
||||
|
||||
# function added
|
||||
self.assertFalse(hasattr(self.request, 'register_component'))
|
||||
mod.new_request(event, session=self.session)
|
||||
self.assertTrue(callable(self.request.register_component))
|
||||
|
||||
# call function
|
||||
self.request.register_component('tailbone-datepicker', 'TailboneDatepicker')
|
||||
self.assertEqual(self.request._tailbone_registered_components,
|
||||
{'tailbone-datepicker': 'TailboneDatepicker'})
|
||||
|
||||
# duplicate registration ignored
|
||||
self.request.register_component('tailbone-datepicker', 'TailboneDatepicker')
|
||||
self.assertEqual(self.request._tailbone_registered_components,
|
||||
{'tailbone-datepicker': 'TailboneDatepicker'})
|
75
tests/util.py
Normal file
75
tests/util.py
Normal file
|
@ -0,0 +1,75 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from pyramid import testing
|
||||
|
||||
from tailbone import subscribers
|
||||
from wuttaweb.menus import MenuHandler
|
||||
# from wuttaweb.subscribers import new_request_set_user
|
||||
from rattail.testing import DataTestCase
|
||||
|
||||
|
||||
class WebTestCase(DataTestCase):
|
||||
"""
|
||||
Base class for test suites requiring a full (typical) web app.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.setup_web()
|
||||
|
||||
def setup_web(self):
|
||||
self.setup_db()
|
||||
self.request = self.make_request()
|
||||
self.pyramid_config = testing.setUp(request=self.request, settings={
|
||||
'wutta_config': self.config,
|
||||
'rattail_config': self.config,
|
||||
'mako.directories': ['tailbone:templates'],
|
||||
# 'pyramid_deform.template_search_path': 'wuttaweb:templates/deform',
|
||||
})
|
||||
|
||||
# init web
|
||||
# self.pyramid_config.include('pyramid_deform')
|
||||
self.pyramid_config.include('pyramid_mako')
|
||||
self.pyramid_config.add_directive('add_wutta_permission_group',
|
||||
'wuttaweb.auth.add_permission_group')
|
||||
self.pyramid_config.add_directive('add_wutta_permission',
|
||||
'wuttaweb.auth.add_permission')
|
||||
self.pyramid_config.add_directive('add_tailbone_permission_group',
|
||||
'wuttaweb.auth.add_permission_group')
|
||||
self.pyramid_config.add_directive('add_tailbone_permission',
|
||||
'wuttaweb.auth.add_permission')
|
||||
self.pyramid_config.add_directive('add_tailbone_index_page',
|
||||
'tailbone.app.add_index_page')
|
||||
self.pyramid_config.add_directive('add_tailbone_model_view',
|
||||
'tailbone.app.add_model_view')
|
||||
self.pyramid_config.add_subscriber('tailbone.subscribers.before_render',
|
||||
'pyramid.events.BeforeRender')
|
||||
self.pyramid_config.include('tailbone.static')
|
||||
|
||||
# setup new request w/ anonymous user
|
||||
event = MagicMock(request=self.request)
|
||||
subscribers.new_request(event, session=self.session)
|
||||
# def user_getter(request, **kwargs): pass
|
||||
# new_request_set_user(event, db_session=self.session,
|
||||
# user_getter=user_getter)
|
||||
|
||||
def tearDown(self):
|
||||
self.teardown_web()
|
||||
|
||||
def teardown_web(self):
|
||||
testing.tearDown()
|
||||
self.teardown_db()
|
||||
|
||||
def make_request(self, **kwargs):
|
||||
kwargs.setdefault('rattail_config', self.config)
|
||||
# kwargs.setdefault('wutta_config', self.config)
|
||||
return testing.DummyRequest(**kwargs)
|
||||
|
||||
|
||||
class NullMenuHandler(MenuHandler):
|
||||
"""
|
||||
Dummy menu handler for testing.
|
||||
"""
|
||||
def make_menus(self, request, **kwargs):
|
||||
return []
|
26
tests/views/test_master.py
Normal file
26
tests/views/test_master.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from tailbone.views import master as mod
|
||||
from tests.util import WebTestCase
|
||||
|
||||
|
||||
class TestMasterView(WebTestCase):
|
||||
|
||||
def make_view(self):
|
||||
return mod.MasterView(self.request)
|
||||
|
||||
def test_make_form_kwargs(self):
|
||||
self.pyramid_config.add_route('settings.view', '/settings/{name}')
|
||||
model = self.app.model
|
||||
setting = model.Setting(name='foo', value='bar')
|
||||
self.session.add(setting)
|
||||
self.session.commit()
|
||||
with patch.multiple(mod.MasterView, create=True,
|
||||
model_class=model.Setting):
|
||||
view = self.make_view()
|
||||
|
||||
# sanity / coverage check
|
||||
kw = view.make_form_kwargs(model_instance=setting)
|
||||
self.assertIsNotNone(kw['action_url'])
|
29
tests/views/test_principal.py
Normal file
29
tests/views/test_principal.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
from unittest.mock import patch, MagicMock
|
||||
|
||||
from tailbone.views import principal as mod
|
||||
from tests.util import WebTestCase
|
||||
|
||||
|
||||
class TestPrincipalMasterView(WebTestCase):
|
||||
|
||||
def make_view(self):
|
||||
return mod.PrincipalMasterView(self.request)
|
||||
|
||||
def test_find_by_perm(self):
|
||||
model = self.app.model
|
||||
self.config.setdefault('rattail.web.menus.handler_spec', 'tests.util:NullMenuHandler')
|
||||
self.pyramid_config.include('tailbone.views.common')
|
||||
self.pyramid_config.include('tailbone.views.auth')
|
||||
self.pyramid_config.add_route('roles', '/roles/')
|
||||
with patch.multiple(mod.PrincipalMasterView, create=True,
|
||||
model_class=model.Role,
|
||||
get_help_url=MagicMock(return_value=None),
|
||||
get_help_markdown=MagicMock(return_value=None),
|
||||
can_edit_help=MagicMock(return_value=False)):
|
||||
|
||||
# sanity / coverage check
|
||||
view = self.make_view()
|
||||
response = view.find_by_perm()
|
||||
self.assertEqual(response.status_code, 200)
|
80
tests/views/test_roles.py
Normal file
80
tests/views/test_roles.py
Normal file
|
@ -0,0 +1,80 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from tailbone.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('tailbone.views.roles')
|
||||
|
||||
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'])
|
33
tests/views/test_users.py
Normal file
33
tests/views/test_users.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
from unittest.mock import patch, MagicMock
|
||||
|
||||
from tailbone.views import users as mod
|
||||
from tailbone.views.principal import PermissionsRenderer
|
||||
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('tailbone.views.users')
|
||||
|
||||
def test_configure_form(self):
|
||||
self.pyramid_config.include('tailbone.views.users')
|
||||
model = self.app.model
|
||||
barney = model.User(username='barney')
|
||||
self.session.add(barney)
|
||||
self.session.commit()
|
||||
view = self.make_view()
|
||||
|
||||
# must use mock configure when making form
|
||||
def configure(form): pass
|
||||
form = view.make_form(instance=barney, configure=configure)
|
||||
|
||||
with patch.object(view, 'viewing', new=True):
|
||||
self.assertNotIn('permissions', form.renderers)
|
||||
view.configure_form(form)
|
||||
self.assertIsInstance(form.renderers['permissions'], PermissionsRenderer)
|
Loading…
Add table
Add a link
Reference in a new issue