| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  | # -*- coding: utf-8; -*- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-11 22:38:51 -06:00
										 |  |  | import datetime | 
					
						
							| 
									
										
										
										
											2025-01-07 13:34:42 -06:00
										 |  |  | import decimal | 
					
						
							| 
									
										
										
										
											2024-12-11 22:38:51 -06:00
										 |  |  | from unittest import TestCase | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  | from unittest.mock import patch | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import colander | 
					
						
							|  |  |  | from pyramid import testing | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from sqlalchemy import orm | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from wuttjamaican.conf import WuttaConfig | 
					
						
							| 
									
										
										
										
											2025-10-29 18:32:35 -05:00
										 |  |  | from wuttjamaican.testing import DataTestCase | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  | from wuttaweb.forms import schema as mod | 
					
						
							| 
									
										
										
										
											2024-08-21 14:38:34 -05:00
										 |  |  | from wuttaweb.forms import widgets | 
					
						
							| 
									
										
										
										
											2025-10-29 18:32:35 -05:00
										 |  |  | from wuttaweb.testing import WebTestCase | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-07 13:34:42 -06:00
										 |  |  | class TestWuttaDateTime(TestCase): | 
					
						
							| 
									
										
										
										
											2024-12-11 22:38:51 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_deserialize(self): | 
					
						
							|  |  |  |         typ = mod.WuttaDateTime() | 
					
						
							|  |  |  |         node = colander.SchemaNode(typ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         result = typ.deserialize(node, colander.null) | 
					
						
							|  |  |  |         self.assertIs(result, colander.null) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         result = typ.deserialize(node, "2024-12-11T10:33 PM") | 
					
						
							| 
									
										
										
										
											2024-12-11 22:38:51 -06:00
										 |  |  |         self.assertIsInstance(result, datetime.datetime) | 
					
						
							|  |  |  |         self.assertEqual(result, datetime.datetime(2024, 12, 11, 22, 33)) | 
					
						
							| 
									
										
										
										
											2024-12-12 15:15:00 -06:00
										 |  |  |         self.assertIsNone(result.tzinfo) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         result = typ.deserialize(node, "2024-12-11T22:33:00") | 
					
						
							| 
									
										
										
										
											2024-12-12 15:15:00 -06:00
										 |  |  |         self.assertIsInstance(result, datetime.datetime) | 
					
						
							|  |  |  |         self.assertEqual(result, datetime.datetime(2024, 12, 11, 22, 33)) | 
					
						
							|  |  |  |         self.assertIsNone(result.tzinfo) | 
					
						
							| 
									
										
										
										
											2024-12-11 22:38:51 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertRaises(colander.Invalid, typ.deserialize, node, "bogus") | 
					
						
							| 
									
										
										
										
											2024-12-11 22:38:51 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  | class TestObjectNode(DataTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def setUp(self): | 
					
						
							|  |  |  |         self.setup_db() | 
					
						
							|  |  |  |         self.request = testing.DummyRequest(wutta_config=self.config) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_dictify(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  |         person = model.Person(full_name="Betty Boop") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-15 20:51:36 -05:00
										 |  |  |         # unsupported type is converted to string | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  |         node = mod.ObjectNode(colander.String()) | 
					
						
							| 
									
										
										
										
											2024-08-15 20:51:36 -05:00
										 |  |  |         value = node.dictify(person) | 
					
						
							|  |  |  |         self.assertEqual(value, "Betty Boop") | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # but supported type can dictify | 
					
						
							|  |  |  |         node = mod.ObjectNode(mod.PersonRef(self.request)) | 
					
						
							|  |  |  |         value = node.dictify(person) | 
					
						
							|  |  |  |         self.assertIs(value, person) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_objectify(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  |         person = model.Person(full_name="Betty Boop") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # unsupported type raises error | 
					
						
							|  |  |  |         node = mod.ObjectNode(colander.String()) | 
					
						
							|  |  |  |         self.assertRaises(NotImplementedError, node.objectify, person) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # but supported type can objectify | 
					
						
							|  |  |  |         node = mod.ObjectNode(mod.PersonRef(self.request)) | 
					
						
							|  |  |  |         value = node.objectify(person) | 
					
						
							|  |  |  |         self.assertIs(value, person) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  | class TestWuttaEnum(WebTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_widget_maker(self): | 
					
						
							|  |  |  |         enum = self.app.enum | 
					
						
							|  |  |  |         typ = mod.WuttaEnum(self.request, enum.UpgradeStatus) | 
					
						
							|  |  |  |         widget = typ.widget_maker() | 
					
						
							|  |  |  |         self.assertIsInstance(widget, widgets.SelectWidget) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-08 12:29:42 -06:00
										 |  |  | MOCK_STATUS_ONE = 1 | 
					
						
							|  |  |  | MOCK_STATUS_TWO = 2 | 
					
						
							|  |  |  | MOCK_STATUS = { | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |     MOCK_STATUS_ONE: "one", | 
					
						
							|  |  |  |     MOCK_STATUS_TWO: "two", | 
					
						
							| 
									
										
										
										
											2025-01-08 12:29:42 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-08 12:29:42 -06:00
										 |  |  | class TestWuttaDictEnum(WebTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_widget_maker(self): | 
					
						
							|  |  |  |         typ = mod.WuttaDictEnum(self.request, MOCK_STATUS) | 
					
						
							|  |  |  |         widget = typ.widget_maker() | 
					
						
							|  |  |  |         self.assertIsInstance(widget, widgets.SelectWidget) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             widget.values, | 
					
						
							|  |  |  |             [ | 
					
						
							|  |  |  |                 (1, "one"), | 
					
						
							|  |  |  |                 (2, "two"), | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2025-01-08 12:29:42 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-28 20:33:56 -06:00
										 |  |  | class TestWuttaMoney(WebTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_widget_maker(self): | 
					
						
							|  |  |  |         enum = self.app.enum | 
					
						
							| 
									
										
										
										
											2025-01-07 13:40:44 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # default scale | 
					
						
							| 
									
										
										
										
											2024-12-28 20:33:56 -06:00
										 |  |  |         typ = mod.WuttaMoney(self.request) | 
					
						
							|  |  |  |         widget = typ.widget_maker() | 
					
						
							|  |  |  |         self.assertIsInstance(widget, widgets.WuttaMoneyInputWidget) | 
					
						
							| 
									
										
										
										
											2025-01-07 13:40:44 -06:00
										 |  |  |         self.assertEqual(widget.scale, 2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # custom scale | 
					
						
							|  |  |  |         typ = mod.WuttaMoney(self.request, scale=4) | 
					
						
							|  |  |  |         widget = typ.widget_maker() | 
					
						
							|  |  |  |         self.assertIsInstance(widget, widgets.WuttaMoneyInputWidget) | 
					
						
							|  |  |  |         self.assertEqual(widget.scale, 4) | 
					
						
							| 
									
										
										
										
											2024-12-28 20:33:56 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-02 21:28:55 -06:00
										 |  |  | class TestWuttaQuantity(WebTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-07 13:34:42 -06:00
										 |  |  |     def test_serialize(self): | 
					
						
							|  |  |  |         node = colander.SchemaNode(mod.WuttaQuantity(self.request)) | 
					
						
							|  |  |  |         typ = node.typ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # null | 
					
						
							|  |  |  |         result = typ.serialize(node, colander.null) | 
					
						
							|  |  |  |         self.assertIs(result, colander.null) | 
					
						
							|  |  |  |         result = typ.serialize(node, None) | 
					
						
							|  |  |  |         self.assertIs(result, colander.null) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # quantity | 
					
						
							|  |  |  |         result = typ.serialize(node, 42) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(result, "42") | 
					
						
							| 
									
										
										
										
											2025-01-07 13:34:42 -06:00
										 |  |  |         result = typ.serialize(node, 42.00) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(result, "42") | 
					
						
							|  |  |  |         result = typ.serialize(node, decimal.Decimal("42.00")) | 
					
						
							|  |  |  |         self.assertEqual(result, "42") | 
					
						
							| 
									
										
										
										
											2025-01-07 13:34:42 -06:00
										 |  |  |         result = typ.serialize(node, 42.13) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(result, "42.13") | 
					
						
							| 
									
										
										
										
											2025-01-02 21:28:55 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  | class TestObjectRef(DataTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def setUp(self): | 
					
						
							|  |  |  |         self.setup_db() | 
					
						
							|  |  |  |         self.request = testing.DummyRequest(wutta_config=self.config) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_empty_option(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # null by default | 
					
						
							|  |  |  |         typ = mod.ObjectRef(self.request) | 
					
						
							|  |  |  |         self.assertIsNone(typ.empty_option) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # passing true yields default empty option | 
					
						
							|  |  |  |         typ = mod.ObjectRef(self.request, empty_option=True) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(typ.empty_option, ("", "(none)")) | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can set explicitly | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         typ = mod.ObjectRef(self.request, empty_option=("foo", "bar")) | 
					
						
							|  |  |  |         self.assertEqual(typ.empty_option, ("foo", "bar")) | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can set just a label | 
					
						
							|  |  |  |         typ = mod.ObjectRef(self.request, empty_option="(empty)") | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(typ.empty_option, ("", "(empty)")) | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_model_class(self): | 
					
						
							|  |  |  |         typ = mod.ObjectRef(self.request) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertRaises(NotImplementedError, getattr, typ, "model_class") | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_serialize(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  |         node = colander.SchemaNode(colander.String()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # null | 
					
						
							|  |  |  |         typ = mod.ObjectRef(self.request) | 
					
						
							|  |  |  |         value = typ.serialize(node, colander.null) | 
					
						
							|  |  |  |         self.assertIs(value, colander.null) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # model instance | 
					
						
							|  |  |  |         person = model.Person(full_name="Betty Boop") | 
					
						
							|  |  |  |         self.session.add(person) | 
					
						
							|  |  |  |         self.session.commit() | 
					
						
							|  |  |  |         self.assertIsNotNone(person.uuid) | 
					
						
							|  |  |  |         typ = mod.ObjectRef(self.request) | 
					
						
							|  |  |  |         value = typ.serialize(node, person) | 
					
						
							| 
									
										
										
										
											2024-12-09 20:56:09 -06:00
										 |  |  |         self.assertEqual(value, person.uuid.hex) | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-11 09:48:50 -06:00
										 |  |  |         # null w/ empty option | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         typ = mod.ObjectRef(self.request, empty_option=("bad", "BAD")) | 
					
						
							| 
									
										
										
										
											2024-12-11 09:48:50 -06:00
										 |  |  |         value = typ.serialize(node, colander.null) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(value, "bad") | 
					
						
							| 
									
										
										
										
											2024-12-11 09:48:50 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  |     def test_deserialize(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  |         node = colander.SchemaNode(colander.String()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # null | 
					
						
							|  |  |  |         typ = mod.ObjectRef(self.request) | 
					
						
							|  |  |  |         value = typ.deserialize(node, colander.null) | 
					
						
							|  |  |  |         self.assertIs(value, colander.null) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # model instance | 
					
						
							|  |  |  |         person = model.Person(full_name="Betty Boop") | 
					
						
							|  |  |  |         self.session.add(person) | 
					
						
							|  |  |  |         self.session.commit() | 
					
						
							|  |  |  |         self.assertIsNotNone(person.uuid) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(mod.ObjectRef, "model_class", new=model.Person): | 
					
						
							|  |  |  |             with patch.object(mod, "Session", return_value=self.session): | 
					
						
							| 
									
										
										
										
											2025-01-02 21:09:31 -06:00
										 |  |  |                 typ = mod.ObjectRef(self.request) | 
					
						
							|  |  |  |                 value = typ.deserialize(node, person.uuid) | 
					
						
							|  |  |  |                 self.assertIs(value, person) | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_dictify(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  |         node = colander.SchemaNode(colander.String()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # model instance | 
					
						
							|  |  |  |         person = model.Person(full_name="Betty Boop") | 
					
						
							|  |  |  |         self.session.add(person) | 
					
						
							|  |  |  |         self.session.commit() | 
					
						
							|  |  |  |         self.assertIsNotNone(person.uuid) | 
					
						
							|  |  |  |         typ = mod.ObjectRef(self.request) | 
					
						
							|  |  |  |         value = typ.dictify(person) | 
					
						
							|  |  |  |         self.assertIs(value, person) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_objectify(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  |         node = colander.SchemaNode(colander.String()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # null | 
					
						
							|  |  |  |         typ = mod.ObjectRef(self.request) | 
					
						
							|  |  |  |         value = typ.objectify(None) | 
					
						
							|  |  |  |         self.assertIsNone(value) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(mod, "Session", return_value=self.session): | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-02 21:09:31 -06:00
										 |  |  |             # model instance | 
					
						
							|  |  |  |             person = model.Person(full_name="Betty Boop") | 
					
						
							|  |  |  |             self.session.add(person) | 
					
						
							|  |  |  |             self.session.commit() | 
					
						
							|  |  |  |             self.assertIsNotNone(person.uuid) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             with patch.object(mod.ObjectRef, "model_class", new=model.Person): | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-02 21:09:31 -06:00
										 |  |  |                 # can specify as uuid | 
					
						
							|  |  |  |                 typ = mod.ObjectRef(self.request) | 
					
						
							|  |  |  |                 value = typ.objectify(person.uuid) | 
					
						
							|  |  |  |                 self.assertIs(value, person) | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-02 21:09:31 -06:00
										 |  |  |                 # or can specify object proper | 
					
						
							|  |  |  |                 typ = mod.ObjectRef(self.request) | 
					
						
							|  |  |  |                 value = typ.objectify(person) | 
					
						
							|  |  |  |                 self.assertIs(value, person) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # error if not found | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             with patch.object(mod.ObjectRef, "model_class", new=model.Person): | 
					
						
							| 
									
										
										
										
											2025-01-02 21:09:31 -06:00
										 |  |  |                 typ = mod.ObjectRef(self.request) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |                 self.assertRaises(ValueError, typ.objectify, "WRONG-UUID") | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_get_query(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(mod.ObjectRef, "model_class", new=model.Person): | 
					
						
							|  |  |  |             with patch.object(mod, "Session", return_value=self.session): | 
					
						
							| 
									
										
										
										
											2025-01-02 21:09:31 -06:00
										 |  |  |                 typ = mod.ObjectRef(self.request) | 
					
						
							|  |  |  |                 query = typ.get_query() | 
					
						
							|  |  |  |                 self.assertIsInstance(query, orm.Query) | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_sort_query(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(mod.ObjectRef, "model_class", new=model.Person): | 
					
						
							|  |  |  |             with patch.object(mod, "Session", return_value=self.session): | 
					
						
							| 
									
										
										
										
											2025-01-02 21:09:31 -06:00
										 |  |  |                 typ = mod.ObjectRef(self.request) | 
					
						
							|  |  |  |                 query = typ.get_query() | 
					
						
							|  |  |  |                 sorted_query = typ.sort_query(query) | 
					
						
							|  |  |  |                 self.assertIs(sorted_query, query) | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_widget_maker(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  |         person = model.Person(full_name="Betty Boop") | 
					
						
							|  |  |  |         self.session.add(person) | 
					
						
							|  |  |  |         self.session.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # basic | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(mod.ObjectRef, "model_class", new=model.Person): | 
					
						
							|  |  |  |             with patch.object(mod, "Session", return_value=self.session): | 
					
						
							| 
									
										
										
										
											2025-01-02 21:09:31 -06:00
										 |  |  |                 typ = mod.ObjectRef(self.request) | 
					
						
							|  |  |  |                 widget = typ.widget_maker() | 
					
						
							|  |  |  |                 self.assertEqual(len(widget.values), 1) | 
					
						
							|  |  |  |                 self.assertEqual(widget.values[0][1], "Betty Boop") | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # empty option | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(mod.ObjectRef, "model_class", new=model.Person): | 
					
						
							|  |  |  |             with patch.object(mod, "Session", return_value=self.session): | 
					
						
							| 
									
										
										
										
											2025-01-02 21:09:31 -06:00
										 |  |  |                 typ = mod.ObjectRef(self.request, empty_option=True) | 
					
						
							|  |  |  |                 widget = typ.widget_maker() | 
					
						
							|  |  |  |                 self.assertEqual(len(widget.values), 2) | 
					
						
							|  |  |  |                 self.assertEqual(widget.values[0][1], "(none)") | 
					
						
							|  |  |  |                 self.assertEqual(widget.values[1][1], "Betty Boop") | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  | class TestPersonRef(WebTestCase): | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_sort_query(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(mod, "Session", return_value=self.session): | 
					
						
							| 
									
										
										
										
											2025-01-02 21:09:31 -06:00
										 |  |  |             typ = mod.PersonRef(self.request) | 
					
						
							|  |  |  |             query = typ.get_query() | 
					
						
							|  |  |  |             self.assertIsInstance(query, orm.Query) | 
					
						
							|  |  |  |             sorted_query = typ.sort_query(query) | 
					
						
							|  |  |  |             self.assertIsInstance(sorted_query, orm.Query) | 
					
						
							|  |  |  |             self.assertIsNot(sorted_query, query) | 
					
						
							| 
									
										
										
										
											2024-08-13 21:43:56 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  |     def test_get_object_url(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.pyramid_config.add_route("people.view", "/people/{uuid}") | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  |         model = self.app.model | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(mod, "Session", return_value=self.session): | 
					
						
							| 
									
										
										
										
											2025-01-02 21:09:31 -06:00
										 |  |  |             typ = mod.PersonRef(self.request) | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-02 21:09:31 -06:00
										 |  |  |             person = model.Person(full_name="Barney Rubble") | 
					
						
							|  |  |  |             self.session.add(person) | 
					
						
							|  |  |  |             self.session.commit() | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-02 21:09:31 -06:00
										 |  |  |             url = typ.get_object_url(person) | 
					
						
							|  |  |  |             self.assertIsNotNone(url) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertIn(f"/people/{person.uuid}", url) | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-12 19:24:36 -06:00
										 |  |  | class TestRoleRef(WebTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_sort_query(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(mod, "Session", return_value=self.session): | 
					
						
							| 
									
										
										
										
											2025-01-02 21:09:31 -06:00
										 |  |  |             typ = mod.RoleRef(self.request) | 
					
						
							|  |  |  |             query = typ.get_query() | 
					
						
							|  |  |  |             self.assertIsInstance(query, orm.Query) | 
					
						
							|  |  |  |             sorted_query = typ.sort_query(query) | 
					
						
							|  |  |  |             self.assertIsInstance(sorted_query, orm.Query) | 
					
						
							|  |  |  |             self.assertIsNot(sorted_query, query) | 
					
						
							| 
									
										
										
										
											2024-12-12 19:24:36 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_get_object_url(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.pyramid_config.add_route("roles.view", "/roles/{uuid}") | 
					
						
							| 
									
										
										
										
											2024-12-12 19:24:36 -06:00
										 |  |  |         model = self.app.model | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(mod, "Session", return_value=self.session): | 
					
						
							| 
									
										
										
										
											2025-01-02 21:09:31 -06:00
										 |  |  |             typ = mod.RoleRef(self.request) | 
					
						
							| 
									
										
										
										
											2024-12-12 19:24:36 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             role = model.Role(name="Manager") | 
					
						
							| 
									
										
										
										
											2025-01-02 21:09:31 -06:00
										 |  |  |             self.session.add(role) | 
					
						
							|  |  |  |             self.session.commit() | 
					
						
							| 
									
										
										
										
											2024-12-12 19:24:36 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-02 21:09:31 -06:00
										 |  |  |             url = typ.get_object_url(role) | 
					
						
							|  |  |  |             self.assertIsNotNone(url) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertIn(f"/roles/{role.uuid}", url) | 
					
						
							| 
									
										
										
										
											2024-12-12 19:24:36 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  | class TestUserRef(WebTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_sort_query(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(mod, "Session", return_value=self.session): | 
					
						
							| 
									
										
										
										
											2025-01-02 21:09:31 -06:00
										 |  |  |             typ = mod.UserRef(self.request) | 
					
						
							|  |  |  |             query = typ.get_query() | 
					
						
							|  |  |  |             self.assertIsInstance(query, orm.Query) | 
					
						
							|  |  |  |             sorted_query = typ.sort_query(query) | 
					
						
							|  |  |  |             self.assertIsInstance(sorted_query, orm.Query) | 
					
						
							|  |  |  |             self.assertIsNot(sorted_query, query) | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_get_object_url(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.pyramid_config.add_route("users.view", "/users/{uuid}") | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  |         model = self.app.model | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(mod, "Session", return_value=self.session): | 
					
						
							| 
									
										
										
										
											2025-01-02 21:09:31 -06:00
										 |  |  |             typ = mod.UserRef(self.request) | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             user = model.User(username="barney") | 
					
						
							| 
									
										
										
										
											2025-01-02 21:09:31 -06:00
										 |  |  |             self.session.add(user) | 
					
						
							|  |  |  |             self.session.commit() | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-02 21:09:31 -06:00
										 |  |  |             url = typ.get_object_url(user) | 
					
						
							|  |  |  |             self.assertIsNotNone(url) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertIn(f"/users/{user.uuid}", url) | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-13 21:43:56 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | class TestRoleRefs(DataTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def setUp(self): | 
					
						
							|  |  |  |         self.setup_db() | 
					
						
							|  |  |  |         self.request = testing.DummyRequest(wutta_config=self.config) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_widget_maker(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) | 
					
						
							|  |  |  |         self.session.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(mod, "Session", return_value=self.session): | 
					
						
							| 
									
										
										
										
											2024-08-14 15:10:54 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-02 21:09:31 -06:00
										 |  |  |             # with root access, default values include: admin, blokes | 
					
						
							|  |  |  |             self.request.is_root = True | 
					
						
							|  |  |  |             typ = mod.RoleRefs(self.request) | 
					
						
							|  |  |  |             widget = typ.widget_maker() | 
					
						
							|  |  |  |             self.assertEqual(len(widget.values), 2) | 
					
						
							|  |  |  |             self.assertEqual(widget.values[0][1], "Administrator") | 
					
						
							|  |  |  |             self.assertEqual(widget.values[1][1], "Blokes") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # without root, default values include: blokes | 
					
						
							|  |  |  |             self.request.is_root = False | 
					
						
							|  |  |  |             typ = mod.RoleRefs(self.request) | 
					
						
							|  |  |  |             widget = typ.widget_maker() | 
					
						
							|  |  |  |             self.assertEqual(len(widget.values), 1) | 
					
						
							|  |  |  |             self.assertEqual(widget.values[0][1], "Blokes") | 
					
						
							| 
									
										
										
										
											2024-12-12 20:07:49 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-14 15:10:54 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | class TestPermissions(DataTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def setUp(self): | 
					
						
							|  |  |  |         self.setup_db() | 
					
						
							|  |  |  |         self.request = testing.DummyRequest(wutta_config=self.config) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_widget_maker(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # no supported permissions | 
					
						
							|  |  |  |         permissions = {} | 
					
						
							|  |  |  |         typ = mod.Permissions(self.request, permissions) | 
					
						
							|  |  |  |         widget = typ.widget_maker() | 
					
						
							|  |  |  |         self.assertEqual(len(widget.values), 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # supported permissions are morphed to values | 
					
						
							|  |  |  |         permissions = { | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             "widgets": { | 
					
						
							|  |  |  |                 "label": "Widgets", | 
					
						
							|  |  |  |                 "perms": { | 
					
						
							|  |  |  |                     "widgets.polish": { | 
					
						
							|  |  |  |                         "label": "Polish the widgets", | 
					
						
							| 
									
										
										
										
											2024-08-14 15:10:54 -05:00
										 |  |  |                     }, | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         typ = mod.Permissions(self.request, permissions) | 
					
						
							|  |  |  |         widget = typ.widget_maker() | 
					
						
							|  |  |  |         self.assertEqual(len(widget.values), 1) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(widget.values[0], ("widgets.polish", "Polish the widgets")) | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestFileDownload(DataTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def setUp(self): | 
					
						
							|  |  |  |         self.setup_db() | 
					
						
							|  |  |  |         self.request = testing.DummyRequest(wutta_config=self.config) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_widget_maker(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # sanity / coverage check | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         typ = mod.FileDownload(self.request, url="/foo") | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  |         widget = typ.widget_maker() | 
					
						
							|  |  |  |         self.assertIsInstance(widget, widgets.FileDownloadWidget) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(widget.url, "/foo") | 
					
						
							| 
									
										
										
										
											2024-12-23 19:24:17 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestEmailRecipients(TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_serialize(self): | 
					
						
							|  |  |  |         typ = mod.EmailRecipients() | 
					
						
							|  |  |  |         node = colander.SchemaNode(typ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         recips = [ | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             "alice@example.com", | 
					
						
							|  |  |  |             "bob@example.com", | 
					
						
							| 
									
										
										
										
											2024-12-23 19:24:17 -06:00
										 |  |  |         ] | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         recips_str = ", ".join(recips) | 
					
						
							| 
									
										
										
										
											2024-12-23 19:24:17 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # values | 
					
						
							|  |  |  |         result = typ.serialize(node, recips_str) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(result, "\n".join(recips)) | 
					
						
							| 
									
										
										
										
											2024-12-23 19:24:17 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # null | 
					
						
							|  |  |  |         result = typ.serialize(node, colander.null) | 
					
						
							|  |  |  |         self.assertIs(result, colander.null) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_deserialize(self): | 
					
						
							|  |  |  |         typ = mod.EmailRecipients() | 
					
						
							|  |  |  |         node = colander.SchemaNode(typ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         recips = [ | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             "alice@example.com", | 
					
						
							|  |  |  |             "bob@example.com", | 
					
						
							| 
									
										
										
										
											2024-12-23 19:24:17 -06:00
										 |  |  |         ] | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         recips_str = ", ".join(recips) | 
					
						
							| 
									
										
										
										
											2024-12-23 19:24:17 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # values | 
					
						
							|  |  |  |         result = typ.deserialize(node, recips_str) | 
					
						
							|  |  |  |         self.assertEqual(result, recips_str) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # null | 
					
						
							|  |  |  |         result = typ.deserialize(node, colander.null) | 
					
						
							|  |  |  |         self.assertIs(result, colander.null) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_widget_maker(self): | 
					
						
							|  |  |  |         typ = mod.EmailRecipients() | 
					
						
							|  |  |  |         widget = typ.widget_maker() | 
					
						
							|  |  |  |         self.assertIsInstance(widget, widgets.EmailRecipientsWidget) |