From aed1d5968abf97976db3725347fe4e7672c935e7 Mon Sep 17 00:00:00 2001 From: Christian Heller Date: Sat, 13 Apr 2024 04:25:36 +0200 Subject: [PATCH] Disable Todo.is_done setting if children are not done yet. --- plomtask/http.py | 7 ++++++- plomtask/todos.py | 8 ++++++++ tests/todos.py | 22 ++++++++++++++-------- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/plomtask/http.py b/plomtask/http.py index 5d165ec..5a7126e 100644 --- a/plomtask/http.py +++ b/plomtask/http.py @@ -209,7 +209,12 @@ class TaskHandler(BaseHTTPRequestHandler): if child_id is not None: child = Todo.by_id(conn, child_id) todo.add_child(child) - todo.is_done = len(form_data.get_all_str('done')) > 0 + if len(form_data.get_all_str('done')) > 0: + if not todo.is_doable: + raise BadFormatException('cannot set undoable Todo to done') + todo.is_done = True + else: + todo.is_done = False todo.save(conn) def do_POST_process(self, conn: DatabaseConnection, params: ParamsParser, diff --git a/plomtask/todos.py b/plomtask/todos.py index 2b9fd1d..43ada0b 100644 --- a/plomtask/todos.py +++ b/plomtask/todos.py @@ -61,6 +61,14 @@ class Todo: todos += [cls.by_id(db_conn, row[0])] return todos + @property + def is_doable(self) -> bool: + """Decide whether .is_done can be set to True based on children's.""" + for child in self.children: + if not child.is_done: + return False + return True + def add_child(self, child: Todo) -> None: """Add child to self.children, guard against recursion""" def walk_steps(node: Todo) -> None: diff --git a/tests/todos.py b/tests/todos.py index 6ef8b09..6fbb944 100644 --- a/tests/todos.py +++ b/tests/todos.py @@ -106,6 +106,11 @@ class TestsWithServer(TestCaseWithServer): def test_do_POST_todo(self) -> None: """Test POST /todo.""" + def post_and_reload(form_data: dict[str, object], + status: int = 302) -> Todo: + self.check_post(form_data, '/todo?id=1', status, '/') + self.db_conn.cached_todos = {} + return Todo.by_date(self.db_conn, '2024-01-01')[0] form_data = {'title': '', 'description': '', 'effort': 1} self.check_post(form_data, '/process', 302, '/') form_data = {'comment': '', 'new_todo': 1} @@ -115,16 +120,16 @@ class TestsWithServer(TestCaseWithServer): self.check_post(form_data, '/todo?id=', 404) self.check_post(form_data, '/todo?id=FOO', 400) self.check_post(form_data, '/todo?id=0', 404) - self.check_post(form_data, '/todo?id=1', 302, '/') - todo1 = Todo.by_date(self.db_conn, '2024-01-01')[0] + todo1 = post_and_reload(form_data) self.assertEqual(todo1.children, []) self.assertEqual(todo1.parents, []) self.assertEqual(todo1.is_done, False) form_data = {'done': ''} - self.check_post(form_data, '/todo?id=1', 302, '/') - self.db_conn.cached_todos = {} - todo1 = Todo.by_date(self.db_conn, '2024-01-01')[0] + todo1 = post_and_reload(form_data) self.assertEqual(todo1.is_done, True) + form_data = {} + todo1 = post_and_reload(form_data) + self.assertEqual(todo1.is_done, False) form_data = {'adopt': 'foo'} self.check_post(form_data, '/todo?id=1', 400) form_data = {'adopt': 1} @@ -134,15 +139,16 @@ class TestsWithServer(TestCaseWithServer): form_data = {'comment': '', 'new_todo': 1} self.check_post(form_data, '/day?date=2024-01-01', 302, '/') form_data = {'adopt': 2} - self.check_post(form_data, '/todo?id=1', 302, '/') - self.db_conn.cached_todos = {} - todo1 = Todo.by_date(self.db_conn, '2024-01-01')[0] + todo1 = post_and_reload(form_data) todo2 = Todo.by_date(self.db_conn, '2024-01-01')[1] self.assertEqual(todo1.children, [todo2]) self.assertEqual(todo1.parents, []) self.assertEqual(todo2.children, []) self.assertEqual(todo2.parents, [todo1]) self.check_post(form_data, '/todo?id=1', 400, '/') + form_data = {'done': ''} + todo1 = post_and_reload(form_data, 400) + self.assertEqual(todo1.is_done, False) def test_do_GET_todo(self) -> None: """Test GET /todo response codes.""" -- 2.30.2