From: Christian Heller Date: Mon, 22 Apr 2024 00:13:39 +0000 (+0200) Subject: Allow Todo adoptions to be un-done in Todo view. X-Git-Url: https://plomlompom.com/repos/%7B%7Bprefix%7D%7D/static/%7B%7Byoutube_prefix%7D%7D%7B%7Bvideo_data.id_%7D%7D?a=commitdiff_plain;h=010ef4bfea17be7436a937f28e7b54d3da17a1e1;p=plomtask Allow Todo adoptions to be un-done in Todo view. --- diff --git a/plomtask/http.py b/plomtask/http.py index e541057..b5a6c16 100644 --- a/plomtask/http.py +++ b/plomtask/http.py @@ -205,8 +205,15 @@ class TaskHandler(BaseHTTPRequestHandler): """Update Todo and its children.""" id_ = self.params.get_int('id') todo = Todo.by_id(self.conn, id_) - child_id = self.form_data.get_int_or_none('adopt') - if child_id is not None: + adopted_child_ids = self.form_data.get_all_int('adopt') + for child in todo.children: + if child.id_ not in adopted_child_ids: + assert isinstance(child.id_, int) + child = Todo.by_id(self.conn, child.id_) + todo.remove_child(child) + for child_id in adopted_child_ids: + if child_id in [c.id_ for c in todo.children]: + continue child = Todo.by_id(self.conn, child_id) todo.add_child(child) todo.set_conditions(self.conn, self.form_data.get_all_int('condition')) diff --git a/plomtask/todos.py b/plomtask/todos.py index 336ec03..cf4c330 100644 --- a/plomtask/todos.py +++ b/plomtask/todos.py @@ -170,7 +170,7 @@ class Todo(BaseModel, ConditionsRelations): return node def add_child(self, child: Todo) -> None: - """Add child to self.children, guard against recursion""" + """Add child to self.children, avoid recursion, update parenthoods.""" def walk_steps(node: Todo) -> None: if node.id_ == self.id_: raise BadFormatException('bad child choice causes recursion') @@ -186,6 +186,13 @@ class Todo(BaseModel, ConditionsRelations): self.children += [child] child.parents += [self] + def remove_child(self, child: Todo) -> None: + """Remove child from self.children, update counter relations.""" + if child not in self.children: + raise HandledException('Cannot remove un-parented child.') + self.children.remove(child) + child.parents.remove(self) + def save(self, db_conn: DatabaseConnection) -> None: """Write self and children to DB and its cache.""" if self.process.id_ is None: diff --git a/templates/todo.html b/templates/todo.html index 92b0657..9debffc 100644 --- a/templates/todo.html +++ b/templates/todo.html @@ -65,7 +65,8 @@ add disables: {{child.process.title.newest|e}} +
  • +{{child.process.title.newest|e}} {% endfor %} adopt: diff --git a/tests/todos.py b/tests/todos.py index 52363c0..4ab34ab 100644 --- a/tests/todos.py +++ b/tests/todos.py @@ -270,9 +270,9 @@ class TestsWithServer(TestCaseWithServer): return Todo.by_date(self.db_conn, '2024-01-01')[0] # test minimum form_data = {'title': '', 'description': '', 'effort': 1} - self.check_post(form_data, '/process', 302, '/') + self.check_post(form_data, '/process', 302) form_data = {'comment': '', 'new_todo': 1} - self.check_post(form_data, '/day?date=2024-01-01', 302, '/') + self.check_post(form_data, '/day?date=2024-01-01', 302) # test posting to bad URLs form_data = {} self.check_post(form_data, '/todo=', 404) @@ -301,7 +301,7 @@ class TestsWithServer(TestCaseWithServer): self.check_post(form_data, '/todo?id=1', 404) # test posting second todo of same process form_data = {'comment': '', 'new_todo': 1} - self.check_post(form_data, '/day?date=2024-01-01', 302, '/') + self.check_post(form_data, '/day?date=2024-01-01', 302) # test todo 1 adopting todo 2 form_data = {'adopt': 2} todo1 = post_and_reload(form_data) @@ -310,12 +310,18 @@ class TestsWithServer(TestCaseWithServer): self.assertEqual(todo1.parents, []) self.assertEqual(todo2.children, []) self.assertEqual(todo2.parents, [todo1]) - # test failure of re-adopting same child - self.check_post(form_data, '/todo?id=1', 400, '/') # test todo1 cannot be set done with todo2 not done yet - form_data = {'done': ''} + form_data = {'done': '', 'adopt': 2} todo1 = post_and_reload(form_data, 400) self.assertEqual(todo1.is_done, False) + # test todo1 un-adopting todo 2 by just not sending an adopt + form_data = {} + todo1 = post_and_reload(form_data, 302) + todo2 = Todo.by_date(self.db_conn, '2024-01-01')[1] + self.assertEqual(todo1.children, []) + self.assertEqual(todo1.parents, []) + self.assertEqual(todo2.children, []) + self.assertEqual(todo2.parents, []) def test_do_GET_todo(self) -> None: """Test GET /todo response codes."""