# -*- coding: utf-8; -*- import datetime import decimal import functools from unittest import TestCase from unittest.mock import MagicMock, patch from sqlalchemy import orm from pyramid import testing from pyramid.response import Response from pyramid.httpexceptions import HTTPNotFound from wuttjamaican.conf import WuttaConfig from wuttaweb.views import master as mod from wuttaweb.views import View from wuttaweb.progress import SessionProgress from wuttaweb.subscribers import new_request_set_user from tests.util import WebTestCase class TestMasterView(WebTestCase): def make_view(self): return mod.MasterView(self.request) def test_defaults(self): with patch.multiple(mod.MasterView, create=True, model_name='Widget', model_key='uuid', deletable_bulk=True, has_autocomplete=True, configurable=True): mod.MasterView.defaults(self.pyramid_config) ############################## # class methods ############################## def test_get_model_class(self): # no model class by default self.assertIsNone(mod.MasterView.get_model_class()) # subclass may specify MyModel = MagicMock() with patch.multiple(mod.MasterView, create=True, model_class=MyModel): self.assertIs(mod.MasterView.get_model_class(), MyModel) def test_get_model_name(self): # error by default (since no model class) self.assertRaises(AttributeError, mod.MasterView.get_model_name) # subclass may specify model name with patch.multiple(mod.MasterView, create=True, model_name='Widget'): self.assertEqual(mod.MasterView.get_model_name(), 'Widget') # or it may specify model class MyModel = MagicMock(__name__='Blaster') with patch.multiple(mod.MasterView, create=True, model_class=MyModel): self.assertEqual(mod.MasterView.get_model_name(), 'Blaster') def test_get_model_name_normalized(self): # error by default (since no model class) self.assertRaises(AttributeError, mod.MasterView.get_model_name_normalized) # subclass may specify *normalized* model name with patch.multiple(mod.MasterView, create=True, model_name_normalized='widget'): self.assertEqual(mod.MasterView.get_model_name_normalized(), 'widget') # or it may specify *standard* model name with patch.multiple(mod.MasterView, create=True, model_name='Blaster'): self.assertEqual(mod.MasterView.get_model_name_normalized(), 'blaster') # or it may specify model class MyModel = MagicMock(__name__='Dinosaur') with patch.multiple(mod.MasterView, create=True, model_class=MyModel): self.assertEqual(mod.MasterView.get_model_name_normalized(), 'dinosaur') def test_get_model_title(self): # error by default (since no model class) self.assertRaises(AttributeError, mod.MasterView.get_model_title) # subclass may specify model title with patch.multiple(mod.MasterView, create=True, model_title='Wutta Widget'): self.assertEqual(mod.MasterView.get_model_title(), "Wutta Widget") # or it may specify model name with patch.multiple(mod.MasterView, create=True, model_name='Blaster'): self.assertEqual(mod.MasterView.get_model_title(), "Blaster") # or it may specify model class MyModel = MagicMock(__name__='Dinosaur') with patch.multiple(mod.MasterView, create=True, model_class=MyModel): self.assertEqual(mod.MasterView.get_model_title(), "Dinosaur") def test_get_model_title_plural(self): # error by default (since no model class) self.assertRaises(AttributeError, mod.MasterView.get_model_title_plural) # subclass may specify *plural* model title with patch.multiple(mod.MasterView, create=True, model_title_plural='People'): self.assertEqual(mod.MasterView.get_model_title_plural(), "People") # or it may specify *singular* model title with patch.multiple(mod.MasterView, create=True, model_title='Wutta Widget'): self.assertEqual(mod.MasterView.get_model_title_plural(), "Wutta Widgets") # or it may specify model name with patch.multiple(mod.MasterView, create=True, model_name='Blaster'): self.assertEqual(mod.MasterView.get_model_title_plural(), "Blasters") # or it may specify model class MyModel = MagicMock(__name__='Dinosaur') with patch.multiple(mod.MasterView, create=True, model_class=MyModel): self.assertEqual(mod.MasterView.get_model_title_plural(), "Dinosaurs") def test_get_model_key(self): # error by default (since no model class) self.assertRaises(AttributeError, mod.MasterView.get_model_key) # subclass may specify model key with patch.multiple(mod.MasterView, create=True, model_key='uuid'): self.assertEqual(mod.MasterView.get_model_key(), ('uuid',)) def test_get_route_prefix(self): # error by default (since no model class) self.assertRaises(AttributeError, mod.MasterView.get_route_prefix) # subclass may specify route prefix with patch.multiple(mod.MasterView, create=True, route_prefix='widgets'): self.assertEqual(mod.MasterView.get_route_prefix(), 'widgets') # subclass may specify *normalized* model name with patch.multiple(mod.MasterView, create=True, model_name_normalized='blaster'): self.assertEqual(mod.MasterView.get_route_prefix(), 'blasters') # or it may specify *standard* model name with patch.multiple(mod.MasterView, create=True, model_name = 'Dinosaur'): self.assertEqual(mod.MasterView.get_route_prefix(), 'dinosaurs') # or it may specify model class MyModel = MagicMock(__name__='Truck') with patch.multiple(mod.MasterView, create=True, model_class=MyModel): self.assertEqual(mod.MasterView.get_route_prefix(), 'trucks') def test_get_permission_prefix(self): # error by default (since no model class) self.assertRaises(AttributeError, mod.MasterView.get_permission_prefix) # subclass may specify permission prefix with patch.object(mod.MasterView, 'permission_prefix', new='widgets', create=True): self.assertEqual(mod.MasterView.get_permission_prefix(), 'widgets') # subclass may specify route prefix with patch.object(mod.MasterView, 'route_prefix', new='widgets', create=True): self.assertEqual(mod.MasterView.get_permission_prefix(), 'widgets') # or it may specify model class Truck = MagicMock(__name__='Truck') with patch.object(mod.MasterView, 'model_class', new=Truck, create=True): self.assertEqual(mod.MasterView.get_permission_prefix(), 'trucks') def test_get_url_prefix(self): # error by default (since no model class) self.assertRaises(AttributeError, mod.MasterView.get_url_prefix) # subclass may specify url prefix with patch.multiple(mod.MasterView, create=True, url_prefix='/widgets'): self.assertEqual(mod.MasterView.get_url_prefix(), '/widgets') # or it may specify route prefix with patch.multiple(mod.MasterView, create=True, route_prefix='trucks'): self.assertEqual(mod.MasterView.get_url_prefix(), '/trucks') # or it may specify *normalized* model name with patch.multiple(mod.MasterView, create=True, model_name_normalized='blaster'): self.assertEqual(mod.MasterView.get_url_prefix(), '/blasters') # or it may specify *standard* model name with patch.multiple(mod.MasterView, create=True, model_name='Dinosaur'): self.assertEqual(mod.MasterView.get_url_prefix(), '/dinosaurs') # or it may specify model class MyModel = MagicMock(__name__='Machine') with patch.multiple(mod.MasterView, create=True, model_class=MyModel): self.assertEqual(mod.MasterView.get_url_prefix(), '/machines') def test_get_instance_url_prefix(self): # error by default (since no model class) self.assertRaises(AttributeError, mod.MasterView.get_instance_url_prefix) # typical example with url_prefix and simple key with patch.multiple(mod.MasterView, create=True, url_prefix='/widgets', model_key='uuid'): self.assertEqual(mod.MasterView.get_instance_url_prefix(), '/widgets/{uuid}') # typical example with composite key with patch.multiple(mod.MasterView, create=True, url_prefix='/widgets', model_key=('foo', 'bar')): self.assertEqual(mod.MasterView.get_instance_url_prefix(), '/widgets/{foo}|{bar}') def test_get_template_prefix(self): # error by default (since no model class) self.assertRaises(AttributeError, mod.MasterView.get_template_prefix) # subclass may specify template prefix with patch.multiple(mod.MasterView, create=True, template_prefix='/widgets'): self.assertEqual(mod.MasterView.get_template_prefix(), '/widgets') # or it may specify url prefix with patch.multiple(mod.MasterView, create=True, url_prefix='/trees'): self.assertEqual(mod.MasterView.get_template_prefix(), '/trees') # or it may specify route prefix with patch.multiple(mod.MasterView, create=True, route_prefix='trucks'): self.assertEqual(mod.MasterView.get_template_prefix(), '/trucks') # or it may specify *normalized* model name with patch.multiple(mod.MasterView, create=True, model_name_normalized='blaster'): self.assertEqual(mod.MasterView.get_template_prefix(), '/blasters') # or it may specify *standard* model name with patch.multiple(mod.MasterView, create=True, model_name='Dinosaur'): self.assertEqual(mod.MasterView.get_template_prefix(), '/dinosaurs') # or it may specify model class MyModel = MagicMock(__name__='Machine') with patch.multiple(mod.MasterView, create=True, model_class=MyModel): self.assertEqual(mod.MasterView.get_template_prefix(), '/machines') def test_get_grid_key(self): # error by default (since no model class) self.assertRaises(AttributeError, mod.MasterView.get_grid_key) # subclass may specify grid key with patch.multiple(mod.MasterView, create=True, grid_key='widgets'): self.assertEqual(mod.MasterView.get_grid_key(), 'widgets') # or it may specify route prefix with patch.multiple(mod.MasterView, create=True, route_prefix='trucks'): self.assertEqual(mod.MasterView.get_grid_key(), 'trucks') # or it may specify *normalized* model name with patch.multiple(mod.MasterView, create=True, model_name_normalized='blaster'): self.assertEqual(mod.MasterView.get_grid_key(), 'blasters') # or it may specify *standard* model name with patch.multiple(mod.MasterView, create=True, model_name='Dinosaur'): self.assertEqual(mod.MasterView.get_grid_key(), 'dinosaurs') # or it may specify model class MyModel = MagicMock(__name__='Machine') with patch.multiple(mod.MasterView, create=True, model_class=MyModel): self.assertEqual(mod.MasterView.get_grid_key(), 'machines') def test_get_config_title(self): # error by default (since no model class) self.assertRaises(AttributeError, mod.MasterView.get_config_title) # subclass may specify config title with patch.multiple(mod.MasterView, create=True, config_title='Widgets'): self.assertEqual(mod.MasterView.get_config_title(), "Widgets") # subclass may specify *plural* model title with patch.multiple(mod.MasterView, create=True, model_title_plural='People'): self.assertEqual(mod.MasterView.get_config_title(), "People") # or it may specify *singular* model title with patch.multiple(mod.MasterView, create=True, model_title='Wutta Widget'): self.assertEqual(mod.MasterView.get_config_title(), "Wutta Widgets") # or it may specify model name with patch.multiple(mod.MasterView, create=True, model_name='Blaster'): self.assertEqual(mod.MasterView.get_config_title(), "Blasters") # or it may specify model class MyModel = MagicMock(__name__='Dinosaur') with patch.multiple(mod.MasterView, create=True, model_class=MyModel): self.assertEqual(mod.MasterView.get_config_title(), "Dinosaurs") ############################## # support methods ############################## def test_get_class_hierarchy(self): class MyView(mod.MasterView): pass view = MyView(self.request) classes = view.get_class_hierarchy() self.assertEqual(classes, [View, mod.MasterView, MyView]) def test_has_perm(self): model = self.app.model auth = self.app.get_auth_handler() with patch.multiple(mod.MasterView, create=True, model_name='Setting'): view = self.make_view() # anonymous user self.assertFalse(view.has_perm('list')) self.assertFalse(self.request.has_perm('list')) # reset del self.request.user_permissions # make user with perms barney = model.User(username='barney') self.session.add(barney) blokes = model.Role(name="Blokes") self.session.add(blokes) barney.roles.append(blokes) auth.grant_permission(blokes, 'settings.list') self.session.commit() # this user has perms self.request.user = barney self.assertTrue(view.has_perm('list')) self.assertTrue(self.request.has_perm('settings.list')) def test_has_any_perm(self): model = self.app.model auth = self.app.get_auth_handler() with patch.multiple(mod.MasterView, create=True, model_name='Setting'): view = self.make_view() # anonymous user self.assertFalse(view.has_any_perm('list', 'view')) self.assertFalse(self.request.has_any_perm('settings.list', 'settings.view')) # reset del self.request.user_permissions # make user with perms barney = model.User(username='barney') self.session.add(barney) blokes = model.Role(name="Blokes") self.session.add(blokes) barney.roles.append(blokes) auth.grant_permission(blokes, 'settings.view') self.session.commit() # this user has perms self.request.user = barney self.assertTrue(view.has_any_perm('list', 'view')) self.assertTrue(self.request.has_any_perm('settings.list', 'settings.view')) def test_make_button(self): view = self.make_view() # normal html = view.make_button('click me') self.assertIn('