From 607cd1e87c1ac45783b344f80632c860859a29b8 Mon Sep 17 00:00:00 2001 From: Christian Heller Date: Sun, 18 Aug 2024 15:46:13 +0200 Subject: [PATCH] Minor test improvements/expansions/refactorings. --- tests/conditions.py | 46 +++++++++++++++------------------------------ tests/todos.py | 23 +++++++++-------------- tests/utils.py | 16 +++++++++++++++- 3 files changed, 39 insertions(+), 46 deletions(-) diff --git a/tests/conditions.py b/tests/conditions.py index c071e65..b35dc6e 100644 --- a/tests/conditions.py +++ b/tests/conditions.py @@ -3,9 +3,6 @@ from typing import Any from tests.utils import (TestCaseSansDB, TestCaseWithDB, TestCaseWithServer, Expected) from plomtask.conditions import Condition -from plomtask.processes import Process -from plomtask.todos import Todo -from plomtask.exceptions import HandledException class TestsSansDB(TestCaseSansDB): @@ -18,26 +15,6 @@ class TestsWithDB(TestCaseWithDB): checked_class = Condition default_init_kwargs = {'is_active': 0} - def test_remove(self) -> None: - """Test .remove() effects on DB and cache.""" - super().test_remove() - proc = Process(None) - proc.save(self.db_conn) - todo = Todo(None, proc, False, '2024-01-01') - todo.save(self.db_conn) - # check condition can only be deleted if not depended upon - for depender in (proc, todo): - c = Condition(None) - c.save(self.db_conn) - assert isinstance(c.id_, int) - depender.set_condition_relations(self.db_conn, [c.id_], [], [], []) - depender.save(self.db_conn) - with self.assertRaises(HandledException): - c.remove(self.db_conn) - depender.set_condition_relations(self.db_conn, [], [], [], []) - depender.save(self.db_conn) - c.remove(self.db_conn) - class ExpectedGetConditions(Expected): """Builder of expectations for GET /conditions.""" @@ -81,6 +58,16 @@ class TestsWithServer(TestCaseWithServer): self.check_minimal_inputs('/condition', valid_payload) # check valid POST payload on bad paths self.check_post(valid_payload, '/condition?id=foo', 400) + # check cannot delete depended-upon Condition + self.post_exp_cond([], {}) + for key in ('conditions', 'blockers', 'enables', 'disables'): + self.post_exp_process([], {key: [1]}, 1) + self.check_post({'delete': ''}, '/condition?id=1', 500) + self.post_exp_process([], {}, 1) + self.post_exp_day([], {'new_todo': '1'}) + for key in ('conditions', 'blockers', 'enables', 'disables'): + self.post_exp_todo([], {key: [1]}, 1) + self.check_post({'delete': ''}, '/condition?id=1', 500) def test_POST_condition(self) -> None: """Test (valid) POST /condition and its effect on GET /condition[s].""" @@ -88,24 +75,22 @@ class TestsWithServer(TestCaseWithServer): exp_single, exp_all = ExpectedGetCondition(1), ExpectedGetConditions() all_exps = [exp_single, exp_all] # test valid POST's effect on single /condition and full /conditions - self.post_exp_cond(all_exps, {'title': 'foo', 'description': 'oof'}, - post_to_id=False) + self.post_exp_cond(all_exps, {}, post_to_id=False) self.check_json_get(url_single, exp_single) self.check_json_get(url_all, exp_all) # test (no) effect of invalid POST to existing Condition on /condition self.check_post({}, url_single, 400) self.check_json_get(url_single, exp_single) - # test effect of POST changing title and activeness + # test effect of POST changing title, description, and activeness self.post_exp_cond(all_exps, {'title': 'bar', 'description': 'oof', 'is_active': 1}) self.check_json_get(url_single, exp_single) - self.check_json_get(url_all, exp_all) # test POST sans 'is_active' setting it negative - self.post_exp_cond(all_exps, {'title': 'bar', 'description': 'oof'}) + self.post_exp_cond(all_exps, {}) self.check_json_get(url_single, exp_single) - self.check_json_get(url_all, exp_all) # test deletion POST's effect, both to return id=1 into empty single, # full /conditions into empty list + self.check_json_get(url_single, exp_single) self.post_exp_cond(all_exps, {'delete': ''}, redir_to_id=False) exp_single.set('is_new', True) self.check_json_get(url_single, exp_single) @@ -125,8 +110,7 @@ class TestsWithServer(TestCaseWithServer): # make Condition and two Processes that among them establish all # possible ConditionsRelations to it, check /condition displays all exp = ExpectedGetCondition(1) - self.post_exp_cond([exp], {'title': 'foo', 'description': 'oof'}, - post_to_id=False) + self.post_exp_cond([exp], {}, post_to_id=False) for i, p in enumerate([('conditions', 'disables'), ('enables', 'blockers')]): self.post_exp_process([exp], {k: [1] for k in p}, i+1) diff --git a/tests/todos.py b/tests/todos.py index ea61a33..834330b 100644 --- a/tests/todos.py +++ b/tests/todos.py @@ -232,11 +232,6 @@ class TestsWithServer(TestCaseWithServer): """Tests against our HTTP server/handler (and database).""" checked_class = Todo - def _post_exp_todo( - self, id_: int, payload: dict[str, Any], exp: Expected) -> None: - self.check_post(payload, f'/todo?id={id_}') - exp.set_todo_from_post(id_, payload) - def test_basic_fail_POST_todo(self) -> None: """Test basic malformed/illegal POST /todo requests.""" self.post_exp_process([], {}, 1) @@ -270,10 +265,10 @@ class TestsWithServer(TestCaseWithServer): # test posting doneness, comment, calendarization, effort todo_post = {'is_done': 1, 'calendarize': 1, 'comment': 'foo', 'effort': 2.3} - self._post_exp_todo(1, todo_post, exp) + self.post_exp_todo([exp], todo_post, 1) self.check_json_get('/todo?id=1', exp) # test implicitly un-setting comment/calendarize/is_done by empty post - self._post_exp_todo(1, {}, exp) + self.post_exp_todo([exp], {}, 1) self.check_json_get('/todo?id=1', exp) # test effort post can be explicitly unset by "effort":"" post self.check_post({'effort': ''}, '/todo?id=1') @@ -287,7 +282,7 @@ class TestsWithServer(TestCaseWithServer): self.check_json_get('/todo?id=1', exp) todo_post = {'conditions': [1], 'disables': [1], 'blockers': [2], 'enables': [2]} - self._post_exp_todo(1, todo_post, exp) + self.post_exp_todo([exp], todo_post, 1) self.check_json_get('/todo?id=1', exp) def test_POST_todo_deletion(self) -> None: @@ -333,12 +328,12 @@ class TestsWithServer(TestCaseWithServer): self.post_exp_process([exp], {}, 1) self.post_exp_day([exp], {'new_todo': [1]}) self.post_exp_day([exp], {'new_todo': [1]}) - self._post_exp_todo(1, {'adopt': 2}, exp) + self.post_exp_todo([exp], {'adopt': 2}, 1) exp.set('steps_todo_to_process', [ exp.step_as_dict(node_id=1, process=None, todo=2)]) self.check_json_get('/todo?id=1', exp) # test Todo un-adopting by just not sending an adopt - self._post_exp_todo(1, {}, exp) + self.post_exp_todo([exp], {}, 1) exp.set('steps_todo_to_process', []) self.check_json_get('/todo?id=1', exp) # test fail on trying to adopt non-existing Todo @@ -346,11 +341,11 @@ class TestsWithServer(TestCaseWithServer): # test cannot self-adopt self.check_post({'adopt': 1}, '/todo?id=1', 400) # test cannot do 1-step circular adoption - self._post_exp_todo(2, {'adopt': 1}, exp) + self.post_exp_todo([exp], {'adopt': 1}, 2) self.check_post({'adopt': 2}, '/todo?id=1', 400) # test cannot do 2-step circular adoption self.post_exp_day([exp], {'new_todo': [1]}) - self._post_exp_todo(3, {'adopt': 2}, exp) + self.post_exp_todo([exp], {'adopt': 2}, 3) self.check_post({'adopt': 3}, '/todo?id=1', 400) # test can adopt Todo into ProcessStep chain via its Process (with key # 'step_filler' equivalent to single-element 'adopt' if intable) @@ -367,7 +362,7 @@ class TestsWithServer(TestCaseWithServer): self.post_exp_day([exp], {'new_todo': [2]}) self.post_exp_day([exp], {'new_todo': [3]}) self.check_json_get('/todo?id=1', exp) - self._post_exp_todo(1, {'step_filler_to_1': 5, 'adopt': [4]}, exp) + self.post_exp_todo([exp], {'step_filler_to_1': 5, 'adopt': [4]}, 1) exp.lib_get('Todo', 1)['children'] += [5] slots[0]['todo'] = 4 slots[1]['todo'] = 5 @@ -386,7 +381,7 @@ class TestsWithServer(TestCaseWithServer): slots[1]['children'] = [exp.step_as_dict( node_id=3, process=4, todo=None, fillable=True)] self.post_exp_day([exp], {'new_todo': [4]}) - self._post_exp_todo(1, {'adopt': [4, 5, 6]}, exp) + self.post_exp_todo([exp], {'adopt': [4, 5, 6]}, 1) slots += [exp.step_as_dict( node_id=4, process=None, todo=6, fillable=False)] self.check_json_get('/todo?id=1', exp) diff --git a/tests/utils.py b/tests/utils.py index 045194f..b9db97e 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -713,7 +713,7 @@ class Expected: def set_cond_from_post(self, id_: int, d: dict[str, Any]) -> None: """Set Condition of id_ in library based on POST dict d.""" - if d == {'delete': ''}: + if 'delete' in d: self.lib_del('Condition', id_) return cond = self.lib_get('Condition', id_) @@ -892,6 +892,10 @@ class TestCaseWithServer(TestCaseWithDB): # pylint: disable=too-many-arguments target = f'/condition?id={id_}' if post_to_id else '/condition' redir = f'/condition?id={id_}' if redir_to_id else '/conditions' + if 'title' not in payload: + payload['title'] = 'foo' + if 'description' not in payload: + payload['description'] = 'foo' self.check_post(payload, target, redir=redir) for exp in exps: exp.set_cond_from_post(id_, payload) @@ -930,6 +934,16 @@ class TestCaseWithServer(TestCaseWithDB): exp.set_proc_from_post(id_, payload) return payload + def post_exp_todo(self, + exps: list[Expected], + payload: dict[str, Any], + id_: int, + ) -> None: + """POST /todo, appropriately updated Expecteds.""" + self.check_post(payload, f'/todo?id={id_}') + for exp in exps: + exp.set_todo_from_post(id_, payload) + def check_filter(self, exp: Expected, category: str, key: str, val: str, list_ids: list[int]) -> None: """Check GET /{category}?{key}={val} sorts to list_ids.""" -- 2.30.2