@@ -457,3 +457,74 @@ async def test_list_kbs_empty(self, tmp_db):
457457 app = await create_app (db_path = tmp_db , anthropic_client = mock_client , embeddings = _mock_embedding_engine ())
458458 result = await app .list_knowledge_bases ()
459459 assert "No knowledge bases" in result
460+
461+
462+ class TestTaskStateMachineTools :
463+ @pytest .mark .asyncio
464+ async def test_create_and_get_task (self , tmp_db ):
465+ mock_client = MagicMock ()
466+ app = await create_app (db_path = tmp_db , anthropic_client = mock_client , embeddings = _mock_embedding_engine ())
467+
468+ created = json .loads (await app .create_task (title = "index docs" , owner = "agent-1" ))
469+ assert created ["title" ] == "index docs"
470+ assert created ["owner" ] == "agent-1"
471+ assert created ["status" ] == "todo"
472+
473+ fetched = json .loads (await app .get_task (created ["task_id" ]))
474+ assert fetched ["task_id" ] == created ["task_id" ]
475+ assert fetched ["version" ] == 0
476+
477+ @pytest .mark .asyncio
478+ async def test_assign_and_release_task_locks (self , tmp_db ):
479+ mock_client = MagicMock ()
480+ app = await create_app (db_path = tmp_db , anthropic_client = mock_client , embeddings = _mock_embedding_engine ())
481+
482+ task_a = json .loads (await app .create_task (title = "task-a" ))
483+ task_b = json .loads (await app .create_task (title = "task-b" ))
484+
485+ assigned = json .loads (await app .assign_task_locks (task_a ["task_id" ], ["src/a.py" ]))
486+ assert assigned ["count" ] == 1
487+
488+ released = json .loads (await app .release_task_locks (task_a ["task_id" ]))
489+ assert released ["released" ] == 1
490+
491+ assigned_b = json .loads (await app .assign_task_locks (task_b ["task_id" ], ["src/a.py" ]))
492+ assert assigned_b ["count" ] == 1
493+
494+ @pytest .mark .asyncio
495+ async def test_transition_task (self , tmp_db ):
496+ mock_client = MagicMock ()
497+ app = await create_app (db_path = tmp_db , anthropic_client = mock_client , embeddings = _mock_embedding_engine ())
498+
499+ created = json .loads (await app .create_task (title = "transition" ))
500+ transitioned = json .loads (
501+ await app .transition_task (
502+ task_id = created ["task_id" ],
503+ from_state = "todo" ,
504+ to_state = "in_progress" ,
505+ actor = "orchestrator" ,
506+ expected_version = 0 ,
507+ )
508+ )
509+ assert transitioned ["task" ]["status" ] == "in_progress"
510+ assert transitioned ["task" ]["version" ] == 1
511+
512+ @pytest .mark .asyncio
513+ async def test_append_and_list_task_events (self , tmp_db ):
514+ mock_client = MagicMock ()
515+ app = await create_app (db_path = tmp_db , anthropic_client = mock_client , embeddings = _mock_embedding_engine ())
516+
517+ created = json .loads (await app .create_task (title = "events" ))
518+ event = json .loads (
519+ await app .append_task_event (
520+ task_id = created ["task_id" ],
521+ event_type = "worklog" ,
522+ actor = "agent-1" ,
523+ payload_json = json .dumps ({"action" : "start" }),
524+ )
525+ )
526+ assert event ["event_type" ] == "worklog"
527+
528+ events = json .loads (await app .list_task_events (task_id = created ["task_id" ], limit = 10 ))
529+ assert len (events ) >= 1
530+ assert events [0 ]["task_id" ] == created ["task_id" ]
0 commit comments