1 """Test Conditions module."""
2 from unittest import TestCase
3 from tests.utils import TestCaseWithDB, TestCaseWithServer
4 from plomtask.conditions import Condition
5 from plomtask.processes import Process
6 from plomtask.todos import Todo
7 from plomtask.exceptions import NotFoundException, HandledException
10 class TestsSansDB(TestCase):
11 """Tests requiring no DB setup."""
13 def test_Condition_id_setting(self) -> None:
14 """Test .id_ being set and its legal range being enforced."""
15 with self.assertRaises(HandledException):
17 condition = Condition(5)
18 self.assertEqual(condition.id_, 5)
21 class TestsWithDB(TestCaseWithDB):
22 """Tests requiring DB, but not server setup."""
24 def check_storage(self, content: list[Condition]) -> None:
25 """Test cache and DB equal content."""
28 expected_cache[item.id_] = item
29 self.assertEqual(Condition.get_cache(), expected_cache)
30 db_found: list[Condition] = []
32 assert isinstance(item.id_, int)
33 for row in self.db_conn.row_where(Condition.table_name, 'id',
35 db_found += [Condition.from_table_row(self.db_conn, row)]
36 self.assertEqual(sorted(content), sorted(db_found))
38 def test_Condition_saving_and_caching(self) -> None:
39 """Test .save/.save_core."""
40 c = Condition(None, False)
43 c.description.set('desc1')
44 c.description.set('desc2')
45 # check object init itself doesn't store anything yet
46 self.check_storage([])
47 # check saving stores in cache and DB
49 self.check_storage([c])
50 # check attributes set properly (and not unset by saving)
51 self.assertEqual(c.id_, 1)
52 self.assertEqual(c.is_active, False)
53 self.assertEqual(sorted(c.title.history.values()),
55 self.assertEqual(sorted(c.description.history.values()),
58 def test_Condition_from_table_row(self) -> None:
59 """Test .from_table_row() properly reads in class from DB"""
60 c = Condition(1, True)
63 c.description.set('desc1')
64 c.description.set('desc2')
66 assert isinstance(c.id_, int)
67 for row in self.db_conn.row_where(Condition.table_name, 'id', c.id_):
68 retrieved = Condition.from_table_row(self.db_conn, row)
69 assert isinstance(retrieved, Condition)
70 self.assertEqual(c, retrieved)
71 self.assertEqual({c.id_: c}, Condition.get_cache())
72 # pylint: disable=no-member
73 self.assertEqual(sorted(retrieved.title.history.values()),
75 # pylint: disable=no-member
76 self.assertEqual(sorted(retrieved.description.history.values()),
79 def test_Condition_by_id(self) -> None:
80 """Test .by_id(), including creation."""
81 # check failure if not yet saved
82 c = Condition(3, False)
83 with self.assertRaises(NotFoundException):
84 Condition.by_id(self.db_conn, 3)
85 # check identity of saved and retrieved
87 self.assertEqual(c, Condition.by_id(self.db_conn, 3))
88 # check create=True acts like normal instantiation (sans saving)
89 by_id_created = Condition.by_id(self.db_conn, 4, create=True)
90 self.assertEqual(Condition(4), by_id_created)
91 self.check_storage([c])
93 def test_Condition_all(self) -> None:
95 c_1 = Condition(None, False)
96 # check pre-save .all() returns empty list
97 self.assertEqual(Condition.all(self.db_conn), [])
98 # check .save() fills .all() result
99 c_1.save(self.db_conn)
100 self.assertEqual(Condition.all(self.db_conn), [c_1])
101 c_2 = Condition(None, True)
102 c_2.save(self.db_conn)
103 self.assertEqual(sorted(Condition.all(self.db_conn)),
106 def test_Condition_singularity(self) -> None:
107 """Test pointers made for single object keep pointing to it."""
108 c = Condition(None, False)
111 retrieved = Condition.by_id(self.db_conn, 1)
112 self.assertEqual(True, retrieved.is_active)
114 def test_Condition_remove(self) -> None:
115 """Test .remove() effects on DB and cache."""
116 # check only saved item can be removed
117 c = Condition(None, False)
118 with self.assertRaises(HandledException):
119 c.remove(self.db_conn)
121 c.remove(self.db_conn)
122 self.check_storage([])
123 # check guard against deleting dependencies of other classes
125 todo = Todo(None, proc, False, '2024-01-01')
126 for depender in (proc, todo):
127 assert hasattr(depender, 'save')
128 assert hasattr(depender, 'set_conditions')
130 depender.save(self.db_conn)
131 depender.set_conditions(self.db_conn, [c.id_], 'conditions')
132 depender.save(self.db_conn)
133 with self.assertRaises(HandledException):
134 c.remove(self.db_conn)
135 depender.set_conditions(self.db_conn, [], 'conditions')
136 depender.save(self.db_conn)
137 c.remove(self.db_conn)
140 class TestsWithServer(TestCaseWithServer):
141 """Module tests against our HTTP server/handler (and database)."""
143 def test_do_POST_condition(self) -> None:
144 """Test POST /condition and its effect on the database."""
145 form_data = {'title': 'foo', 'description': 'foo'}
146 self.check_post(form_data, '/condition', 302, '/condition?id=1')
147 self.assertEqual(1, len(Condition.all(self.db_conn)))
148 form_data['delete'] = ''
149 self.check_post(form_data, '/condition?id=', 404)
150 self.check_post(form_data, '/condition?id=2', 404)
151 self.check_post(form_data, '/condition?id=1', 302, '/conditions')
152 self.assertEqual(0, len(Condition.all(self.db_conn)))
154 def test_do_GET(self) -> None:
155 """Test /condition and /conditions response codes."""
156 form_data = {'title': 'foo', 'description': 'foo'}
157 self.check_post(form_data, '/condition', 302, '/condition?id=1')
158 self.check_get_defaults('/condition')
159 self.check_get('/conditions', 200)