home · contact · privacy
Disable Todo.is_done setting if children are not done yet.
authorChristian Heller <c.heller@plomlompom.de>
Sat, 13 Apr 2024 02:25:36 +0000 (04:25 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Sat, 13 Apr 2024 02:25:36 +0000 (04:25 +0200)
plomtask/http.py
plomtask/todos.py
tests/todos.py

index 5d165ecf90f1ca6ebaed77e55b73a5d55ff428b8..5a7126e3232176630d78ddd43b10bb659c425e94 100644 (file)
@@ -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,
index 2b9fd1d8edb2fa159f3955f469a6b3d394aa1efa..43ada0b6a04f3df387c1f1933356e1e2b1832fbc 100644 (file)
@@ -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:
index 6ef8b091396b9d1047a1122ce8a446a7c995c14d..6fbb944b92eafd353518773ac555152ead43b421 100644 (file)
@@ -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."""