for suffix in ['', 'x', '1.1']:
                 self.check_post({'fill_for_1': f'{prefix}{suffix}'},
                                 '/todo?id=1', 400, '/todo')
-        # test we cannot POST adoption of self or non-existing Todo
-        self.check_post({'adopt': 1}, '/todo?id=1', 400)
-        self.check_post({'adopt': 2}, '/todo?id=1', 404)
 
-    def test_do_POST_todo(self) -> None:
+    def test_basic_POST_todo(self) -> None:
         """Test POST /todo."""
         date = '2024-01-01'
         day_post = {'day_comment': '', 'new_todo': 1, 'make_type': 'full'}
         self.check_json_get('/todo?id=1', expected)
         self.check_post({}, '/todo?id=1')
         self.check_json_get('/todo?id=1', expected)
-        # test posting doneness
-        todo_dict['is_done'] = True
-        self.check_post({'done': ''}, '/todo?id=1')
+        # test posting doneness, comment, calendarization, effort
+        todo_post = {'done': '', 'calendarize': '', 'comment': 'foo',
+                     'effort': 2.3}
+        todo_dict = self.todo_as_dict(
+                1, process_id=1, date=date, is_done=True, calendarize=True,
+                comment='foo', effort=2.3)
+        expected = self.GET_todo_dict(1, [todo_dict], [proc_dict])
+        self.check_post(todo_post, '/todo?id=1')
         self.check_json_get('/todo?id=1', expected)
-        # test implicitly posting non-doneness
+        # test implicitly un-setting all of those except effort by empty post
         self.check_post({}, '/todo?id=1')
-        todo_dict['is_done'] = False
+        todo_dict = self.todo_as_dict(1, process_id=1, date=date, effort=2.3)
+        expected = self.GET_todo_dict(1, [todo_dict], [proc_dict])
+        self.check_json_get('/todo?id=1', expected)
+        # test empty effort post can be explicitly unset by "" post
+        self.check_post({'effort': ''}, '/todo?id=1')
+        todo_dict['effort'] = None
+        self.check_json_get('/todo?id=1', expected)
+        # test failure of deletion on non-existing Todo
+        self.check_post({'delete': ''}, '/todo?id=2', 404, '/')
+        # test deletion of existing Todo
+        self.check_post({'delete': ''}, '/todo?id=1', 302, '/')
+        self.check_get('/todo?id=1', 404)
+        # test deletion of adopted Todo
+        self.check_post(day_post, f'/day?date={date}&make_type=full')
+        self.check_post(day_post, f'/day?date={date}&make_type=full')
+        self.check_post({'adopt': 2}, '/todo?id=1')
+        self.check_post({'delete': ''}, '/todo?id=2', 302, '/')
         self.check_json_get('/todo?id=1', expected)
-        # post new Todo to Day and adopt it
+        # test deletion of adopting Todo
         self.check_post(day_post, f'/day?date={date}&make_type=full')
+        self.check_post({'adopt': 2}, '/todo?id=1')
+        self.check_post({'delete': ''}, '/todo?id=1', 302, '/')
+        todo_dict['id'] = 2
+        expected = self.GET_todo_dict(2, [todo_dict], [proc_dict])
+        self.check_json_get('/todo?id=2', expected)
+
+    def test_POST_todo_adoption(self) -> None:
+        """Test POST /todo."""
+        date = '2024-01-01'
+        # post two Todos to Day, have first adopt second
+        proc_dict = self.proc_as_dict(**self._proc1_form_data)
+        day_post = {'day_comment': '', 'new_todo': 1, 'make_type': 'full'}
+        self.check_post(day_post, f'/day?date={date}&make_type=full')
+        self.check_post(day_post, f'/day?date={date}&make_type=full')
+        todo1_dict = self.todo_as_dict(1, process_id=1, date=date)
+        todo1_dict['children'] = [2]
         todo2_dict = self.todo_as_dict(2, process_id=1, date=date)
+        todo2_dict['parents'] = [1]
+        expected = self.GET_todo_dict(1, [todo1_dict, todo2_dict], [proc_dict])
         expected['todo_candidates'] = [2]
-        assert isinstance(expected['_library'], dict)
-        expected['_library']['Todo']['2'] = todo2_dict
-        expected['_library']['Todo']['2']['parents'] = [1]
-        expected['_library']['Todo']['1']['children'] = [2]
         expected['steps_todo_to_process'] = [{
             'children': [], 'fillable': False,
             'node_id': 1, 'process': None, 'todo': 2}]
         self.check_post({'adopt': 2}, '/todo?id=1')
         self.check_json_get('/todo?id=1', expected)
-        # # test todo1 cannot be set done with todo2 not done yet
+        # test Todo cannot be set done with adopted Todo not done yet
         self.check_post({'adopt': 2, 'done': ''}, '/todo?id=1', 400)
         self.check_json_get('/todo?id=1', expected)
-        # # test todo1 un-adopting todo 2 by just not sending an adopt
+        # test Todo un-adopting by just not sending an adopt
         self.check_post({}, '/todo?id=1')
-        expected['_library']['Todo']['2']['parents'] = []
-        expected['_library']['Todo']['1']['children'] = []
+        todo1_dict['children'] = []
+        todo2_dict['parents'] = []
         expected['steps_todo_to_process'] = []
         self.check_json_get('/todo?id=1', expected)
-        # test todo2 deletion
-        self.check_post({'delete': ''}, '/todo?id=2', 302, '/')
-        del expected['_library']['Todo']['2']
-        expected['todo_candidates'] = []
-        self.check_json_get('/todo?id=1', expected)
+        # test fail on trying to adopt non-existing Todo
+        self.check_post({'adopt': 3}, '/todo?id=1', 404)
+        # test cannot self-adopt
+        self.check_post({'adopt': 1}, '/todo?id=1', 400)
+        # test cannot do 1-step circular adoption
+        self.check_post({'adopt': 1}, '/todo?id=2')
+        self.check_post({'adopt': 2}, '/todo?id=1', 400)
+        # test cannot do 2-step circular adoption
+        day_post = {'day_comment': '', 'new_todo': 1, 'make_type': 'full'}
+        self.check_post(day_post, f'/day?date={date}&make_type=full')
+        self.check_post({'adopt': 2}, '/todo?id=3')
+        self.check_post({'adopt': 3}, '/todo?id=1', 400)
 
     def test_do_GET_todo(self) -> None:
         """Test GET /todo response codes."""
         expected = self.GET_todo_dict(1, [todo1_dict], [proc1_dict,
                                                         proc2_dict])
         self.check_json_get('/todo?id=1', expected)
-        # post new Todo to Day and expect visibility as candidate
-        self.check_post(day_post, f'/day?date={date}&make_type=full')
-        todo2_dict = self.todo_as_dict(2, process_id=1, date=date)
-        assert isinstance(expected['_library'], dict)
-        expected['_library']['Todo']['2'] = todo2_dict
-        expected['todo_candidates'] = [2]
-        self.check_json_get('/todo?id=1', expected)
 
     def test_do_POST_day(self) -> None:
         """Test Todo posting of POST /day."""