home · contact · privacy
539d86f47bea49d639ff7ae377272e89059a9dcf
[plomtask] / tests / processes.py
1 """Test Processes module."""
2 from unittest import TestCase
3 from typing import Any
4 from tests.utils import TestCaseWithDB, TestCaseWithServer
5 from plomtask.processes import Process, ProcessStep
6 from plomtask.conditions import Condition
7 from plomtask.exceptions import NotFoundException, BadFormatException
8
9
10 class TestsSansDB(TestCase):
11     """Module tests not requiring DB setup."""
12
13     def test_Process_versioned_defaults(self) -> None:
14         """Test defaults of Process' VersionedAttributes."""
15         self.assertEqual(Process(None).title.newest, 'UNNAMED')
16         self.assertEqual(Process(None).description.newest, '')
17         self.assertEqual(Process(None).effort.newest, 1.0)
18
19     def test_Process_legal_ID(self) -> None:
20         """Test Process cannot be instantiated with id_=0."""
21         with self.assertRaises(BadFormatException):
22             Process(0)
23
24
25 class TestsWithDB(TestCaseWithDB):
26     """Mdule tests not requiring DB setup."""
27
28     def test_Process_ids(self) -> None:
29         """Test Process.save_without_steps() re Process.id_."""
30         p = Process(None)
31         p.save_without_steps(self.db_conn)
32         self.assertEqual(p.id_,
33                          Process.by_id(self.db_conn, 1, create=False).id_)
34         p = Process(None)
35         p.save_without_steps(self.db_conn)
36         self.assertEqual(p.id_,
37                          Process.by_id(self.db_conn, 2, create=False).id_)
38         p = Process(5)
39         p.save_without_steps(self.db_conn)
40         self.assertEqual(p.id_,
41                          Process.by_id(self.db_conn, 5, create=False).id_)
42
43     def test_Process_steps(self) -> None:
44         """Test addition, nesting, and non-recursion of ProcessSteps"""
45         p_1 = Process(1)
46         p_1.save_without_steps(self.db_conn)
47         assert p_1.id_ is not None
48         p_2 = Process(2)
49         p_2.save_without_steps(self.db_conn)
50         assert p_2.id_ is not None
51         p_3 = Process(3)
52         p_3.save_without_steps(self.db_conn)
53         assert p_3.id_ is not None
54         p_1.add_step(self.db_conn, None, p_2.id_, None)
55         p_1_dict: dict[int, dict[str, Any]] = {1: {
56             'process': p_2, 'parent_id': None,
57             'is_explicit': True, 'steps': {}, 'seen': False
58         }}
59         self.assertEqual(p_1.get_steps(self.db_conn, None), p_1_dict)
60         s_b = p_1.add_step(self.db_conn, None, p_3.id_, None)
61         p_1_dict[2] = {
62             'process': p_3, 'parent_id': None,
63             'is_explicit': True, 'steps': {}, 'seen': False
64         }
65         self.assertEqual(p_1.get_steps(self.db_conn, None), p_1_dict)
66         s_c = p_2.add_step(self.db_conn, None, p_3.id_, None)
67         assert s_c.id_ is not None
68         p_1_dict[1]['steps'] = {3: {
69             'process': p_3, 'parent_id': None,
70             'is_explicit': False, 'steps': {}, 'seen': False
71         }}
72         self.assertEqual(p_1.get_steps(self.db_conn, None), p_1_dict)
73         p_1.add_step(self.db_conn, None, p_2.id_, s_b.id_)
74         p_1_dict[2]['steps'][4] = {
75             'process': p_2, 'parent_id': s_b.id_, 'seen': False,
76             'is_explicit': True, 'steps': {3: {
77                 'process': p_3, 'parent_id': None,
78                 'is_explicit': False, 'steps': {}, 'seen': True
79                 }}}
80         self.assertEqual(p_1.get_steps(self.db_conn, None), p_1_dict)
81         p_1.add_step(self.db_conn, None, p_3.id_, 999)
82         p_1_dict[5] = {
83             'process': p_3, 'parent_id': None,
84             'is_explicit': True, 'steps': {}, 'seen': False
85         }
86         self.assertEqual(p_1.get_steps(self.db_conn, None), p_1_dict)
87         p_1.add_step(self.db_conn, None, p_3.id_, 3)
88         p_1_dict[6] = {
89             'process': p_3, 'parent_id': None,
90             'is_explicit': True, 'steps': {}, 'seen': False
91         }
92         self.assertEqual(p_1.get_steps(self.db_conn, None), p_1_dict)
93         self.assertEqual(p_1.used_as_step_by(self.db_conn), [])
94         self.assertEqual(p_2.used_as_step_by(self.db_conn), [p_1])
95         self.assertEqual(p_3.used_as_step_by(self.db_conn), [p_1, p_2])
96
97     def test_Process_undoes(self) -> None:
98         """Test setting Process.undoes"""
99         p = Process(None)
100         p.set_undoes(self.db_conn, [])
101         p.set_undoes(self.db_conn, [])
102         self.assertEqual(p.undoes, [])
103         c1 = Condition(None, False)
104         c1.save(self.db_conn)
105         assert c1.id_ is not None
106         p.set_undoes(self.db_conn, [c1.id_])
107         self.assertEqual(p.undoes, [c1])
108         c2 = Condition(None, False)
109         c2.save(self.db_conn)
110         assert c2.id_ is not None
111         p.set_undoes(self.db_conn, [c2.id_])
112         self.assertEqual(p.undoes, [c2])
113         p.set_undoes(self.db_conn, [c1.id_, c2.id_])
114         self.assertEqual(p.undoes, [c1, c2])
115
116     def test_Process_fulfills(self) -> None:
117         """Test setting Process.fulfills"""
118         p = Process(None)
119         p.set_fulfills(self.db_conn, [])
120         p.set_fulfills(self.db_conn, [])
121         self.assertEqual(p.fulfills, [])
122         c1 = Condition(None, False)
123         c1.save(self.db_conn)
124         assert c1.id_ is not None
125         p.set_fulfills(self.db_conn, [c1.id_])
126         self.assertEqual(p.fulfills, [c1])
127         c2 = Condition(None, False)
128         c2.save(self.db_conn)
129         assert c2.id_ is not None
130         p.set_fulfills(self.db_conn, [c2.id_])
131         self.assertEqual(p.fulfills, [c2])
132         p.set_fulfills(self.db_conn, [c1.id_, c2.id_])
133         self.assertEqual(p.fulfills, [c1, c2])
134
135     def test_Process_conditions(self) -> None:
136         """Test setting Process.conditions"""
137         p = Process(None)
138         p.set_conditions(self.db_conn, [])
139         p.set_conditions(self.db_conn, [])
140         self.assertEqual(p.conditions, [])
141         c1 = Condition(None, False)
142         c1.save(self.db_conn)
143         assert c1.id_ is not None
144         p.set_conditions(self.db_conn, [c1.id_])
145         self.assertEqual(p.conditions, [c1])
146         c2 = Condition(None, False)
147         c2.save(self.db_conn)
148         assert c2.id_ is not None
149         p.set_conditions(self.db_conn, [c2.id_])
150         self.assertEqual(p.conditions, [c2])
151         p.set_conditions(self.db_conn, [c1.id_, c2.id_])
152         self.assertEqual(p.conditions, [c1, c2])
153
154     def test_Process_by_id(self) -> None:
155         """Test Process.by_id()."""
156         with self.assertRaises(NotFoundException):
157             Process.by_id(self.db_conn, None, create=False)
158         with self.assertRaises(NotFoundException):
159             Process.by_id(self.db_conn, 0, create=False)
160         with self.assertRaises(NotFoundException):
161             Process.by_id(self.db_conn, 1, create=False)
162         self.assertNotEqual(Process(1).id_,
163                             Process.by_id(self.db_conn, None, create=True).id_)
164         self.assertEqual(Process(1).id_,
165                          Process.by_id(self.db_conn, 1, create=True).id_)
166         self.assertEqual(Process(2).id_,
167                          Process.by_id(self.db_conn, 2, create=True).id_)
168
169     def test_Process_all(self) -> None:
170         """Test Process.all()."""
171         p_1 = Process(None)
172         p_1.save_without_steps(self.db_conn)
173         p_2 = Process(None)
174         p_2.save_without_steps(self.db_conn)
175         self.assertEqual({p_1.id_, p_2.id_},
176                          set(p.id_ for p in Process.all(self.db_conn)))
177
178     def test_ProcessStep_singularity(self) -> None:
179         """Test pointers made for single object keep pointing to it."""
180         p_1 = Process(None)
181         p_1.save_without_steps(self.db_conn)
182         p_2 = Process(None)
183         p_2.save_without_steps(self.db_conn)
184         assert p_2.id_ is not None
185         step = p_1.add_step(self.db_conn, None, p_2.id_, None)
186         assert step.id_ is not None
187         step_retrieved = ProcessStep.by_id(self.db_conn, step.id_)
188         step.parent_step_id = 99
189         self.assertEqual(step.parent_step_id, step_retrieved.parent_step_id)
190
191     def test_Process_singularity(self) -> None:
192         """Test pointers made for single object keep pointing to it."""
193         p_1 = Process(None)
194         p_1.save_without_steps(self.db_conn)
195         p_2 = Process(None)
196         p_2.save_without_steps(self.db_conn)
197         assert p_2.id_ is not None
198         p_1.add_step(self.db_conn, None, p_2.id_, None)
199         p_retrieved = Process.by_id(self.db_conn, p_1.id_)
200         self.assertEqual(p_1.explicit_steps, p_retrieved.explicit_steps)
201
202     def test_Process_versioned_attributes_singularity(self) -> None:
203         """Test behavior of VersionedAttributes on saving (with .title)."""
204         p = Process(None)
205         p.save_without_steps(self.db_conn)
206         p.title.set('named')
207         p_loaded = Process.by_id(self.db_conn, p.id_)
208         self.assertEqual(p.title.history, p_loaded.title.history)
209
210
211 class TestsWithServer(TestCaseWithServer):
212     """Module tests against our HTTP server/handler (and database)."""
213
214     def test_do_POST_process(self) -> None:
215         """Test POST /process and its effect on the database."""
216         self.assertEqual(0, len(Process.all(self.db_conn)))
217         form_data = {'title': 'foo', 'description': 'foo', 'effort': 1.1}
218         self.check_post(form_data, '/process?id=', 302, '/')
219         self.assertEqual(1, len(Process.all(self.db_conn)))
220         self.check_post(form_data, '/process?id=FOO', 400)
221         form_data['effort'] = 'foo'
222         self.check_post(form_data, '/process?id=', 400)
223         self.check_post({}, '/process?id=', 400)
224         form_data = {'title': '', 'description': ''}
225         self.check_post(form_data, '/process?id=', 400)
226         form_data = {'title': '', 'effort': 1.1}
227         self.check_post(form_data, '/process?id=', 400)
228         form_data = {'description': '', 'effort': 1.0}
229         self.check_post(form_data, '/process?id=', 400)
230         self.assertEqual(1, len(Process.all(self.db_conn)))
231         form_data = {'title': 'foo', 'description': 'foo', 'effort': 1.0,
232                      'condition': []}
233         self.check_post(form_data, '/process?id=', 302, '/')
234         form_data['condition'] = [1]
235         self.check_post(form_data, '/process?id=', 404)
236         form_data_cond = {'title': 'foo', 'description': 'foo'}
237         self.check_post(form_data_cond, '/condition', 302, '/')
238         self.check_post(form_data, '/process?id=', 302, '/')
239         form_data['undoes'] = [1]
240         self.check_post(form_data, '/process?id=', 302, '/')
241         form_data['fulfills'] = [1]
242         self.check_post(form_data, '/process?id=', 302, '/')
243
244     def test_do_GET(self) -> None:
245         """Test /process and /processes response codes."""
246         self.check_get('/process', 200)
247         self.check_get('/process?id=', 200)
248         self.check_get('/process?id=0', 400)
249         self.check_get('/process?id=FOO', 400)
250         self.check_get('/processes', 200)