| 
									
										
										
										
											2024-08-07 14:00:53 -05:00
										 |  |  | # -*- coding: utf-8; -*- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-12 15:15:00 -06:00
										 |  |  | import datetime | 
					
						
							| 
									
										
										
										
											2025-01-02 20:13:04 -06:00
										 |  |  | import decimal | 
					
						
							| 
									
										
										
										
											2025-02-21 13:27:52 -06:00
										 |  |  | from collections import OrderedDict | 
					
						
							|  |  |  | from enum import Enum | 
					
						
							| 
									
										
										
										
											2024-08-07 14:00:53 -05:00
										 |  |  | from unittest import TestCase | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | from unittest.mock import patch, MagicMock | 
					
						
							| 
									
										
										
										
											2024-08-07 14:00:53 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-23 12:10:51 -05:00
										 |  |  | import sqlalchemy as sa | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | from sqlalchemy import orm | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  | from paginate import Page | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | from paginate_sqlalchemy import SqlalchemyOrmPage | 
					
						
							| 
									
										
										
										
											2024-08-07 14:00:53 -05:00
										 |  |  | from pyramid import testing | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from wuttjamaican.conf import WuttaConfig | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | from wuttaweb.grids import base as mod | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  | from wuttaweb.grids.filters import ( | 
					
						
							|  |  |  |     GridFilter, | 
					
						
							|  |  |  |     StringAlchemyFilter, | 
					
						
							|  |  |  |     default_sqlalchemy_filters, | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2024-08-21 14:38:34 -05:00
										 |  |  | from wuttaweb.util import FieldList | 
					
						
							|  |  |  | from wuttaweb.forms import Form | 
					
						
							| 
									
										
										
										
											2025-01-06 16:47:48 -06:00
										 |  |  | from wuttaweb.testing import WebTestCase | 
					
						
							| 
									
										
										
										
											2024-08-07 14:00:53 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-16 18:19:24 -05:00
										 |  |  | class TestGrid(WebTestCase): | 
					
						
							| 
									
										
										
										
											2024-08-07 14:00:53 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def make_grid(self, request=None, **kwargs): | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         return mod.Grid(request or self.request, **kwargs) | 
					
						
							| 
									
										
										
										
											2024-08-07 14:00:53 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_constructor(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # empty | 
					
						
							|  |  |  |         grid = self.make_grid() | 
					
						
							|  |  |  |         self.assertIsNone(grid.key) | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  |         self.assertEqual(grid.columns, []) | 
					
						
							| 
									
										
										
										
											2024-08-07 14:00:53 -05:00
										 |  |  |         self.assertIsNone(grid.data) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # now with columns | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["foo", "bar"]) | 
					
						
							| 
									
										
										
										
											2024-08-07 14:00:53 -05:00
										 |  |  |         self.assertIsInstance(grid.columns, FieldList) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.columns, ["foo", "bar"]) | 
					
						
							| 
									
										
										
										
											2024-08-07 14:00:53 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |     def test_constructor_sorting(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # defaults, not sortable | 
					
						
							|  |  |  |         grid = self.make_grid() | 
					
						
							|  |  |  |         self.assertFalse(grid.sortable) | 
					
						
							|  |  |  |         self.assertTrue(grid.sort_on_backend) | 
					
						
							|  |  |  |         self.assertEqual(grid.sorters, {}) | 
					
						
							|  |  |  |         self.assertEqual(grid.sort_defaults, []) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # defaults, sortable | 
					
						
							|  |  |  |         grid = self.make_grid(sortable=True) | 
					
						
							|  |  |  |         self.assertTrue(grid.sortable) | 
					
						
							|  |  |  |         self.assertTrue(grid.sort_on_backend) | 
					
						
							|  |  |  |         self.assertEqual(grid.sorters, {}) | 
					
						
							|  |  |  |         self.assertEqual(grid.sort_defaults, []) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # sorters may be pre-populated | 
					
						
							|  |  |  |         grid = self.make_grid(model_class=model.Setting, sortable=True) | 
					
						
							|  |  |  |         self.assertEqual(len(grid.sorters), 2) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertIn("name", grid.sorters) | 
					
						
							|  |  |  |         self.assertIn("value", grid.sorters) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         self.assertEqual(grid.sort_defaults, []) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # sort defaults as str | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             model_class=model.Setting, sortable=True, sort_defaults="name" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual(grid.sort_defaults, [mod.SortInfo("name", "asc")]) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # sort defaults as tuple | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             model_class=model.Setting, sortable=True, sort_defaults=("name", "desc") | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual(grid.sort_defaults, [mod.SortInfo("name", "desc")]) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # sort defaults as list w/ single tuple | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             model_class=model.Setting, sortable=True, sort_defaults=[("name", "desc")] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual(grid.sort_defaults, [mod.SortInfo("name", "desc")]) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-18 19:23:15 -05:00
										 |  |  |         # multi-column defaults | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             model_class=model.Setting, | 
					
						
							|  |  |  |             sortable=True, | 
					
						
							|  |  |  |             sort_multiple=True, | 
					
						
							|  |  |  |             sort_defaults=[("name", "desc"), ("value", "asc")], | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-18 19:23:15 -05:00
										 |  |  |         self.assertTrue(grid.sort_multiple) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             grid.sort_defaults, | 
					
						
							|  |  |  |             [mod.SortInfo("name", "desc"), mod.SortInfo("value", "asc")], | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-18 19:23:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # multi-column sort disabled for oruga | 
					
						
							|  |  |  |         self.request.use_oruga = True | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             model_class=model.Setting, sortable=True, sort_multiple=True | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-18 19:23:15 -05:00
										 |  |  |         self.assertFalse(grid.sort_multiple) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |     def test_constructor_filtering(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # defaults, not filterable | 
					
						
							|  |  |  |         grid = self.make_grid() | 
					
						
							|  |  |  |         self.assertFalse(grid.filterable) | 
					
						
							|  |  |  |         self.assertEqual(grid.filters, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # defaults, filterable | 
					
						
							|  |  |  |         grid = self.make_grid(filterable=True) | 
					
						
							|  |  |  |         self.assertTrue(grid.filterable) | 
					
						
							|  |  |  |         self.assertEqual(grid.filters, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # filters may be pre-populated | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(mod.Grid, "make_filter", return_value=42): | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |             grid = self.make_grid(model_class=model.Setting, filterable=True) | 
					
						
							|  |  |  |             self.assertEqual(len(grid.filters), 2) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertIn("name", grid.filters) | 
					
						
							|  |  |  |             self.assertIn("value", grid.filters) | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can specify filters | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             model_class=model.Setting, filterable=True, filters={"name": 42} | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |         self.assertTrue(grid.filterable) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.filters, {"name": 42}) | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-07 14:00:53 -05:00
										 |  |  |     def test_vue_tagname(self): | 
					
						
							|  |  |  |         grid = self.make_grid() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.vue_tagname, "wutta-grid") | 
					
						
							| 
									
										
										
										
											2024-08-07 14:00:53 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_vue_component(self): | 
					
						
							|  |  |  |         grid = self.make_grid() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.vue_component, "WuttaGrid") | 
					
						
							| 
									
										
										
										
											2024-08-07 14:00:53 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-11 16:52:13 -05:00
										 |  |  |     def test_get_columns(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # empty | 
					
						
							|  |  |  |         grid = self.make_grid() | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  |         self.assertEqual(grid.columns, []) | 
					
						
							|  |  |  |         self.assertEqual(grid.get_columns(), []) | 
					
						
							| 
									
										
										
										
											2024-08-11 16:52:13 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # explicit | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["foo", "bar"]) | 
					
						
							|  |  |  |         self.assertEqual(grid.columns, ["foo", "bar"]) | 
					
						
							|  |  |  |         self.assertEqual(grid.get_columns(), ["foo", "bar"]) | 
					
						
							| 
									
										
										
										
											2024-08-11 16:52:13 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # derived from model | 
					
						
							|  |  |  |         grid = self.make_grid(model_class=model.Setting) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.columns, ["name", "value"]) | 
					
						
							|  |  |  |         self.assertEqual(grid.get_columns(), ["name", "value"]) | 
					
						
							| 
									
										
										
										
											2024-08-11 16:52:13 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-13 21:43:56 -05:00
										 |  |  |     def test_append(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["one", "two"]) | 
					
						
							|  |  |  |         self.assertEqual(grid.columns, ["one", "two"]) | 
					
						
							|  |  |  |         grid.append("one", "two", "three") | 
					
						
							|  |  |  |         self.assertEqual(grid.columns, ["one", "two", "three"]) | 
					
						
							| 
									
										
										
										
											2024-08-13 21:43:56 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  |     def test_remove(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["one", "two", "three", "four"]) | 
					
						
							|  |  |  |         self.assertEqual(grid.columns, ["one", "two", "three", "four"]) | 
					
						
							|  |  |  |         grid.remove("two", "three") | 
					
						
							|  |  |  |         self.assertEqual(grid.columns, ["one", "four"]) | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-15 20:51:36 -05:00
										 |  |  |     def test_set_label(self): | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |         model = self.app.model | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(mod.Grid, "make_filter"): | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |             # nb. filters are MagicMock instances | 
					
						
							|  |  |  |             grid = self.make_grid(model_class=model.Setting, filterable=True) | 
					
						
							| 
									
										
										
										
											2024-08-15 20:51:36 -05:00
										 |  |  |         self.assertEqual(grid.labels, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # basic | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_label("name", "NAME COL") | 
					
						
							|  |  |  |         self.assertEqual(grid.labels["name"], "NAME COL") | 
					
						
							| 
									
										
										
										
											2024-08-15 20:51:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can replace label | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_label("name", "Different") | 
					
						
							|  |  |  |         self.assertEqual(grid.labels["name"], "Different") | 
					
						
							|  |  |  |         self.assertEqual(grid.get_label("name"), "Different") | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can update only column, not filter | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.labels, {"name": "Different"}) | 
					
						
							|  |  |  |         self.assertIn("name", grid.filters) | 
					
						
							|  |  |  |         self.assertEqual(grid.filters["name"].label, "Different") | 
					
						
							|  |  |  |         grid.set_label("name", "COLUMN ONLY", column_only=True) | 
					
						
							|  |  |  |         self.assertEqual(grid.get_label("name"), "COLUMN ONLY") | 
					
						
							|  |  |  |         self.assertEqual(grid.filters["name"].label, "Different") | 
					
						
							| 
									
										
										
										
											2024-08-15 20:51:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_get_label(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["foo", "bar"]) | 
					
						
							| 
									
										
										
										
											2024-08-15 20:51:36 -05:00
										 |  |  |         self.assertEqual(grid.labels, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # default derived from key | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.get_label("foo"), "Foo") | 
					
						
							| 
									
										
										
										
											2024-08-15 20:51:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can override | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_label("foo", "Different") | 
					
						
							|  |  |  |         self.assertEqual(grid.get_label("foo"), "Different") | 
					
						
							| 
									
										
										
										
											2024-08-15 20:51:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-13 16:29:34 -05:00
										 |  |  |     def test_set_renderer(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["foo", "bar"]) | 
					
						
							| 
									
										
										
										
											2024-08-13 16:29:34 -05:00
										 |  |  |         self.assertEqual(grid.renderers, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def render1(record, key, value): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # basic | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_renderer("foo", render1) | 
					
						
							|  |  |  |         self.assertIs(grid.renderers["foo"], render1) | 
					
						
							| 
									
										
										
										
											2024-08-13 16:29:34 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         def render2(record, key, value, extra=None): | 
					
						
							|  |  |  |             return extra | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # can pass kwargs to get a partial | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_renderer("foo", render2, extra=42) | 
					
						
							|  |  |  |         self.assertIsNot(grid.renderers["foo"], render2) | 
					
						
							|  |  |  |         self.assertEqual(grid.renderers["foo"](None, None, None), 42) | 
					
						
							| 
									
										
										
										
											2024-08-13 16:29:34 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-06 16:56:31 -06:00
										 |  |  |         # can use built-in string shortcut | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_renderer("foo", "quantity") | 
					
						
							| 
									
										
										
										
											2025-01-06 16:56:31 -06:00
										 |  |  |         obj = MagicMock(foo=42.00) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.renderers["foo"](obj, "foo", 42.00), "42") | 
					
						
							| 
									
										
										
										
											2025-01-06 16:56:31 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-13 17:02:39 -06:00
										 |  |  |     def test_set_default_renderers(self): | 
					
						
							| 
									
										
										
										
											2024-12-12 15:15:00 -06:00
										 |  |  |         model = self.app.model | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # no defaults for "plain" schema | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["foo", "bar"]) | 
					
						
							| 
									
										
										
										
											2024-12-12 15:15:00 -06:00
										 |  |  |         self.assertEqual(grid.renderers, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # no defaults for "plain" mapped class | 
					
						
							|  |  |  |         grid = self.make_grid(model_class=model.Setting) | 
					
						
							|  |  |  |         self.assertEqual(grid.renderers, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def myrender(obj, key, value): | 
					
						
							|  |  |  |             return value | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # renderer set for datetime mapped field | 
					
						
							|  |  |  |         grid = self.make_grid(model_class=model.Upgrade) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertIn("created", grid.renderers) | 
					
						
							|  |  |  |         self.assertIsNot(grid.renderers["created"], myrender) | 
					
						
							| 
									
										
										
										
											2024-12-12 15:15:00 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # renderer *not* set for datetime, if override present | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             model_class=model.Upgrade, renderers={"created": myrender} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertIn("created", grid.renderers) | 
					
						
							|  |  |  |         self.assertIs(grid.renderers["created"], myrender) | 
					
						
							| 
									
										
										
										
											2024-12-12 15:15:00 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-02 20:13:04 -06:00
										 |  |  |         # renderer set for boolean mapped field | 
					
						
							|  |  |  |         grid = self.make_grid(model_class=model.Upgrade) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertIn("executing", grid.renderers) | 
					
						
							|  |  |  |         self.assertIsNot(grid.renderers["executing"], myrender) | 
					
						
							| 
									
										
										
										
											2025-01-02 20:13:04 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # renderer *not* set for boolean, if override present | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             model_class=model.Upgrade, renderers={"executing": myrender} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertIn("executing", grid.renderers) | 
					
						
							|  |  |  |         self.assertIs(grid.renderers["executing"], myrender) | 
					
						
							| 
									
										
										
										
											2025-01-02 20:13:04 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-13 17:02:39 -06:00
										 |  |  |         # nb. as of writing we have no Date columns in default schema, | 
					
						
							|  |  |  |         # so must invent one to test that type | 
					
						
							|  |  |  |         class SomeFoolery(model.Base): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             __tablename__ = "somefoolery" | 
					
						
							| 
									
										
										
										
											2025-01-13 17:02:39 -06:00
										 |  |  |             id = sa.Column(sa.Integer(), primary_key=True) | 
					
						
							|  |  |  |             created = sa.Column(sa.Date()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # renderer set for date mapped field | 
					
						
							|  |  |  |         grid = self.make_grid(model_class=SomeFoolery) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertIn("created", grid.renderers) | 
					
						
							|  |  |  |         self.assertIsNot(grid.renderers["created"], myrender) | 
					
						
							| 
									
										
										
										
											2025-01-13 17:02:39 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-21 13:27:52 -06:00
										 |  |  |     def test_set_enum(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class MockEnum(Enum): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             FOO = "foo" | 
					
						
							|  |  |  |             BAR = "bar" | 
					
						
							| 
									
										
										
										
											2025-02-21 13:27:52 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # no enums by default | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["foo", "bar"]) | 
					
						
							| 
									
										
										
										
											2025-02-21 13:27:52 -06:00
										 |  |  |         self.assertEqual(grid.enums, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # enum is set, but not filter choices | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             columns=["foo", "bar"], filterable=False, enums={"foo": MockEnum} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertIs(grid.enums["foo"], MockEnum) | 
					
						
							| 
									
										
										
										
											2025-02-21 13:27:52 -06:00
										 |  |  |         self.assertEqual(grid.filters, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # both enum and filter choices are set | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             model_class=model.Setting, filterable=True, enums={"name": MockEnum} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertIs(grid.enums["name"], MockEnum) | 
					
						
							|  |  |  |         self.assertIn("name", grid.filters) | 
					
						
							|  |  |  |         self.assertIn("value", grid.filters) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             grid.filters["name"].choices, | 
					
						
							|  |  |  |             OrderedDict( | 
					
						
							|  |  |  |                 [ | 
					
						
							|  |  |  |                     ("FOO", "foo"), | 
					
						
							|  |  |  |                     ("BAR", "bar"), | 
					
						
							|  |  |  |                 ] | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2025-02-21 13:27:52 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-10 16:45:12 -05:00
										 |  |  |     def test_linked_columns(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["foo", "bar"]) | 
					
						
							| 
									
										
										
										
											2024-08-10 16:45:12 -05:00
										 |  |  |         self.assertEqual(grid.linked_columns, []) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertFalse(grid.is_linked("foo")) | 
					
						
							| 
									
										
										
										
											2024-08-10 16:45:12 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_link("foo") | 
					
						
							|  |  |  |         self.assertEqual(grid.linked_columns, ["foo"]) | 
					
						
							|  |  |  |         self.assertTrue(grid.is_linked("foo")) | 
					
						
							|  |  |  |         self.assertFalse(grid.is_linked("bar")) | 
					
						
							| 
									
										
										
										
											2024-08-10 16:45:12 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_link("bar") | 
					
						
							|  |  |  |         self.assertEqual(grid.linked_columns, ["foo", "bar"]) | 
					
						
							|  |  |  |         self.assertTrue(grid.is_linked("foo")) | 
					
						
							|  |  |  |         self.assertTrue(grid.is_linked("bar")) | 
					
						
							| 
									
										
										
										
											2024-08-10 16:45:12 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_link("foo", False) | 
					
						
							|  |  |  |         self.assertEqual(grid.linked_columns, ["bar"]) | 
					
						
							|  |  |  |         self.assertFalse(grid.is_linked("foo")) | 
					
						
							|  |  |  |         self.assertTrue(grid.is_linked("bar")) | 
					
						
							| 
									
										
										
										
											2024-08-10 16:45:12 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-18 16:31:25 -06:00
										 |  |  |     def test_hidden_columns(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["foo", "bar"]) | 
					
						
							| 
									
										
										
										
											2025-02-18 16:31:25 -06:00
										 |  |  |         self.assertEqual(grid.hidden_columns, []) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertFalse(grid.is_hidden("foo")) | 
					
						
							| 
									
										
										
										
											2025-02-18 16:31:25 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_hidden("foo") | 
					
						
							|  |  |  |         self.assertEqual(grid.hidden_columns, ["foo"]) | 
					
						
							|  |  |  |         self.assertTrue(grid.is_hidden("foo")) | 
					
						
							|  |  |  |         self.assertFalse(grid.is_hidden("bar")) | 
					
						
							| 
									
										
										
										
											2025-02-18 16:31:25 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_hidden("bar") | 
					
						
							|  |  |  |         self.assertEqual(grid.hidden_columns, ["foo", "bar"]) | 
					
						
							|  |  |  |         self.assertTrue(grid.is_hidden("foo")) | 
					
						
							|  |  |  |         self.assertTrue(grid.is_hidden("bar")) | 
					
						
							| 
									
										
										
										
											2025-02-18 16:31:25 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_hidden("foo", False) | 
					
						
							|  |  |  |         self.assertEqual(grid.hidden_columns, ["bar"]) | 
					
						
							|  |  |  |         self.assertFalse(grid.is_hidden("foo")) | 
					
						
							|  |  |  |         self.assertTrue(grid.is_hidden("bar")) | 
					
						
							| 
									
										
										
										
											2025-02-18 16:31:25 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-21 15:50:36 -05:00
										 |  |  |     def test_searchable_columns(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["foo", "bar"]) | 
					
						
							| 
									
										
										
										
											2024-08-21 15:50:36 -05:00
										 |  |  |         self.assertEqual(grid.searchable_columns, set()) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertFalse(grid.is_searchable("foo")) | 
					
						
							| 
									
										
										
										
											2024-08-21 15:50:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_searchable("foo") | 
					
						
							|  |  |  |         self.assertEqual(grid.searchable_columns, {"foo"}) | 
					
						
							|  |  |  |         self.assertTrue(grid.is_searchable("foo")) | 
					
						
							|  |  |  |         self.assertFalse(grid.is_searchable("bar")) | 
					
						
							| 
									
										
										
										
											2024-08-21 15:50:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_searchable("bar") | 
					
						
							|  |  |  |         self.assertEqual(grid.searchable_columns, {"foo", "bar"}) | 
					
						
							|  |  |  |         self.assertTrue(grid.is_searchable("foo")) | 
					
						
							|  |  |  |         self.assertTrue(grid.is_searchable("bar")) | 
					
						
							| 
									
										
										
										
											2024-08-21 15:50:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_searchable("foo", False) | 
					
						
							|  |  |  |         self.assertEqual(grid.searchable_columns, {"bar"}) | 
					
						
							|  |  |  |         self.assertFalse(grid.is_searchable("foo")) | 
					
						
							|  |  |  |         self.assertTrue(grid.is_searchable("bar")) | 
					
						
							| 
									
										
										
										
											2024-08-21 15:50:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-21 14:38:34 -05:00
										 |  |  |     def test_add_action(self): | 
					
						
							|  |  |  |         grid = self.make_grid() | 
					
						
							|  |  |  |         self.assertEqual(len(grid.actions), 0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.add_action("view") | 
					
						
							| 
									
										
										
										
											2024-08-21 14:38:34 -05:00
										 |  |  |         self.assertEqual(len(grid.actions), 1) | 
					
						
							|  |  |  |         self.assertIsInstance(grid.actions[0], mod.GridAction) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-24 14:26:13 -05:00
										 |  |  |     def test_set_tools(self): | 
					
						
							|  |  |  |         grid = self.make_grid() | 
					
						
							|  |  |  |         self.assertEqual(grid.tools, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # null | 
					
						
							|  |  |  |         grid.set_tools(None) | 
					
						
							|  |  |  |         self.assertEqual(grid.tools, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # empty | 
					
						
							|  |  |  |         grid.set_tools({}) | 
					
						
							|  |  |  |         self.assertEqual(grid.tools, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # full dict is replaced | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.tools = {"foo": "bar"} | 
					
						
							|  |  |  |         self.assertEqual(grid.tools, {"foo": "bar"}) | 
					
						
							|  |  |  |         grid.set_tools({"bar": "baz"}) | 
					
						
							|  |  |  |         self.assertEqual(grid.tools, {"bar": "baz"}) | 
					
						
							| 
									
										
										
										
											2024-08-24 14:26:13 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can specify as list of html elements | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_tools(["foo", "bar"]) | 
					
						
							| 
									
										
										
										
											2024-08-24 14:26:13 -05:00
										 |  |  |         self.assertEqual(len(grid.tools), 2) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(list(grid.tools.values()), ["foo", "bar"]) | 
					
						
							| 
									
										
										
										
											2024-08-24 14:26:13 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_add_tool(self): | 
					
						
							|  |  |  |         grid = self.make_grid() | 
					
						
							|  |  |  |         self.assertEqual(grid.tools, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # with key | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.add_tool("foo", key="foo") | 
					
						
							|  |  |  |         self.assertEqual(grid.tools, {"foo": "foo"}) | 
					
						
							| 
									
										
										
										
											2024-08-24 14:26:13 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # without key | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.add_tool("bar") | 
					
						
							| 
									
										
										
										
											2024-08-24 14:26:13 -05:00
										 |  |  |         self.assertEqual(len(grid.tools), 2) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(list(grid.tools.values()), ["foo", "bar"]) | 
					
						
							| 
									
										
										
										
											2024-08-24 14:26:13 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-16 18:19:24 -05:00
										 |  |  |     def test_get_pagesize_options(self): | 
					
						
							|  |  |  |         grid = self.make_grid() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # default | 
					
						
							|  |  |  |         options = grid.get_pagesize_options() | 
					
						
							|  |  |  |         self.assertEqual(options, [5, 10, 20, 50, 100, 200]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # override default | 
					
						
							|  |  |  |         options = grid.get_pagesize_options(default=[42]) | 
					
						
							|  |  |  |         self.assertEqual(options, [42]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # from config | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.config.setdefault("wuttaweb.grids.default_pagesize_options", "1 2 3") | 
					
						
							| 
									
										
										
										
											2024-08-16 18:19:24 -05:00
										 |  |  |         options = grid.get_pagesize_options() | 
					
						
							|  |  |  |         self.assertEqual(options, [1, 2, 3]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_get_pagesize(self): | 
					
						
							|  |  |  |         grid = self.make_grid() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # default | 
					
						
							|  |  |  |         size = grid.get_pagesize() | 
					
						
							|  |  |  |         self.assertEqual(size, 20) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # override default | 
					
						
							|  |  |  |         size = grid.get_pagesize(default=42) | 
					
						
							|  |  |  |         self.assertEqual(size, 42) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # override default options | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.config.setdefault("wuttaweb.grids.default_pagesize_options", "10 15 30") | 
					
						
							| 
									
										
										
										
											2024-08-16 18:19:24 -05:00
										 |  |  |         grid = self.make_grid() | 
					
						
							|  |  |  |         size = grid.get_pagesize() | 
					
						
							|  |  |  |         self.assertEqual(size, 10) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # from config | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.config.setdefault("wuttaweb.grids.default_pagesize", "15") | 
					
						
							| 
									
										
										
										
											2024-08-16 18:19:24 -05:00
										 |  |  |         size = grid.get_pagesize() | 
					
						
							|  |  |  |         self.assertEqual(size, 15) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  |     ############################## | 
					
						
							|  |  |  |     # configuration methods | 
					
						
							|  |  |  |     ############################## | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_load_settings(self): | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         model = self.app.model | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # nb. first use a paging grid | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             key="foo", paginated=True, paginate_on_backend=True, pagesize=20, page=1 | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # settings are loaded, applied, saved | 
					
						
							|  |  |  |         self.assertEqual(grid.page, 1) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertNotIn("grid.foo.page", self.request.session) | 
					
						
							|  |  |  |         self.request.GET = {"pagesize": "10", "page": "2"} | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  |         grid.load_settings() | 
					
						
							|  |  |  |         self.assertEqual(grid.page, 2) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(self.request.session["grid.foo.page"], 2) | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can skip the saving step | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.request.GET = {"pagesize": "10", "page": "3"} | 
					
						
							| 
									
										
										
										
											2024-08-18 19:23:15 -05:00
										 |  |  |         grid.load_settings(persist=False) | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  |         self.assertEqual(grid.page, 3) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(self.request.session["grid.foo.page"], 2) | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # no error for non-paginated grid | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(key="foo", paginated=False) | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  |         grid.load_settings() | 
					
						
							|  |  |  |         self.assertFalse(grid.paginated) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         # nb. next use a sorting grid | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             key="settings", | 
					
						
							|  |  |  |             model_class=model.Setting, | 
					
						
							|  |  |  |             sortable=True, | 
					
						
							|  |  |  |             sort_on_backend=True, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # settings are loaded, applied, saved | 
					
						
							|  |  |  |         self.assertEqual(grid.sort_defaults, []) | 
					
						
							| 
									
										
										
										
											2025-09-01 11:53:50 -05:00
										 |  |  |         self.assertIsNone(grid.active_sorters) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.request.GET = {"sort1key": "name", "sort1dir": "desc"} | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         grid.load_settings() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.active_sorters, [{"key": "name", "dir": "desc"}]) | 
					
						
							|  |  |  |         self.assertEqual(self.request.session["grid.settings.sorters.length"], 1) | 
					
						
							|  |  |  |         self.assertEqual(self.request.session["grid.settings.sorters.1.key"], "name") | 
					
						
							|  |  |  |         self.assertEqual(self.request.session["grid.settings.sorters.1.dir"], "desc") | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can skip the saving step | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.request.GET = {"sort1key": "name", "sort1dir": "asc"} | 
					
						
							| 
									
										
										
										
											2024-08-18 19:23:15 -05:00
										 |  |  |         grid.load_settings(persist=False) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.active_sorters, [{"key": "name", "dir": "asc"}]) | 
					
						
							|  |  |  |         self.assertEqual(self.request.session["grid.settings.sorters.length"], 1) | 
					
						
							|  |  |  |         self.assertEqual(self.request.session["grid.settings.sorters.1.key"], "name") | 
					
						
							|  |  |  |         self.assertEqual(self.request.session["grid.settings.sorters.1.dir"], "desc") | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # no error for non-sortable grid | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(key="foo", sortable=False) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         grid.load_settings() | 
					
						
							|  |  |  |         self.assertFalse(grid.sortable) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # with sort defaults | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             model_class=model.Setting, | 
					
						
							|  |  |  |             sortable=True, | 
					
						
							|  |  |  |             sort_on_backend=True, | 
					
						
							|  |  |  |             sort_defaults="name", | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2025-09-01 11:53:50 -05:00
										 |  |  |         self.assertIsNone(grid.active_sorters) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         grid.load_settings() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.active_sorters, [{"key": "name", "dir": "asc"}]) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # with multi-column sort defaults | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             model_class=model.Setting, sortable=True, sort_on_backend=True | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         grid.sort_defaults = [ | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             mod.SortInfo("name", "asc"), | 
					
						
							|  |  |  |             mod.SortInfo("value", "desc"), | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         ] | 
					
						
							| 
									
										
										
										
											2025-09-01 11:53:50 -05:00
										 |  |  |         self.assertIsNone(grid.active_sorters) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         grid.load_settings() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.active_sorters, [{"key": "name", "dir": "asc"}]) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # load settings from session when nothing is in request | 
					
						
							|  |  |  |         self.request.GET = {} | 
					
						
							|  |  |  |         self.request.session.invalidate() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertNotIn("grid.settings.sorters.length", self.request.session) | 
					
						
							|  |  |  |         self.request.session["grid.settings.sorters.length"] = 1 | 
					
						
							|  |  |  |         self.request.session["grid.settings.sorters.1.key"] = "name" | 
					
						
							|  |  |  |         self.request.session["grid.settings.sorters.1.dir"] = "desc" | 
					
						
							|  |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             key="settings", | 
					
						
							|  |  |  |             model_class=model.Setting, | 
					
						
							|  |  |  |             sortable=True, | 
					
						
							|  |  |  |             sort_on_backend=True, | 
					
						
							|  |  |  |             paginated=True, | 
					
						
							|  |  |  |             paginate_on_backend=True, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2025-09-01 11:53:50 -05:00
										 |  |  |         self.assertIsNone(grid.active_sorters) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         grid.load_settings() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.active_sorters, [{"key": "name", "dir": "desc"}]) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |         # filter settings are loaded, applied, saved | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             key="settings", model_class=model.Setting, filterable=True | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |         self.assertEqual(len(grid.filters), 2) | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  |         self.assertEqual(len(grid.active_filters), 0) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertNotIn("grid.settings.filter.name.active", self.request.session) | 
					
						
							|  |  |  |         self.assertNotIn("grid.settings.filter.value.active", self.request.session) | 
					
						
							|  |  |  |         self.request.GET = {"name": "john", "name.verb": "contains"} | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |         grid.load_settings() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertTrue(grid.filters["name"].active) | 
					
						
							|  |  |  |         self.assertEqual(grid.filters["name"].verb, "contains") | 
					
						
							|  |  |  |         self.assertEqual(grid.filters["name"].value, "john") | 
					
						
							|  |  |  |         self.assertTrue(self.request.session["grid.settings.filter.name.active"]) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             self.request.session["grid.settings.filter.name.verb"], "contains" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             self.request.session["grid.settings.filter.name.value"], "john" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # filter + sort settings are loaded, applied, saved | 
					
						
							|  |  |  |         self.request.session.invalidate() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             key="settings", model_class=model.Setting, sortable=True, filterable=True | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |         self.assertEqual(len(grid.filters), 2) | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  |         self.assertEqual(len(grid.active_filters), 0) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertNotIn("grid.settings.filter.name.active", self.request.session) | 
					
						
							|  |  |  |         self.assertNotIn("grid.settings.filter.value.active", self.request.session) | 
					
						
							|  |  |  |         self.assertNotIn("grid.settings.sorters.length", self.request.session) | 
					
						
							|  |  |  |         self.request.GET = { | 
					
						
							|  |  |  |             "name": "john", | 
					
						
							|  |  |  |             "name.verb": "contains", | 
					
						
							|  |  |  |             "sort1key": "name", | 
					
						
							|  |  |  |             "sort1dir": "asc", | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |         grid.load_settings() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertTrue(grid.filters["name"].active) | 
					
						
							|  |  |  |         self.assertEqual(grid.filters["name"].verb, "contains") | 
					
						
							|  |  |  |         self.assertEqual(grid.filters["name"].value, "john") | 
					
						
							|  |  |  |         self.assertTrue(self.request.session["grid.settings.filter.name.active"]) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             self.request.session["grid.settings.filter.name.verb"], "contains" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             self.request.session["grid.settings.filter.name.value"], "john" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual(self.request.session["grid.settings.sorters.length"], 1) | 
					
						
							|  |  |  |         self.assertEqual(self.request.session["grid.settings.sorters.1.key"], "name") | 
					
						
							|  |  |  |         self.assertEqual(self.request.session["grid.settings.sorters.1.dir"], "asc") | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  |         # can reset view to defaults | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.request.GET = {"reset-view": "true"} | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  |         grid.load_settings() | 
					
						
							|  |  |  |         self.assertEqual(grid.active_filters, []) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertIsNone(grid.filters["name"].value) | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  |     def test_request_has_settings(self): | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |         model = self.app.model | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(key="settings", model_class=model.Setting) | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         # paging | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertFalse(grid.request_has_settings("page")) | 
					
						
							|  |  |  |         with patch.object(grid, "paginated", new=True): | 
					
						
							|  |  |  |             with patch.object(self.request, "GET", new={"pagesize": "20"}): | 
					
						
							|  |  |  |                 self.assertTrue(grid.request_has_settings("page")) | 
					
						
							|  |  |  |             with patch.object(self.request, "GET", new={"page": "1"}): | 
					
						
							|  |  |  |                 self.assertTrue(grid.request_has_settings("page")) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # sorting | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertFalse(grid.request_has_settings("sort")) | 
					
						
							|  |  |  |         with patch.object(grid, "sortable", new=True): | 
					
						
							|  |  |  |             with patch.object(self.request, "GET", new={"sort1key": "name"}): | 
					
						
							|  |  |  |                 self.assertTrue(grid.request_has_settings("sort")) | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # filtering | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             key="settings", model_class=model.Setting, filterable=True | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertFalse(grid.request_has_settings("filter")) | 
					
						
							|  |  |  |         with patch.object(grid, "filterable", new=True): | 
					
						
							|  |  |  |             with patch.object( | 
					
						
							|  |  |  |                 self.request, "GET", new={"name": "john", "name.verb": "contains"} | 
					
						
							|  |  |  |             ): | 
					
						
							|  |  |  |                 self.assertTrue(grid.request_has_settings("filter")) | 
					
						
							|  |  |  |         with patch.object(self.request, "GET", new={"filter": "1"}): | 
					
						
							|  |  |  |             self.assertTrue(grid.request_has_settings("filter")) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_get_setting(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(key="foo") | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         settings = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # default is null | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         value = grid.get_setting(settings, "pagesize") | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         self.assertIsNone(value) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # can read value from user session | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.request.session["grid.foo.pagesize"] = 15 | 
					
						
							|  |  |  |         value = grid.get_setting(settings, "pagesize", src="session") | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         self.assertEqual(value, 15) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # string value not normalized | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.request.session["grid.foo.pagesize"] = "15" | 
					
						
							|  |  |  |         value = grid.get_setting(settings, "pagesize", src="session") | 
					
						
							|  |  |  |         self.assertEqual(value, "15") | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         self.assertNotEqual(value, 15) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # but can be normalized | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.request.session["grid.foo.pagesize"] = "15" | 
					
						
							|  |  |  |         value = grid.get_setting(settings, "pagesize", src="session", normalize=int) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         self.assertEqual(value, 15) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # can read value from request | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.request.GET = {"pagesize": "25"} | 
					
						
							|  |  |  |         value = grid.get_setting(settings, "pagesize", src="request", normalize=int) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         self.assertEqual(value, 25) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # null when normalization fails | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.request.GET = {"pagesize": "invalid"} | 
					
						
							|  |  |  |         value = grid.get_setting(settings, "pagesize", src="request", normalize=int) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         self.assertIsNone(value) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # reset | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         del self.request.session["grid.foo.pagesize"] | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         self.request.GET = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # value can come from provided settings | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         settings["pagesize"] = "35" | 
					
						
							|  |  |  |         value = grid.get_setting(settings, "pagesize", src="session", normalize=int) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         self.assertEqual(value, 35) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |     def test_update_filter_settings(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # nothing happens if not filterable | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(key="settings", model_class=model.Setting) | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |         settings = {} | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.request.session["grid.settings.filter.name.active"] = True | 
					
						
							|  |  |  |         self.request.session["grid.settings.filter.name.verb"] = "contains" | 
					
						
							|  |  |  |         self.request.session["grid.settings.filter.name.value"] = "john" | 
					
						
							|  |  |  |         grid.update_filter_settings(settings, src="session") | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |         self.assertEqual(settings, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # nb. now use a filterable grid | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             key="settings", model_class=model.Setting, filterable=True | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # settings are updated from session | 
					
						
							|  |  |  |         settings = {} | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.request.session["grid.settings.filter.name.active"] = True | 
					
						
							|  |  |  |         self.request.session["grid.settings.filter.name.verb"] = "contains" | 
					
						
							|  |  |  |         self.request.session["grid.settings.filter.name.value"] = "john" | 
					
						
							|  |  |  |         grid.update_filter_settings(settings, src="session") | 
					
						
							|  |  |  |         self.assertTrue(settings["filter.name.active"]) | 
					
						
							|  |  |  |         self.assertEqual(settings["filter.name.verb"], "contains") | 
					
						
							|  |  |  |         self.assertEqual(settings["filter.name.value"], "john") | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # settings are updated from request | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.request.GET = {"value": "sally", "value.verb": "contains"} | 
					
						
							|  |  |  |         grid.update_filter_settings(settings, src="request") | 
					
						
							|  |  |  |         self.assertFalse(settings["filter.name.active"]) | 
					
						
							|  |  |  |         self.assertTrue(settings["filter.value.active"]) | 
					
						
							|  |  |  |         self.assertEqual(settings["filter.value.verb"], "contains") | 
					
						
							|  |  |  |         self.assertEqual(settings["filter.value.value"], "sally") | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |     def test_update_sort_settings(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # nothing happens if not sortable | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(key="settings", model_class=model.Setting) | 
					
						
							|  |  |  |         settings = {"sorters.length": 0} | 
					
						
							|  |  |  |         self.request.session["grid.settings.sorters.length"] = 1 | 
					
						
							|  |  |  |         self.request.session["grid.settings.sorters.1.key"] = "name" | 
					
						
							|  |  |  |         self.request.session["grid.settings.sorters.1.dir"] = "asc" | 
					
						
							|  |  |  |         grid.update_sort_settings(settings, src="session") | 
					
						
							|  |  |  |         self.assertEqual(settings["sorters.length"], 0) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # nb. now use a sortable grid | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             key="settings", | 
					
						
							|  |  |  |             model_class=model.Setting, | 
					
						
							|  |  |  |             sortable=True, | 
					
						
							|  |  |  |             sort_on_backend=True, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # settings are updated from session | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         settings = { | 
					
						
							|  |  |  |             "sorters.length": 1, | 
					
						
							|  |  |  |             "sorters.1.key": "name", | 
					
						
							|  |  |  |             "sorters.1.dir": "asc", | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         self.request.session["grid.settings.sorters.length"] = 1 | 
					
						
							|  |  |  |         self.request.session["grid.settings.sorters.1.key"] = "name" | 
					
						
							|  |  |  |         self.request.session["grid.settings.sorters.1.dir"] = "asc" | 
					
						
							|  |  |  |         grid.update_sort_settings(settings, src="session") | 
					
						
							|  |  |  |         self.assertEqual(settings["sorters.length"], 1) | 
					
						
							|  |  |  |         self.assertEqual(settings["sorters.1.key"], "name") | 
					
						
							|  |  |  |         self.assertEqual(settings["sorters.1.dir"], "asc") | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # settings are updated from request | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.request.GET = {"sort1key": "value", "sort1dir": "desc"} | 
					
						
							|  |  |  |         grid.update_sort_settings(settings, src="request") | 
					
						
							|  |  |  |         self.assertEqual(settings["sorters.length"], 1) | 
					
						
							|  |  |  |         self.assertEqual(settings["sorters.1.key"], "value") | 
					
						
							|  |  |  |         self.assertEqual(settings["sorters.1.dir"], "desc") | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_update_page_settings(self): | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # nothing happens if not paginated | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(key="foo") | 
					
						
							|  |  |  |         settings = {"pagesize": 20, "page": 1} | 
					
						
							|  |  |  |         self.request.session["grid.foo.pagesize"] = 10 | 
					
						
							|  |  |  |         self.request.session["grid.foo.page"] = 2 | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         grid.update_page_settings(settings) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(settings["pagesize"], 20) | 
					
						
							|  |  |  |         self.assertEqual(settings["page"], 1) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # nb. now use a paginated grid | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(key="foo", paginated=True, paginate_on_backend=True) | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # settings are updated from session | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         settings = {"pagesize": 20, "page": 1} | 
					
						
							|  |  |  |         self.request.session["grid.foo.pagesize"] = 10 | 
					
						
							|  |  |  |         self.request.session["grid.foo.page"] = 2 | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  |         grid.update_page_settings(settings) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(settings["pagesize"], 10) | 
					
						
							|  |  |  |         self.assertEqual(settings["page"], 2) | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # settings are updated from request | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.request.GET = {"pagesize": "15", "page": "4"} | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  |         grid.update_page_settings(settings) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(settings["pagesize"], 15) | 
					
						
							|  |  |  |         self.assertEqual(settings["page"], 4) | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_persist_settings(self): | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         model = self.app.model | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # nb. start out with paginated-only grid | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(key="foo", paginated=True, paginate_on_backend=True) | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         # invalid dest | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertRaises(ValueError, grid.persist_settings, {}, dest="doesnotexist") | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  |         # nb. no error if empty settings, but it saves null values | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.persist_settings({}, dest="session") | 
					
						
							|  |  |  |         self.assertIsNone(self.request.session["grid.foo.page"]) | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # provided values are saved | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.persist_settings({"pagesize": 15, "page": 3}, dest="session") | 
					
						
							|  |  |  |         self.assertEqual(self.request.session["grid.foo.page"], 3) | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         # nb. now switch to sortable-only grid | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             key="settings", | 
					
						
							|  |  |  |             model_class=model.Setting, | 
					
						
							|  |  |  |             sortable=True, | 
					
						
							|  |  |  |             sort_on_backend=True, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # no error if empty settings; does not save values | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.persist_settings({}, dest="session") | 
					
						
							|  |  |  |         self.assertNotIn("grid.settings.sorters.length", self.request.session) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # provided values are saved | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.persist_settings( | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "sorters.length": 2, | 
					
						
							|  |  |  |                 "sorters.1.key": "name", | 
					
						
							|  |  |  |                 "sorters.1.dir": "desc", | 
					
						
							|  |  |  |                 "sorters.2.key": "value", | 
					
						
							|  |  |  |                 "sorters.2.dir": "asc", | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             dest="session", | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual(self.request.session["grid.settings.sorters.length"], 2) | 
					
						
							|  |  |  |         self.assertEqual(self.request.session["grid.settings.sorters.1.key"], "name") | 
					
						
							|  |  |  |         self.assertEqual(self.request.session["grid.settings.sorters.1.dir"], "desc") | 
					
						
							|  |  |  |         self.assertEqual(self.request.session["grid.settings.sorters.2.key"], "value") | 
					
						
							|  |  |  |         self.assertEqual(self.request.session["grid.settings.sorters.2.dir"], "asc") | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # old values removed when new are saved | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.persist_settings( | 
					
						
							|  |  |  |             {"sorters.length": 1, "sorters.1.key": "name", "sorters.1.dir": "desc"}, | 
					
						
							|  |  |  |             dest="session", | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual(self.request.session["grid.settings.sorters.length"], 1) | 
					
						
							|  |  |  |         self.assertEqual(self.request.session["grid.settings.sorters.1.key"], "name") | 
					
						
							|  |  |  |         self.assertEqual(self.request.session["grid.settings.sorters.1.dir"], "desc") | 
					
						
							|  |  |  |         self.assertNotIn("grid.settings.sorters.2.key", self.request.session) | 
					
						
							|  |  |  |         self.assertNotIn("grid.settings.sorters.2.dir", self.request.session) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |         # nb. now switch to filterable-only grid | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             key="settings", model_class=model.Setting, filterable=True | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertIn("name", grid.filters) | 
					
						
							|  |  |  |         self.assertEqual(grid.filters["name"].key, "name") | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # no error if empty settings; does not save values | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.persist_settings({}, dest="session") | 
					
						
							|  |  |  |         self.assertNotIn("grid.settings.filters.name", self.request.session) | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # provided values are saved | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.persist_settings( | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "filter.name.active": True, | 
					
						
							|  |  |  |                 "filter.name.verb": "contains", | 
					
						
							|  |  |  |                 "filter.name.value": "john", | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             dest="session", | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertTrue(self.request.session["grid.settings.filter.name.active"]) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             self.request.session["grid.settings.filter.name.verb"], "contains" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             self.request.session["grid.settings.filter.name.value"], "john" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |     ############################## | 
					
						
							|  |  |  |     # sorting methods | 
					
						
							|  |  |  |     ############################## | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_make_backend_sorters(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # default is empty | 
					
						
							|  |  |  |         grid = self.make_grid() | 
					
						
							|  |  |  |         sorters = grid.make_backend_sorters() | 
					
						
							|  |  |  |         self.assertEqual(sorters, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # makes sorters if model class | 
					
						
							|  |  |  |         grid = self.make_grid(model_class=model.Setting) | 
					
						
							|  |  |  |         sorters = grid.make_backend_sorters() | 
					
						
							|  |  |  |         self.assertEqual(len(sorters), 2) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertIn("name", sorters) | 
					
						
							|  |  |  |         self.assertIn("value", sorters) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # does not replace supplied sorters | 
					
						
							|  |  |  |         grid = self.make_grid(model_class=model.Setting) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         mysorters = {"value": 42} | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         sorters = grid.make_backend_sorters(mysorters) | 
					
						
							|  |  |  |         self.assertEqual(len(sorters), 2) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertIn("name", sorters) | 
					
						
							|  |  |  |         self.assertIn("value", sorters) | 
					
						
							|  |  |  |         self.assertEqual(sorters["value"], 42) | 
					
						
							|  |  |  |         self.assertEqual(mysorters["value"], 42) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_make_sorter(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  |         sample_data = [ | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             {"name": "foo1", "value": "ONE"}, | 
					
						
							|  |  |  |             {"name": "foo2", "value": "two"}, | 
					
						
							|  |  |  |             {"name": "foo3", "value": "three"}, | 
					
						
							|  |  |  |             {"name": "foo4", "value": "four"}, | 
					
						
							|  |  |  |             {"name": "foo5", "value": "five"}, | 
					
						
							|  |  |  |             {"name": "foo6", "value": "six"}, | 
					
						
							|  |  |  |             {"name": "foo7", "value": "seven"}, | 
					
						
							|  |  |  |             {"name": "foo8", "value": "eight"}, | 
					
						
							|  |  |  |             {"name": "foo9", "value": "nine"}, | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         ] | 
					
						
							|  |  |  |         for setting in sample_data: | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.app.save_setting(self.session, setting["name"], setting["value"]) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         self.session.commit() | 
					
						
							|  |  |  |         sample_query = self.session.query(model.Setting) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # plain data | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["name", "value"]) | 
					
						
							|  |  |  |         sorter = grid.make_sorter("name") | 
					
						
							|  |  |  |         sorted_data = sorter(sample_data, "desc") | 
					
						
							|  |  |  |         self.assertEqual(sorted_data[0], {"name": "foo9", "value": "nine"}) | 
					
						
							|  |  |  |         sorted_data = sorter(sample_data, "asc") | 
					
						
							|  |  |  |         self.assertEqual(sorted_data[0], {"name": "foo1", "value": "ONE"}) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # model class, but still plain data | 
					
						
							|  |  |  |         grid = self.make_grid(model_class=model.Setting) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         sorter = grid.make_sorter("name") | 
					
						
							|  |  |  |         sorted_data = sorter(sample_data, "desc") | 
					
						
							|  |  |  |         self.assertEqual(sorted_data[0], {"name": "foo9", "value": "nine"}) | 
					
						
							|  |  |  |         sorted_data = sorter(sample_data, "asc") | 
					
						
							|  |  |  |         self.assertEqual(sorted_data[0], {"name": "foo1", "value": "ONE"}) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # repeat previous test, w/ model property | 
					
						
							|  |  |  |         grid = self.make_grid(model_class=model.Setting) | 
					
						
							|  |  |  |         sorter = grid.make_sorter(model.Setting.name) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         sorted_data = sorter(sample_data, "desc") | 
					
						
							|  |  |  |         self.assertEqual(sorted_data[0], {"name": "foo9", "value": "nine"}) | 
					
						
							|  |  |  |         sorted_data = sorter(sample_data, "asc") | 
					
						
							|  |  |  |         self.assertEqual(sorted_data[0], {"name": "foo1", "value": "ONE"}) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # sqlalchemy query | 
					
						
							|  |  |  |         grid = self.make_grid(model_class=model.Setting) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         sorter = grid.make_sorter("name") | 
					
						
							|  |  |  |         sorted_query = sorter(sample_query, "desc") | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         sorted_data = sorted_query.all() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(dict(sorted_data[0]), {"name": "foo9", "value": "nine"}) | 
					
						
							|  |  |  |         sorted_query = sorter(sample_query, "asc") | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         sorted_data = sorted_query.all() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(dict(sorted_data[0]), {"name": "foo1", "value": "ONE"}) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # repeat previous test, w/ model property | 
					
						
							|  |  |  |         grid = self.make_grid(model_class=model.Setting) | 
					
						
							|  |  |  |         sorter = grid.make_sorter(model.Setting.name) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         sorted_query = sorter(sample_query, "desc") | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         sorted_data = sorted_query.all() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(dict(sorted_data[0]), {"name": "foo9", "value": "nine"}) | 
					
						
							|  |  |  |         sorted_query = sorter(sample_query, "asc") | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         sorted_data = sorted_query.all() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(dict(sorted_data[0]), {"name": "foo1", "value": "ONE"}) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # sortfunc for "invalid" column will fail when called; however | 
					
						
							|  |  |  |         # it can work for manual sort w/ custom keyfunc | 
					
						
							|  |  |  |         grid = self.make_grid(model_class=model.Setting) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         sorter = grid.make_sorter("doesnotexist") | 
					
						
							|  |  |  |         self.assertRaises(TypeError, sorter, sample_query, "desc") | 
					
						
							|  |  |  |         self.assertRaises(KeyError, sorter, sample_data, "desc") | 
					
						
							|  |  |  |         sorter = grid.make_sorter("doesnotexist", keyfunc=lambda obj: obj["name"]) | 
					
						
							|  |  |  |         sorted_data = sorter(sample_data, "desc") | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         self.assertEqual(len(sorted_data), 9) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         sorted_data = sorter(sample_data, "asc") | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         self.assertEqual(len(sorted_data), 9) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-18 19:23:15 -05:00
										 |  |  |         # case folding is on by default | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         grid = self.make_grid(model_class=model.Setting) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         sorter = grid.make_sorter("value") | 
					
						
							|  |  |  |         sorted_data = sorter(sample_data, "desc") | 
					
						
							|  |  |  |         self.assertEqual(dict(sorted_data[0]), {"name": "foo2", "value": "two"}) | 
					
						
							|  |  |  |         sorted_data = sorter(sample_data, "asc") | 
					
						
							|  |  |  |         self.assertEqual(dict(sorted_data[0]), {"name": "foo8", "value": "eight"}) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-18 19:23:15 -05:00
										 |  |  |         # results are different with case folding off | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         grid = self.make_grid(model_class=model.Setting) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         sorter = grid.make_sorter("value", foldcase=False) | 
					
						
							|  |  |  |         sorted_data = sorter(sample_data, "desc") | 
					
						
							|  |  |  |         self.assertEqual(dict(sorted_data[0]), {"name": "foo2", "value": "two"}) | 
					
						
							|  |  |  |         sorted_data = sorter(sample_data, "asc") | 
					
						
							|  |  |  |         self.assertEqual(dict(sorted_data[0]), {"name": "foo1", "value": "ONE"}) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |     def test_set_joiner(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # basic | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             columns=["foo", "bar"], sortable=True, sort_on_backend=True | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |         self.assertEqual(grid.joiners, {}) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_joiner("foo", 42) | 
					
						
							|  |  |  |         self.assertEqual(grid.joiners, {"foo": 42}) | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_remove_joiner(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # basic | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             columns=["foo", "bar"], | 
					
						
							|  |  |  |             sortable=True, | 
					
						
							|  |  |  |             sort_on_backend=True, | 
					
						
							|  |  |  |             joiners={"foo": 42}, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual(grid.joiners, {"foo": 42}) | 
					
						
							|  |  |  |         grid.remove_joiner("foo") | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |         self.assertEqual(grid.joiners, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |     def test_set_sorter(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # explicit sortfunc | 
					
						
							|  |  |  |         grid = self.make_grid() | 
					
						
							|  |  |  |         self.assertEqual(grid.sorters, {}) | 
					
						
							|  |  |  |         sortfunc = lambda data, direction: data | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_sorter("foo", sortfunc) | 
					
						
							|  |  |  |         self.assertIs(grid.sorters["foo"], sortfunc) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # auto from model property | 
					
						
							|  |  |  |         grid = self.make_grid(model_class=model.Setting, sortable=True, sorters={}) | 
					
						
							|  |  |  |         self.assertEqual(grid.sorters, {}) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_sorter("name", model.Setting.name) | 
					
						
							|  |  |  |         self.assertTrue(callable(grid.sorters["name"])) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # auto from column name | 
					
						
							|  |  |  |         grid = self.make_grid(model_class=model.Setting, sortable=True, sorters={}) | 
					
						
							|  |  |  |         self.assertEqual(grid.sorters, {}) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_sorter("name", "name") | 
					
						
							|  |  |  |         self.assertTrue(callable(grid.sorters["name"])) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # auto from key | 
					
						
							|  |  |  |         grid = self.make_grid(model_class=model.Setting, sortable=True, sorters={}) | 
					
						
							|  |  |  |         self.assertEqual(grid.sorters, {}) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_sorter("name") | 
					
						
							|  |  |  |         self.assertTrue(callable(grid.sorters["name"])) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_remove_sorter(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # basics | 
					
						
							|  |  |  |         grid = self.make_grid(model_class=model.Setting, sortable=True) | 
					
						
							|  |  |  |         self.assertEqual(len(grid.sorters), 2) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertIn("name", grid.sorters) | 
					
						
							|  |  |  |         self.assertIn("value", grid.sorters) | 
					
						
							|  |  |  |         grid.remove_sorter("value") | 
					
						
							|  |  |  |         self.assertNotIn("value", grid.sorters) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_set_sort_defaults(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  |         grid = self.make_grid(model_class=model.Setting, sortable=True) | 
					
						
							|  |  |  |         self.assertEqual(grid.sort_defaults, []) | 
					
						
							| 
									
										
										
										
											2024-08-18 19:23:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can set just sortkey | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_sort_defaults("name") | 
					
						
							|  |  |  |         self.assertEqual(grid.sort_defaults, [mod.SortInfo("name", "asc")]) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-18 19:23:15 -05:00
										 |  |  |         # can set sortkey, sortdir | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_sort_defaults("name", "desc") | 
					
						
							|  |  |  |         self.assertEqual(grid.sort_defaults, [mod.SortInfo("name", "desc")]) | 
					
						
							| 
									
										
										
										
											2024-08-18 19:23:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can set sortkey, sortdir as tuple | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_sort_defaults(("value", "asc")) | 
					
						
							|  |  |  |         self.assertEqual(grid.sort_defaults, [mod.SortInfo("value", "asc")]) | 
					
						
							| 
									
										
										
										
											2024-08-18 19:23:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can set as list | 
					
						
							|  |  |  |         grid.sort_multiple = True | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_sort_defaults([("value", "asc"), ("name", "desc")]) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             grid.sort_defaults, | 
					
						
							|  |  |  |             [mod.SortInfo("value", "asc"), mod.SortInfo("name", "desc")], | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-18 19:23:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # list is pruned if multi-sort disabled | 
					
						
							|  |  |  |         grid.sort_multiple = False | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_sort_defaults([("value", "asc"), ("name", "desc")]) | 
					
						
							|  |  |  |         self.assertEqual(grid.sort_defaults, [mod.SortInfo("value", "asc")]) | 
					
						
							| 
									
										
										
										
											2024-08-18 19:23:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # error if any other single arg | 
					
						
							|  |  |  |         self.assertRaises(ValueError, grid.set_sort_defaults, 42) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # error if more than 2 args | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertRaises( | 
					
						
							|  |  |  |             ValueError, grid.set_sort_defaults, "name", "asc", "value", "desc" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-18 19:23:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |     def test_is_sortable(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # basics, frontend sorting | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             model_class=model.Setting, sortable=True, sort_on_backend=False | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertTrue(grid.is_sortable("name")) | 
					
						
							|  |  |  |         self.assertTrue(grid.is_sortable("value")) | 
					
						
							|  |  |  |         grid.remove_sorter("value") | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         # nb. columns are always sortable for frontend, despite remove_sorter() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertTrue(grid.is_sortable("value")) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         # nb. when grid is not sortable, no column is either | 
					
						
							|  |  |  |         grid.sortable = False | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertFalse(grid.is_sortable("name")) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # same test but with backend sorting | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             model_class=model.Setting, sortable=True, sort_on_backend=True | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertTrue(grid.is_sortable("name")) | 
					
						
							|  |  |  |         self.assertTrue(grid.is_sortable("value")) | 
					
						
							|  |  |  |         grid.remove_sorter("value") | 
					
						
							|  |  |  |         self.assertFalse(grid.is_sortable("value")) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         # nb. when grid is not sortable, no column is either | 
					
						
							|  |  |  |         grid.sortable = False | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertFalse(grid.is_sortable("name")) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |     def test_make_backend_filters(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # default is empty | 
					
						
							|  |  |  |         grid = self.make_grid() | 
					
						
							|  |  |  |         filters = grid.make_backend_filters() | 
					
						
							|  |  |  |         self.assertEqual(filters, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # makes filters if model class | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(mod.Grid, "make_filter"): | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |             # nb. filters are MagicMock instances | 
					
						
							|  |  |  |             grid = self.make_grid(model_class=model.Setting) | 
					
						
							|  |  |  |             filters = grid.make_backend_filters() | 
					
						
							|  |  |  |         self.assertEqual(len(filters), 2) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertIn("name", filters) | 
					
						
							|  |  |  |         self.assertIn("value", filters) | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # does not replace supplied filters | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         myfilters = {"value": 42} | 
					
						
							|  |  |  |         with patch.object(mod.Grid, "make_filter"): | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |             # nb. filters are MagicMock instances | 
					
						
							|  |  |  |             grid = self.make_grid(model_class=model.Setting) | 
					
						
							|  |  |  |             filters = grid.make_backend_filters(myfilters) | 
					
						
							|  |  |  |         self.assertEqual(len(filters), 2) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertIn("name", filters) | 
					
						
							|  |  |  |         self.assertIn("value", filters) | 
					
						
							|  |  |  |         self.assertEqual(filters["value"], 42) | 
					
						
							|  |  |  |         self.assertEqual(myfilters["value"], 42) | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-28 21:08:10 -06:00
										 |  |  |         # filters for all *true* columns by default, despite grid.columns | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(mod.Grid, "make_filter"): | 
					
						
							| 
									
										
										
										
											2024-12-28 21:08:10 -06:00
										 |  |  |             # nb. filters are MagicMock instances | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             grid = self.make_grid( | 
					
						
							|  |  |  |                 model_class=model.User, columns=["username", "person"] | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2024-12-28 21:08:10 -06:00
										 |  |  |             filters = grid.make_backend_filters() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertIn("username", filters) | 
					
						
							|  |  |  |             self.assertIn("active", filters) | 
					
						
							| 
									
										
										
										
											2024-12-28 21:08:10 -06:00
										 |  |  |             # nb. relationship not included by default | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertNotIn("person", filters) | 
					
						
							| 
									
										
										
										
											2025-01-27 15:55:07 -06:00
										 |  |  |             # nb. uuid fields not included by default | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertNotIn("uuid", filters) | 
					
						
							|  |  |  |             self.assertNotIn("person_uuid", filters) | 
					
						
							| 
									
										
										
										
											2024-12-28 21:08:10 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |     def test_make_filter(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-23 12:10:51 -05:00
										 |  |  |         # arg is column name | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |         grid = self.make_grid(model_class=model.Setting) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         filtr = grid.make_filter("name") | 
					
						
							| 
									
										
										
										
											2024-08-23 12:10:51 -05:00
										 |  |  |         self.assertIsInstance(filtr, StringAlchemyFilter) | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-23 12:10:51 -05:00
										 |  |  |         # arg is column name, but model class is invalid | 
					
						
							|  |  |  |         grid = self.make_grid(model_class=42) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertRaises(ValueError, grid.make_filter, "name") | 
					
						
							| 
									
										
										
										
											2024-08-23 12:10:51 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # arg is model property | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |         grid = self.make_grid(model_class=model.Setting) | 
					
						
							|  |  |  |         filtr = grid.make_filter(model.Setting.name) | 
					
						
							| 
									
										
										
										
											2024-08-23 12:10:51 -05:00
										 |  |  |         self.assertIsInstance(filtr, StringAlchemyFilter) | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-23 12:10:51 -05:00
										 |  |  |         # model property as kwarg | 
					
						
							|  |  |  |         grid = self.make_grid(model_class=model.Setting) | 
					
						
							|  |  |  |         filtr = grid.make_filter(None, model_property=model.Setting.name) | 
					
						
							|  |  |  |         self.assertIsInstance(filtr, StringAlchemyFilter) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # default factory | 
					
						
							|  |  |  |         grid = self.make_grid(model_class=model.Setting) | 
					
						
							|  |  |  |         with patch.dict(default_sqlalchemy_filters, {None: GridFilter}, clear=True): | 
					
						
							|  |  |  |             filtr = grid.make_filter(model.Setting.name) | 
					
						
							|  |  |  |         self.assertIsInstance(filtr, GridFilter) | 
					
						
							|  |  |  |         self.assertNotIsInstance(filtr, StringAlchemyFilter) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # factory override | 
					
						
							|  |  |  |         grid = self.make_grid(model_class=model.Setting) | 
					
						
							|  |  |  |         filtr = grid.make_filter(model.Setting.name, factory=GridFilter) | 
					
						
							|  |  |  |         self.assertIsInstance(filtr, GridFilter) | 
					
						
							|  |  |  |         self.assertNotIsInstance(filtr, StringAlchemyFilter) | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |     def test_set_filter(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(mod.Grid, "make_filter", return_value=42): | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # auto from model property | 
					
						
							|  |  |  |             grid = self.make_grid(model_class=model.Setting) | 
					
						
							|  |  |  |             self.assertEqual(grid.filters, {}) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             grid.set_filter("name", model.Setting.name) | 
					
						
							|  |  |  |             self.assertIn("name", grid.filters) | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # auto from column name | 
					
						
							|  |  |  |             grid = self.make_grid(model_class=model.Setting) | 
					
						
							|  |  |  |             self.assertEqual(grid.filters, {}) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             grid.set_filter("name", "name") | 
					
						
							|  |  |  |             self.assertIn("name", grid.filters) | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # auto from key | 
					
						
							|  |  |  |             grid = self.make_grid(model_class=model.Setting) | 
					
						
							|  |  |  |             self.assertEqual(grid.filters, {}) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             grid.set_filter("name") | 
					
						
							|  |  |  |             self.assertIn("name", grid.filters) | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # explicit is not yet implemented | 
					
						
							|  |  |  |             grid = self.make_grid(model_class=model.Setting) | 
					
						
							|  |  |  |             self.assertEqual(grid.filters, {}) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertRaises(NotImplementedError, grid.set_filter, "name", lambda q: q) | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_remove_filter(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # basics | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(mod.Grid, "make_filter"): | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |             # nb. filters are MagicMock instances | 
					
						
							|  |  |  |             grid = self.make_grid(model_class=model.Setting, filterable=True) | 
					
						
							|  |  |  |         self.assertEqual(len(grid.filters), 2) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertIn("name", grid.filters) | 
					
						
							|  |  |  |         self.assertIn("value", grid.filters) | 
					
						
							|  |  |  |         grid.remove_filter("value") | 
					
						
							|  |  |  |         self.assertNotIn("value", grid.filters) | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  |     def test_set_filter_defaults(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # empty by default | 
					
						
							|  |  |  |         grid = self.make_grid(model_class=model.Setting, filterable=True) | 
					
						
							|  |  |  |         self.assertEqual(grid.filter_defaults, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # can specify via method call | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_filter_defaults(name={"active": True}) | 
					
						
							|  |  |  |         self.assertEqual(grid.filter_defaults, {"name": {"active": True}}) | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can specify via constructor | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             model_class=model.Setting, | 
					
						
							|  |  |  |             filterable=True, | 
					
						
							|  |  |  |             filter_defaults={"name": {"active": True}}, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual(grid.filter_defaults, {"name": {"active": True}}) | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  |     ############################## | 
					
						
							|  |  |  |     # data methods | 
					
						
							|  |  |  |     ############################## | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_get_visible_data(self): | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         model = self.app.model | 
					
						
							|  |  |  |         sample_data = [ | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             {"name": "foo1", "value": "ONE"}, | 
					
						
							|  |  |  |             {"name": "foo2", "value": "two"}, | 
					
						
							|  |  |  |             {"name": "foo3", "value": "three"}, | 
					
						
							|  |  |  |             {"name": "foo4", "value": "four"}, | 
					
						
							|  |  |  |             {"name": "foo5", "value": "five"}, | 
					
						
							|  |  |  |             {"name": "foo6", "value": "six"}, | 
					
						
							|  |  |  |             {"name": "foo7", "value": "seven"}, | 
					
						
							|  |  |  |             {"name": "foo8", "value": "eight"}, | 
					
						
							|  |  |  |             {"name": "foo9", "value": "nine"}, | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  |         ] | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         for setting in sample_data: | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.app.save_setting(self.session, setting["name"], setting["value"]) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         self.session.commit() | 
					
						
							|  |  |  |         sample_query = self.session.query(model.Setting) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # data is sorted and paginated | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             model_class=model.Setting, | 
					
						
							|  |  |  |             data=sample_query, | 
					
						
							|  |  |  |             filterable=True, | 
					
						
							|  |  |  |             sortable=True, | 
					
						
							|  |  |  |             sort_on_backend=True, | 
					
						
							|  |  |  |             sort_defaults=("name", "desc"), | 
					
						
							|  |  |  |             paginated=True, | 
					
						
							|  |  |  |             paginate_on_backend=True, | 
					
						
							|  |  |  |             pagesize=4, | 
					
						
							|  |  |  |             page=2, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         grid.load_settings() | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |         # nb. for now the filtering is mocked | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(grid, "filter_data") as filter_data: | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |             filter_data.side_effect = lambda q: q | 
					
						
							|  |  |  |             visible = grid.get_visible_data() | 
					
						
							|  |  |  |             filter_data.assert_called_once_with(sample_query) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual([s.name for s in visible], ["foo5", "foo4", "foo3", "foo2"]) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |     def test_filter_data(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  |         sample_data = [ | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             {"name": "foo1", "value": "ONE"}, | 
					
						
							|  |  |  |             {"name": "foo2", "value": "two"}, | 
					
						
							|  |  |  |             {"name": "foo3", "value": "ggg"}, | 
					
						
							|  |  |  |             {"name": "foo4", "value": "ggg"}, | 
					
						
							|  |  |  |             {"name": "foo5", "value": "ggg"}, | 
					
						
							|  |  |  |             {"name": "foo6", "value": "six"}, | 
					
						
							|  |  |  |             {"name": "foo7", "value": "seven"}, | 
					
						
							|  |  |  |             {"name": "foo8", "value": "eight"}, | 
					
						
							|  |  |  |             {"name": "foo9", "value": "nine"}, | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  |         ] | 
					
						
							|  |  |  |         for setting in sample_data: | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.app.save_setting(self.session, setting["name"], setting["value"]) | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  |         self.session.commit() | 
					
						
							|  |  |  |         sample_query = self.session.query(model.Setting) | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             key="settings", model_class=model.Setting, filterable=True | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual(list(grid.filters), ["name", "value"]) | 
					
						
							|  |  |  |         self.assertIsInstance(grid.filters["name"], StringAlchemyFilter) | 
					
						
							|  |  |  |         self.assertIsInstance(grid.filters["value"], StringAlchemyFilter) | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # not filtered by default | 
					
						
							|  |  |  |         grid.load_settings() | 
					
						
							|  |  |  |         self.assertEqual(grid.active_filters, []) | 
					
						
							|  |  |  |         filtered_query = grid.filter_data(sample_query) | 
					
						
							|  |  |  |         self.assertIs(filtered_query, sample_query) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # can be filtered per session settings | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.request.session["grid.settings.filter.value.active"] = True | 
					
						
							|  |  |  |         self.request.session["grid.settings.filter.value.verb"] = "contains" | 
					
						
							|  |  |  |         self.request.session["grid.settings.filter.value.value"] = "ggg" | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  |         grid.load_settings() | 
					
						
							|  |  |  |         self.assertEqual(len(grid.active_filters), 1) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.active_filters[0].key, "value") | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  |         filtered_query = grid.filter_data(sample_query) | 
					
						
							|  |  |  |         self.assertIsInstance(filtered_query, orm.Query) | 
					
						
							|  |  |  |         self.assertIsNot(filtered_query, sample_query) | 
					
						
							|  |  |  |         self.assertEqual(filtered_query.count(), 3) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # can be filtered per request settings | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.request.GET = {"value": "s", "value.verb": "contains"} | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |         grid.load_settings() | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  |         self.assertEqual(len(grid.active_filters), 1) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.active_filters[0].key, "value") | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  |         filtered_query = grid.filter_data(sample_query) | 
					
						
							|  |  |  |         self.assertIsInstance(filtered_query, orm.Query) | 
					
						
							|  |  |  |         self.assertEqual(filtered_query.count(), 2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # not filtered if verb is invalid | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.request.GET = {"value": "ggg", "value.verb": "doesnotexist"} | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  |         grid.load_settings() | 
					
						
							|  |  |  |         self.assertEqual(len(grid.active_filters), 1) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.active_filters[0].verb, "doesnotexist") | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  |         filtered_query = grid.filter_data(sample_query) | 
					
						
							|  |  |  |         self.assertIs(filtered_query, sample_query) | 
					
						
							|  |  |  |         self.assertEqual(filtered_query.count(), 9) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # not filtered if error | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.request.GET = {"value": "ggg", "value.verb": "contains"} | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  |         grid.load_settings() | 
					
						
							|  |  |  |         self.assertEqual(len(grid.active_filters), 1) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.active_filters[0].verb, "contains") | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  |         filtered_query = grid.filter_data(sample_query) | 
					
						
							|  |  |  |         self.assertIsNot(filtered_query, sample_query) | 
					
						
							|  |  |  |         self.assertEqual(filtered_query.count(), 3) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object( | 
					
						
							|  |  |  |             grid.active_filters[0], "filter_contains", side_effect=RuntimeError | 
					
						
							|  |  |  |         ): | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  |             filtered_query = grid.filter_data(sample_query) | 
					
						
							|  |  |  |         self.assertIs(filtered_query, sample_query) | 
					
						
							|  |  |  |         self.assertEqual(filtered_query.count(), 9) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # joiner is invoked | 
					
						
							|  |  |  |         self.assertEqual(len(grid.active_filters), 1) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.active_filters[0].key, "value") | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  |         joiner = MagicMock(side_effect=lambda q: q) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.joiners = {"value": joiner} | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  |         grid.joined = set() | 
					
						
							|  |  |  |         filtered_query = grid.filter_data(sample_query) | 
					
						
							|  |  |  |         joiner.assert_called_once_with(sample_query) | 
					
						
							|  |  |  |         self.assertEqual(filtered_query.count(), 3) | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |     def test_sort_data(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  |         sample_data = [ | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             {"name": "foo1", "value": "ONE"}, | 
					
						
							|  |  |  |             {"name": "foo2", "value": "two"}, | 
					
						
							|  |  |  |             {"name": "foo3", "value": "ggg"}, | 
					
						
							|  |  |  |             {"name": "foo4", "value": "ggg"}, | 
					
						
							|  |  |  |             {"name": "foo5", "value": "ggg"}, | 
					
						
							|  |  |  |             {"name": "foo6", "value": "six"}, | 
					
						
							|  |  |  |             {"name": "foo7", "value": "seven"}, | 
					
						
							|  |  |  |             {"name": "foo8", "value": "eight"}, | 
					
						
							|  |  |  |             {"name": "foo9", "value": "nine"}, | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         ] | 
					
						
							|  |  |  |         for setting in sample_data: | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.app.save_setting(self.session, setting["name"], setting["value"]) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         self.session.commit() | 
					
						
							|  |  |  |         sample_query = self.session.query(model.Setting) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             model_class=model.Setting, | 
					
						
							|  |  |  |             sortable=True, | 
					
						
							|  |  |  |             sort_on_backend=True, | 
					
						
							|  |  |  |             sort_defaults=("name", "desc"), | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         grid.load_settings() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # can sort a simple list of data | 
					
						
							|  |  |  |         sorted_data = grid.sort_data(sample_data) | 
					
						
							|  |  |  |         self.assertIsInstance(sorted_data, list) | 
					
						
							|  |  |  |         self.assertEqual(len(sorted_data), 9) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(sorted_data[0]["name"], "foo9") | 
					
						
							|  |  |  |         self.assertEqual(sorted_data[-1]["name"], "foo1") | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can also sort a data query | 
					
						
							|  |  |  |         sorted_query = grid.sort_data(sample_query) | 
					
						
							|  |  |  |         self.assertIsInstance(sorted_query, orm.Query) | 
					
						
							|  |  |  |         sorted_data = sorted_query.all() | 
					
						
							|  |  |  |         self.assertEqual(len(sorted_data), 9) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(sorted_data[0]["name"], "foo9") | 
					
						
							|  |  |  |         self.assertEqual(sorted_data[-1]["name"], "foo1") | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # cannot sort data if sorter missing in overrides | 
					
						
							|  |  |  |         sorted_data = grid.sort_data(sample_data, sorters=[]) | 
					
						
							|  |  |  |         # nb. sorted data is in same order as original sample (not sorted) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(sorted_data[0]["name"], "foo1") | 
					
						
							|  |  |  |         self.assertEqual(sorted_data[-1]["name"], "foo9") | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-18 19:23:15 -05:00
										 |  |  |         # multi-column sorting for list data | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         sorted_data = grid.sort_data( | 
					
						
							|  |  |  |             sample_data, | 
					
						
							|  |  |  |             sorters=[{"key": "value", "dir": "asc"}, {"key": "name", "dir": "asc"}], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual(dict(sorted_data[0]), {"name": "foo8", "value": "eight"}) | 
					
						
							|  |  |  |         self.assertEqual(dict(sorted_data[1]), {"name": "foo3", "value": "ggg"}) | 
					
						
							|  |  |  |         self.assertEqual(dict(sorted_data[3]), {"name": "foo5", "value": "ggg"}) | 
					
						
							|  |  |  |         self.assertEqual(dict(sorted_data[-1]), {"name": "foo2", "value": "two"}) | 
					
						
							| 
									
										
										
										
											2024-08-18 19:23:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # multi-column sorting for query | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         sorted_query = grid.sort_data( | 
					
						
							|  |  |  |             sample_query, | 
					
						
							|  |  |  |             sorters=[{"key": "value", "dir": "asc"}, {"key": "name", "dir": "asc"}], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual(dict(sorted_data[0]), {"name": "foo8", "value": "eight"}) | 
					
						
							|  |  |  |         self.assertEqual(dict(sorted_data[1]), {"name": "foo3", "value": "ggg"}) | 
					
						
							|  |  |  |         self.assertEqual(dict(sorted_data[3]), {"name": "foo5", "value": "ggg"}) | 
					
						
							|  |  |  |         self.assertEqual(dict(sorted_data[-1]), {"name": "foo2", "value": "two"}) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # cannot sort data if sortfunc is missing for column | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.remove_sorter("name") | 
					
						
							|  |  |  |         sorted_data = grid.sort_data( | 
					
						
							|  |  |  |             sample_data, | 
					
						
							|  |  |  |             sorters=[{"key": "value", "dir": "asc"}, {"key": "name", "dir": "asc"}], | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         # nb. sorted data is in same order as original sample (not sorted) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(sorted_data[0]["name"], "foo1") | 
					
						
							|  |  |  |         self.assertEqual(sorted_data[-1]["name"], "foo9") | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |         # now try with a joiner | 
					
						
							|  |  |  |         query = self.session.query(model.User) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             model_class=model.User, | 
					
						
							|  |  |  |             data=query, | 
					
						
							|  |  |  |             columns=["username", "full_name"], | 
					
						
							|  |  |  |             sortable=True, | 
					
						
							|  |  |  |             sort_on_backend=True, | 
					
						
							|  |  |  |             sort_defaults="full_name", | 
					
						
							|  |  |  |             joiners={ | 
					
						
							|  |  |  |                 "full_name": lambda q: q.join(model.Person), | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         grid.set_sorter("full_name", model.Person.full_name) | 
					
						
							| 
									
										
										
										
											2024-08-21 20:15:23 -05:00
										 |  |  |         grid.load_settings() | 
					
						
							|  |  |  |         data = grid.get_visible_data() | 
					
						
							|  |  |  |         self.assertIsInstance(data, orm.Query) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  |     def test_paginate_data(self): | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         model = self.app.model | 
					
						
							|  |  |  |         sample_data = [ | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             {"name": "foo1", "value": "ONE"}, | 
					
						
							|  |  |  |             {"name": "foo2", "value": "two"}, | 
					
						
							|  |  |  |             {"name": "foo3", "value": "three"}, | 
					
						
							|  |  |  |             {"name": "foo4", "value": "four"}, | 
					
						
							|  |  |  |             {"name": "foo5", "value": "five"}, | 
					
						
							|  |  |  |             {"name": "foo6", "value": "six"}, | 
					
						
							|  |  |  |             {"name": "foo7", "value": "seven"}, | 
					
						
							|  |  |  |             {"name": "foo8", "value": "eight"}, | 
					
						
							|  |  |  |             {"name": "foo9", "value": "nine"}, | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         ] | 
					
						
							|  |  |  |         for setting in sample_data: | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.app.save_setting(self.session, setting["name"], setting["value"]) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         self.session.commit() | 
					
						
							|  |  |  |         sample_query = self.session.query(model.Setting) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # basic list pager | 
					
						
							|  |  |  |         grid = self.make_grid(paginated=True, paginate_on_backend=True) | 
					
						
							|  |  |  |         pager = grid.paginate_data(sample_data) | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  |         self.assertIsInstance(pager, Page) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         # basic query pager | 
					
						
							|  |  |  |         grid = self.make_grid(paginated=True, paginate_on_backend=True) | 
					
						
							|  |  |  |         pager = grid.paginate_data(sample_query) | 
					
						
							|  |  |  |         self.assertIsInstance(pager, SqlalchemyOrmPage) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-17 11:35:38 -05:00
										 |  |  |         # page is reset to 1 for empty data | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.request.session["grid.foo.page"] = 2 | 
					
						
							|  |  |  |         grid = self.make_grid(key="foo", paginated=True, paginate_on_backend=True) | 
					
						
							| 
									
										
										
										
											2024-08-17 11:35:38 -05:00
										 |  |  |         grid.load_settings() | 
					
						
							|  |  |  |         self.assertEqual(grid.page, 2) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(self.request.session["grid.foo.page"], 2) | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         pager = grid.paginate_data(sample_data) | 
					
						
							| 
									
										
										
										
											2024-08-17 11:35:38 -05:00
										 |  |  |         self.assertEqual(pager.page, 1) | 
					
						
							|  |  |  |         self.assertEqual(grid.page, 1) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(self.request.session["grid.foo.page"], 1) | 
					
						
							| 
									
										
										
										
											2024-08-17 11:35:38 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  |     ############################## | 
					
						
							|  |  |  |     # rendering methods | 
					
						
							|  |  |  |     ############################## | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-06 16:56:31 -06:00
										 |  |  |     def test_render_batch_id(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["foo", "bar"]) | 
					
						
							| 
									
										
										
										
											2025-01-06 16:56:31 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # null | 
					
						
							|  |  |  |         obj = MagicMock(foo=None) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.render_batch_id(obj, "foo", None), "") | 
					
						
							| 
									
										
										
										
											2025-01-06 16:56:31 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # int | 
					
						
							|  |  |  |         obj = MagicMock(foo=42) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.render_batch_id(obj, "foo", 42), "00000042") | 
					
						
							| 
									
										
										
										
											2025-01-06 16:56:31 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-02 20:13:04 -06:00
										 |  |  |     def test_render_boolean(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["foo", "bar"]) | 
					
						
							| 
									
										
										
										
											2025-01-02 20:13:04 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # null | 
					
						
							|  |  |  |         obj = MagicMock(foo=None) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.render_boolean(obj, "foo", None), "") | 
					
						
							| 
									
										
										
										
											2025-01-02 20:13:04 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # true | 
					
						
							|  |  |  |         obj = MagicMock(foo=True) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.render_boolean(obj, "foo", True), "Yes") | 
					
						
							| 
									
										
										
										
											2025-01-02 20:13:04 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # false | 
					
						
							|  |  |  |         obj = MagicMock(foo=False) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.render_boolean(obj, "foo", False), "No") | 
					
						
							| 
									
										
										
										
											2025-01-02 20:13:04 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_render_currency(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["foo", "bar"]) | 
					
						
							| 
									
										
										
										
											2025-01-02 20:13:04 -06:00
										 |  |  |         obj = MagicMock() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # null | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.render_currency(obj, "foo", None), "") | 
					
						
							| 
									
										
										
										
											2025-01-02 20:13:04 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # basic decimal example | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         value = decimal.Decimal("42.00") | 
					
						
							|  |  |  |         self.assertEqual(grid.render_currency(obj, "foo", value), "$42.00") | 
					
						
							| 
									
										
										
										
											2025-01-02 20:13:04 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # basic float example | 
					
						
							|  |  |  |         value = 42.00 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.render_currency(obj, "foo", value), "$42.00") | 
					
						
							| 
									
										
										
										
											2025-01-02 20:13:04 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # decimal places will be rounded | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         value = decimal.Decimal("42.12345") | 
					
						
							|  |  |  |         self.assertEqual(grid.render_currency(obj, "foo", value), "$42.12") | 
					
						
							| 
									
										
										
										
											2025-01-02 20:13:04 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # negative numbers get parens | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         value = decimal.Decimal("-42.42") | 
					
						
							|  |  |  |         self.assertEqual(grid.render_currency(obj, "foo", value), "($42.42)") | 
					
						
							| 
									
										
										
										
											2025-01-02 20:13:04 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-21 13:27:52 -06:00
										 |  |  |     def test_render_enum(self): | 
					
						
							|  |  |  |         enum = self.app.enum | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["foo", "bar"]) | 
					
						
							|  |  |  |         obj = {"status": None} | 
					
						
							| 
									
										
										
										
											2025-02-21 13:27:52 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # null | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         value = grid.render_enum(obj, "status", None, enum=enum.UpgradeStatus) | 
					
						
							| 
									
										
										
										
											2025-02-21 13:27:52 -06:00
										 |  |  |         self.assertIsNone(value) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # normal | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         obj["status"] = enum.UpgradeStatus.SUCCESS | 
					
						
							|  |  |  |         value = grid.render_enum(obj, "status", "SUCCESS", enum=enum.UpgradeStatus) | 
					
						
							|  |  |  |         self.assertEqual(value, "success") | 
					
						
							| 
									
										
										
										
											2025-02-21 13:27:52 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-25 22:34:49 -06:00
										 |  |  |     def test_render_percent(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["foo", "bar"]) | 
					
						
							| 
									
										
										
										
											2025-01-25 22:34:49 -06:00
										 |  |  |         obj = MagicMock() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # null | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.render_percent(obj, "foo", None), "") | 
					
						
							| 
									
										
										
										
											2025-01-25 22:34:49 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # typical | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.render_percent(obj, "foo", 12.3419), "12.34 %") | 
					
						
							| 
									
										
										
										
											2025-01-25 22:34:49 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # more decimal places | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             grid.render_percent(obj, "foo", 12.3419, decimals=3), "12.342 %" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             grid.render_percent(obj, "foo", 12.3419, decimals=4), "12.3419 %" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2025-01-25 22:34:49 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # negative | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.render_percent(obj, "foo", -12.3419), "(12.34 %)") | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             grid.render_percent(obj, "foo", -12.3419, decimals=3), "(12.342 %)" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2025-01-25 22:34:49 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-02 20:13:04 -06:00
										 |  |  |     def test_render_quantity(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["foo", "bar"]) | 
					
						
							| 
									
										
										
										
											2025-01-02 20:13:04 -06:00
										 |  |  |         obj = MagicMock() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # null | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.render_quantity(obj, "foo", None), "") | 
					
						
							| 
									
										
										
										
											2025-01-02 20:13:04 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # integer decimals become integers | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         value = decimal.Decimal("1.000") | 
					
						
							|  |  |  |         self.assertEqual(grid.render_quantity(obj, "foo", value), "1") | 
					
						
							| 
									
										
										
										
											2025-01-02 20:13:04 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # but decimal places are preserved | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         value = decimal.Decimal("1.234") | 
					
						
							|  |  |  |         self.assertEqual(grid.render_quantity(obj, "foo", value), "1.234") | 
					
						
							| 
									
										
										
										
											2025-01-02 20:13:04 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # zero is *not* empty string (with this renderer) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.render_quantity(obj, "foo", 0), "0") | 
					
						
							| 
									
										
										
										
											2025-01-02 20:13:04 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-13 17:02:39 -06:00
										 |  |  |     def test_render_date(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["foo", "bar"]) | 
					
						
							| 
									
										
										
										
											2025-01-13 17:02:39 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # null | 
					
						
							|  |  |  |         obj = MagicMock(dt=None) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         result = grid.render_date(obj, "dt", None) | 
					
						
							|  |  |  |         self.assertEqual(result, "") | 
					
						
							| 
									
										
										
										
											2025-01-13 17:02:39 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # typical | 
					
						
							|  |  |  |         dt = datetime.date(2025, 1, 13) | 
					
						
							|  |  |  |         obj = MagicMock(dt=dt) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         result = grid.render_date(obj, "dt", str(dt)) | 
					
						
							|  |  |  |         self.assertEqual(result, "2025-01-13") | 
					
						
							| 
									
										
										
										
											2025-01-13 17:02:39 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-12 15:15:00 -06:00
										 |  |  |     def test_render_datetime(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["foo", "bar"]) | 
					
						
							| 
									
										
										
										
											2024-12-12 15:15:00 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         obj = MagicMock(dt=None) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         result = grid.render_datetime(obj, "dt", None) | 
					
						
							|  |  |  |         self.assertEqual(result, "") | 
					
						
							| 
									
										
										
										
											2024-12-12 15:15:00 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         dt = datetime.datetime(2024, 12, 12, 13, 44, tzinfo=datetime.timezone.utc) | 
					
						
							|  |  |  |         obj = MagicMock(dt=dt) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         result = grid.render_datetime(obj, "dt", str(dt)) | 
					
						
							|  |  |  |         self.assertEqual(result, "2024-12-12 13:44+0000") | 
					
						
							| 
									
										
										
										
											2024-12-12 15:15:00 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-07 14:00:53 -05:00
										 |  |  |     def test_render_vue_tag(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["foo", "bar"]) | 
					
						
							| 
									
										
										
										
											2024-08-07 14:00:53 -05:00
										 |  |  |         html = grid.render_vue_tag() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(html, "<wutta-grid></wutta-grid>") | 
					
						
							| 
									
										
										
										
											2024-08-07 14:00:53 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_render_vue_template(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.pyramid_config.include("pyramid_mako") | 
					
						
							|  |  |  |         self.pyramid_config.add_subscriber( | 
					
						
							|  |  |  |             "wuttaweb.subscribers.before_render", "pyramid.events.BeforeRender" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-07 14:00:53 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["foo", "bar"]) | 
					
						
							| 
									
										
										
										
											2024-08-07 14:00:53 -05:00
										 |  |  |         html = grid.render_vue_template() | 
					
						
							|  |  |  |         self.assertIn('<script type="text/x-template" id="wutta-grid-template">', html) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-21 14:38:34 -05:00
										 |  |  |     def test_render_table_element(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.pyramid_config.include("pyramid_mako") | 
					
						
							|  |  |  |         self.pyramid_config.add_subscriber( | 
					
						
							|  |  |  |             "wuttaweb.subscribers.before_render", "pyramid.events.BeforeRender" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-21 14:38:34 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(key="foobar", columns=["foo", "bar"]) | 
					
						
							| 
									
										
										
										
											2024-08-21 14:38:34 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # form not required | 
					
						
							|  |  |  |         html = grid.render_table_element() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertNotIn("<script ", html) | 
					
						
							|  |  |  |         self.assertIn("<b-table ", html) | 
					
						
							| 
									
										
										
										
											2024-08-21 14:38:34 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # form will register grid data | 
					
						
							|  |  |  |         form = Form(self.request) | 
					
						
							| 
									
										
										
										
											2024-08-23 14:14:41 -05:00
										 |  |  |         self.assertEqual(len(form.grid_vue_context), 0) | 
					
						
							| 
									
										
										
										
											2024-08-21 14:38:34 -05:00
										 |  |  |         html = grid.render_table_element(form) | 
					
						
							| 
									
										
										
										
											2024-08-23 14:14:41 -05:00
										 |  |  |         self.assertEqual(len(form.grid_vue_context), 1) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertIn("foobar", form.grid_vue_context) | 
					
						
							| 
									
										
										
										
											2024-08-21 14:38:34 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-19 13:40:23 -05:00
										 |  |  |     def test_render_vue_finalize(self): | 
					
						
							|  |  |  |         grid = self.make_grid() | 
					
						
							|  |  |  |         html = grid.render_vue_finalize() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertIn("<script>", html) | 
					
						
							| 
									
										
										
										
											2024-08-19 13:40:23 -05:00
										 |  |  |         self.assertIn("Vue.component('wutta-grid', WuttaGrid)", html) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-07 14:00:53 -05:00
										 |  |  |     def test_get_vue_columns(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # error if no columns are set | 
					
						
							|  |  |  |         grid = self.make_grid() | 
					
						
							|  |  |  |         self.assertRaises(ValueError, grid.get_vue_columns) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # otherwise get back field/label dicts | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["foo", "bar"]) | 
					
						
							| 
									
										
										
										
											2024-08-07 14:00:53 -05:00
										 |  |  |         columns = grid.get_vue_columns() | 
					
						
							|  |  |  |         first = columns[0] | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(first["field"], "foo") | 
					
						
							|  |  |  |         self.assertEqual(first["label"], "Foo") | 
					
						
							| 
									
										
										
										
											2024-08-07 19:47:24 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-18 19:23:15 -05:00
										 |  |  |     def test_get_vue_active_sorters(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # empty | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(key="foo", sortable=True, sort_on_backend=True) | 
					
						
							| 
									
										
										
										
											2024-08-18 19:23:15 -05:00
										 |  |  |         grid.load_settings() | 
					
						
							|  |  |  |         sorters = grid.get_vue_active_sorters() | 
					
						
							|  |  |  |         self.assertEqual(sorters, []) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # format is different | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             key="settings", | 
					
						
							|  |  |  |             model_class=model.Setting, | 
					
						
							|  |  |  |             sortable=True, | 
					
						
							|  |  |  |             sort_on_backend=True, | 
					
						
							|  |  |  |             sort_defaults="name", | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-18 19:23:15 -05:00
										 |  |  |         grid.load_settings() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.active_sorters, [{"key": "name", "dir": "asc"}]) | 
					
						
							| 
									
										
										
										
											2024-08-18 19:23:15 -05:00
										 |  |  |         sorters = grid.get_vue_active_sorters() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(sorters, [{"field": "name", "order": "asc"}]) | 
					
						
							| 
									
										
										
										
											2024-08-18 19:23:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-09 08:44:11 -05:00
										 |  |  |     def test_get_vue_first_sorter(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # empty by default | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(key="foo", sortable=True) | 
					
						
							| 
									
										
										
										
											2025-08-09 08:44:11 -05:00
										 |  |  |         sorter = grid.get_vue_first_sorter() | 
					
						
							|  |  |  |         self.assertIsNone(sorter) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # will use first element from sort_defaults when applicable... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # basic | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(key="foo", sortable=True, sort_defaults="name") | 
					
						
							| 
									
										
										
										
											2025-08-09 08:44:11 -05:00
										 |  |  |         sorter = grid.get_vue_first_sorter() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(sorter, ["name", "asc"]) | 
					
						
							| 
									
										
										
										
											2025-08-09 08:44:11 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # descending | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(key="foo", sortable=True, sort_defaults=("name", "desc")) | 
					
						
							| 
									
										
										
										
											2025-08-09 08:44:11 -05:00
										 |  |  |         sorter = grid.get_vue_first_sorter() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(sorter, ["name", "desc"]) | 
					
						
							| 
									
										
										
										
											2025-08-09 08:44:11 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # multiple | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             key="foo", sortable=True, sort_defaults=[("key", "asc"), ("name", "asc")] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2025-08-09 08:44:11 -05:00
										 |  |  |         sorter = grid.get_vue_first_sorter() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(sorter, ["key", "asc"]) | 
					
						
							| 
									
										
										
										
											2025-08-09 08:44:11 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # will use first element from active_sorters when applicable... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # basic | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(key="foo", sortable=True) | 
					
						
							|  |  |  |         grid.active_sorters = [{"key": "name", "dir": "asc"}] | 
					
						
							| 
									
										
										
										
											2025-08-09 08:44:11 -05:00
										 |  |  |         sorter = grid.get_vue_first_sorter() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(sorter, ["name", "asc"]) | 
					
						
							| 
									
										
										
										
											2025-08-09 08:44:11 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # descending | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(key="foo", sortable=True) | 
					
						
							|  |  |  |         grid.active_sorters = [{"key": "name", "dir": "desc"}] | 
					
						
							| 
									
										
										
										
											2025-08-09 08:44:11 -05:00
										 |  |  |         sorter = grid.get_vue_first_sorter() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(sorter, ["name", "desc"]) | 
					
						
							| 
									
										
										
										
											2025-08-09 08:44:11 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # multiple | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(key="foo", sortable=True) | 
					
						
							|  |  |  |         grid.active_sorters = [ | 
					
						
							|  |  |  |             {"key": "key", "dir": "asc"}, | 
					
						
							|  |  |  |             {"key": "name", "dir": "asc"}, | 
					
						
							|  |  |  |         ] | 
					
						
							| 
									
										
										
										
											2025-08-09 08:44:11 -05:00
										 |  |  |         sorter = grid.get_vue_first_sorter() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(sorter, ["key", "asc"]) | 
					
						
							| 
									
										
										
										
											2025-08-09 08:44:11 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  |     def test_get_vue_filters(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # basic | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             key="settings", model_class=model.Setting, filterable=True | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  |         grid.load_settings() | 
					
						
							|  |  |  |         filters = grid.get_vue_filters() | 
					
						
							|  |  |  |         self.assertEqual(len(filters), 2) | 
					
						
							| 
									
										
										
										
											2025-02-21 13:27:52 -06:00
										 |  |  |         name, value = filters | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(name["choices"], []) | 
					
						
							|  |  |  |         self.assertEqual(name["choice_labels"], {}) | 
					
						
							|  |  |  |         self.assertEqual(value["choices"], []) | 
					
						
							|  |  |  |         self.assertEqual(value["choice_labels"], {}) | 
					
						
							| 
									
										
										
										
											2025-02-21 13:27:52 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         class MockEnum(Enum): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             FOO = "foo" | 
					
						
							|  |  |  |             BAR = "bar" | 
					
						
							| 
									
										
										
										
											2025-02-21 13:27:52 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # with filter choices | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid( | 
					
						
							|  |  |  |             key="settings", | 
					
						
							|  |  |  |             model_class=model.Setting, | 
					
						
							|  |  |  |             filterable=True, | 
					
						
							|  |  |  |             enums={"name": MockEnum}, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2025-02-21 13:27:52 -06:00
										 |  |  |         grid.load_settings() | 
					
						
							|  |  |  |         filters = grid.get_vue_filters() | 
					
						
							|  |  |  |         self.assertEqual(len(filters), 2) | 
					
						
							|  |  |  |         name, value = filters | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(name["choices"], ["FOO", "BAR"]) | 
					
						
							|  |  |  |         self.assertEqual(name["choice_labels"], {"FOO": "foo", "BAR": "bar"}) | 
					
						
							|  |  |  |         self.assertEqual(value["choices"], []) | 
					
						
							|  |  |  |         self.assertEqual(value["choice_labels"], {}) | 
					
						
							| 
									
										
										
										
											2024-08-22 13:50:29 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-25 19:11:41 -06:00
										 |  |  |     def test_object_to_dict(self): | 
					
						
							|  |  |  |         grid = self.make_grid() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         setting = {"name": "foo", "value": "bar"} | 
					
						
							| 
									
										
										
										
											2024-11-25 19:11:41 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # new dict but with same values | 
					
						
							|  |  |  |         dct = grid.object_to_dict(setting) | 
					
						
							|  |  |  |         self.assertIsInstance(dct, dict) | 
					
						
							|  |  |  |         self.assertIsNot(dct, setting) | 
					
						
							|  |  |  |         self.assertEqual(dct, setting) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # random object, not iterable | 
					
						
							|  |  |  |         class MockSetting: | 
					
						
							|  |  |  |             def __init__(self, **kw): | 
					
						
							|  |  |  |                 self.__dict__.update(kw) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-25 19:11:41 -06:00
										 |  |  |         mock = MockSetting(**setting) | 
					
						
							|  |  |  |         dct = grid.object_to_dict(mock) | 
					
						
							|  |  |  |         self.assertIsInstance(dct, dict) | 
					
						
							|  |  |  |         self.assertEqual(dct, setting) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-23 14:14:41 -05:00
										 |  |  |     def test_get_vue_context(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # empty if no columns defined | 
					
						
							|  |  |  |         grid = self.make_grid() | 
					
						
							|  |  |  |         context = grid.get_vue_context() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(context, {"data": [], "row_classes": {}}) | 
					
						
							| 
									
										
										
										
											2024-08-23 14:14:41 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # typical data is a list | 
					
						
							|  |  |  |         mydata = [ | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             {"foo": "bar"}, | 
					
						
							| 
									
										
										
										
											2024-08-23 14:14:41 -05:00
										 |  |  |         ] | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["foo"], data=mydata) | 
					
						
							| 
									
										
										
										
											2024-08-23 14:14:41 -05:00
										 |  |  |         context = grid.get_vue_context() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(context, {"data": [{"foo": "bar"}], "row_classes": {}}) | 
					
						
							| 
									
										
										
										
											2024-08-23 14:14:41 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # if grid has actions, that list may be supplemented | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.actions.append(mod.GridAction(self.request, "view", url="/blarg")) | 
					
						
							| 
									
										
										
										
											2024-08-23 14:14:41 -05:00
										 |  |  |         context = grid.get_vue_context() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertIsNot(context["data"], mydata) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             context, | 
					
						
							|  |  |  |             {"data": [{"foo": "bar", "_action_url_view": "/blarg"}], "row_classes": {}}, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-23 14:14:41 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can override value rendering | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_renderer("foo", lambda record, key, value: "blah blah") | 
					
						
							| 
									
										
										
										
											2024-08-23 14:14:41 -05:00
										 |  |  |         context = grid.get_vue_context() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             context, | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "data": [{"foo": "blah blah", "_action_url_view": "/blarg"}], | 
					
						
							|  |  |  |                 "row_classes": {}, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-23 14:14:41 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can set row class | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.row_class = "whatever" | 
					
						
							| 
									
										
										
										
											2024-08-23 14:14:41 -05:00
										 |  |  |         context = grid.get_vue_context() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             context, | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "data": [{"foo": "blah blah", "_action_url_view": "/blarg"}], | 
					
						
							|  |  |  |                 "row_classes": {"0": "whatever"}, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-23 14:14:41 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-07 19:47:24 -05:00
										 |  |  |     def test_get_vue_data(self): | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  |         # empty if no columns defined | 
					
						
							| 
									
										
										
										
											2024-08-07 19:47:24 -05:00
										 |  |  |         grid = self.make_grid() | 
					
						
							|  |  |  |         data = grid.get_vue_data() | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  |         self.assertEqual(data, []) | 
					
						
							| 
									
										
										
										
											2024-08-07 19:47:24 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-12 21:17:08 -05:00
										 |  |  |         # typical data is a list | 
					
						
							| 
									
										
										
										
											2024-08-07 19:47:24 -05:00
										 |  |  |         mydata = [ | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             {"foo": "bar"}, | 
					
						
							| 
									
										
										
										
											2024-08-07 19:47:24 -05:00
										 |  |  |         ] | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["foo"], data=mydata) | 
					
						
							| 
									
										
										
										
											2024-08-07 19:47:24 -05:00
										 |  |  |         data = grid.get_vue_data() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(data, [{"foo": "bar"}]) | 
					
						
							| 
									
										
										
										
											2024-08-07 19:47:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # if grid has actions, that list may be supplemented | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.actions.append(mod.GridAction(self.request, "view", url="/blarg")) | 
					
						
							| 
									
										
										
										
											2024-08-07 19:47:24 -05:00
										 |  |  |         data = grid.get_vue_data() | 
					
						
							|  |  |  |         self.assertIsNot(data, mydata) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(data, [{"foo": "bar", "_action_url_view": "/blarg"}]) | 
					
						
							| 
									
										
										
										
											2024-08-07 19:47:24 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-23 14:14:41 -05:00
										 |  |  |         # can override value rendering | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.set_renderer("foo", lambda record, key, value: "blah blah") | 
					
						
							| 
									
										
										
										
											2024-08-13 16:29:34 -05:00
										 |  |  |         data = grid.get_vue_data() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(data, [{"foo": "blah blah", "_action_url_view": "/blarg"}]) | 
					
						
							| 
									
										
										
										
											2024-08-13 16:29:34 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-23 14:14:41 -05:00
										 |  |  |     def test_get_row_class(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         user = model.User(username="barney", active=True) | 
					
						
							| 
									
										
										
										
											2024-08-23 14:14:41 -05:00
										 |  |  |         self.session.add(user) | 
					
						
							|  |  |  |         self.session.commit() | 
					
						
							|  |  |  |         data = dict(user) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # null by default | 
					
						
							|  |  |  |         grid = self.make_grid() | 
					
						
							|  |  |  |         self.assertIsNone(grid.get_row_class(user, data, 1)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # can use static class | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid.row_class = "foo" | 
					
						
							|  |  |  |         self.assertEqual(grid.get_row_class(user, data, 1), "foo") | 
					
						
							| 
									
										
										
										
											2024-08-23 14:14:41 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can use callable | 
					
						
							|  |  |  |         def status(u, d, i): | 
					
						
							|  |  |  |             if not u.active: | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |                 return "inactive" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-23 14:14:41 -05:00
										 |  |  |         grid.row_class = status | 
					
						
							|  |  |  |         self.assertIsNone(grid.get_row_class(user, data, 1)) | 
					
						
							|  |  |  |         user.active = False | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(grid.get_row_class(user, data, 1), "inactive") | 
					
						
							| 
									
										
										
										
											2024-08-23 14:14:41 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  |     def test_get_vue_pager_stats(self): | 
					
						
							|  |  |  |         data = [ | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             {"foo": 1, "bar": 1}, | 
					
						
							|  |  |  |             {"foo": 2, "bar": 2}, | 
					
						
							|  |  |  |             {"foo": 3, "bar": 3}, | 
					
						
							|  |  |  |             {"foo": 4, "bar": 4}, | 
					
						
							|  |  |  |             {"foo": 5, "bar": 5}, | 
					
						
							|  |  |  |             {"foo": 6, "bar": 6}, | 
					
						
							|  |  |  |             {"foo": 7, "bar": 7}, | 
					
						
							|  |  |  |             {"foo": 8, "bar": 8}, | 
					
						
							|  |  |  |             {"foo": 9, "bar": 9}, | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  |         ] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         grid = self.make_grid(columns=["foo", "bar"], pagesize=4, page=2) | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  |         grid.pager = grid.paginate_data(data) | 
					
						
							|  |  |  |         stats = grid.get_vue_pager_stats() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(stats["item_count"], 9) | 
					
						
							|  |  |  |         self.assertEqual(stats["items_per_page"], 4) | 
					
						
							|  |  |  |         self.assertEqual(stats["page"], 2) | 
					
						
							|  |  |  |         self.assertEqual(stats["first_item"], 5) | 
					
						
							|  |  |  |         self.assertEqual(stats["last_item"], 8) | 
					
						
							| 
									
										
										
										
											2024-08-16 22:52:24 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-07 19:47:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | class TestGridAction(TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def setUp(self): | 
					
						
							|  |  |  |         self.config = WuttaConfig() | 
					
						
							|  |  |  |         self.request = testing.DummyRequest(wutta_config=self.config, use_oruga=False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def make_action(self, key, **kwargs): | 
					
						
							| 
									
										
										
										
											2024-08-18 14:05:10 -05:00
										 |  |  |         return mod.GridAction(self.request, key, **kwargs) | 
					
						
							| 
									
										
										
										
											2024-08-07 19:47:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_render_icon(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # icon is derived from key by default | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         action = self.make_action("blarg") | 
					
						
							| 
									
										
										
										
											2024-08-07 19:47:24 -05:00
										 |  |  |         html = action.render_icon() | 
					
						
							|  |  |  |         self.assertIn('<i class="fas fa-blarg">', html) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-15 02:10:08 -05:00
										 |  |  |         # oruga has different output | 
					
						
							| 
									
										
										
										
											2024-08-07 19:47:24 -05:00
										 |  |  |         self.request.use_oruga = True | 
					
						
							| 
									
										
										
										
											2024-08-15 02:10:08 -05:00
										 |  |  |         html = action.render_icon() | 
					
						
							|  |  |  |         self.assertIn('<o-icon icon="blarg">', html) | 
					
						
							| 
									
										
										
										
											2024-08-07 19:47:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_render_label(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # label is derived from key by default | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         action = self.make_action("blarg") | 
					
						
							| 
									
										
										
										
											2024-08-07 19:47:24 -05:00
										 |  |  |         label = action.render_label() | 
					
						
							|  |  |  |         self.assertEqual(label, "Blarg") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # otherwise use what caller provides | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         action = self.make_action("foo", label="Bar") | 
					
						
							| 
									
										
										
										
											2024-08-07 19:47:24 -05:00
										 |  |  |         label = action.render_label() | 
					
						
							|  |  |  |         self.assertEqual(label, "Bar") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-11 09:56:47 -05:00
										 |  |  |     def test_render_icon_and_label(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         action = self.make_action("blarg") | 
					
						
							|  |  |  |         with patch.multiple( | 
					
						
							|  |  |  |             action, render_icon=lambda: "ICON", render_label=lambda: "LABEL" | 
					
						
							|  |  |  |         ): | 
					
						
							| 
									
										
										
										
											2024-08-11 09:56:47 -05:00
										 |  |  |             html = action.render_icon_and_label() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertEqual("ICON LABEL", html) | 
					
						
							| 
									
										
										
										
											2024-08-11 09:56:47 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-07 19:47:24 -05:00
										 |  |  |     def test_get_url(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         obj = {"foo": "bar"} | 
					
						
							| 
									
										
										
										
											2024-08-07 19:47:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # null by default | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         action = self.make_action("blarg") | 
					
						
							| 
									
										
										
										
											2024-08-07 19:47:24 -05:00
										 |  |  |         url = action.get_url(obj) | 
					
						
							|  |  |  |         self.assertIsNone(url) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # or can be "static" | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         action = self.make_action("blarg", url="/foo") | 
					
						
							| 
									
										
										
										
											2024-08-07 19:47:24 -05:00
										 |  |  |         url = action.get_url(obj) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(url, "/foo") | 
					
						
							| 
									
										
										
										
											2024-08-07 19:47:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # or can be "dynamic" | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         action = self.make_action("blarg", url=lambda o, i: "/yeehaw") | 
					
						
							| 
									
										
										
										
											2024-08-07 19:47:24 -05:00
										 |  |  |         url = action.get_url(obj) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(url, "/yeehaw") |