From d971dc6b0ad68ccd982670d3323ea52534c886a9 Mon Sep 17 00:00:00 2001 From: LoopX Agent <337587101+loopx-agent@users.noreply.github.com> Date: Fri, 9 Oct 2026 02:26:14 +0800 Subject: [PATCH] test(chat): align cadence and exact Todo fixtures Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com> --- tests/test_chat_machine_configuration_api.py | 2 +- tests/test_chat_manager_details.py | 39 +++++++++++++++++++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/tests/test_chat_machine_configuration_api.py b/tests/test_chat_machine_configuration_api.py index 1f5b0fd0d5..34b0d877a2 100644 --- a/tests/test_chat_machine_configuration_api.py +++ b/tests/test_chat_machine_configuration_api.py @@ -351,7 +351,7 @@ def test_inspection_lists_registered_namespaces_without_local_refs( } assert namespace_catalog["todo_replan_cadence"]["configuration_template"] == { "schema_version": "todo_replan_cadence_machine_defaults_v1", - "count_unit": "completed_todos", + "count_unit": "effective_turns", "count": 5, } assert namespace_catalog["change_quality_qualification"][ diff --git a/tests/test_chat_manager_details.py b/tests/test_chat_manager_details.py index d3876d619f..e738a618ad 100644 --- a/tests/test_chat_manager_details.py +++ b/tests/test_chat_manager_details.py @@ -1,3 +1,5 @@ +import pytest + import loopx.chat_manager_details as details from loopx.chat_manager import manager_workspace @@ -58,7 +60,18 @@ def test_priority_context_keeps_conditions_and_scoped_decision(monkeypatch, tmp_ 'required_decision_scopes': [{'kind': 'direction', 'granularity': 'action', 'scope_key': 'publish_report'}], 'note': 'Context. ' * 60 + 'Keep this a draft; do not publish.'} - monkeypatch.setattr(details, 'list_goal_todos', lambda **_: {'ok': True, 'todos': [row]}) + selectors = [] + + def read(**kwargs): + assert kwargs['goal_id'] == 'alpha' + selector = kwargs.get('todo_id') + selectors.append(selector) + if selector is None: + return {'ok': True, 'todos': [row]} + assert selector == row['todo_id'] + return {'ok': True, 'todo': row} + + monkeypatch.setattr(details, 'list_goal_todos', read) result = details.read_manager_goal_details(tmp_path/'r', tmp_path, 'alpha', owner_scope=True) overview = result['todos'][0] assert overview['resume_when'] == row['resume_when'] @@ -70,6 +83,30 @@ def test_priority_context_keeps_conditions_and_scoped_decision(monkeypatch, tmp_ owner_scope=True, todo_id='todo_work') assert exact['todos'][0]['continuation'].endswith('Keep this a draft; do not publish.') assert exact['todos'][0]['content_truncated'] is False + assert exact['todos'][0]['resume_when'] == row['resume_when'] + assert exact['todos'][0]['required_decision_scopes'] == row['required_decision_scopes'] + assert selectors == [None, 'todo_work'] + + +@pytest.mark.parametrize('available', [True, False]) +def test_exact_read_distinguishes_missing_from_unavailable(monkeypatch, tmp_path, available): + def read(**kwargs): + assert kwargs['goal_id'] == 'alpha' and kwargs['todo_id'] == 'todo_missing' + if available: + return {'ok': True, 'todo': None, 'not_found': True} + return {'ok': False, 'error': 'private failure body'} + + monkeypatch.setattr(details, 'list_goal_todos', read) + result = details.read_manager_goal_details( + tmp_path/'r', tmp_path, 'alpha', owner_scope=True, todo_id='todo_missing', + ) + assert result['status'] == ('read' if available else 'unavailable') + assert result['todos'] == [] + assert result['coverage'] == ( + {'active': 0, 'included': 0, 'omitted': 0} if available else + {'active': None, 'included': 0, 'omitted': None} + ) + assert 'private failure body' not in str(result) def test_manager_receives_default_operating_instructions_without_overwriting_custom(tmp_path):