6ecb31ea0a
Stale project state from prior live_gui tests (shared session-scoped subprocess) was leaking into subsequent tests, causing the test_full_live_workflow race condition: 'Project not switched' errors when self.project still claimed to be a different project. The fix: _handle_reset_session now mirrors the default-project branch of __init__ (lines 1743-1745), creating a fresh default project dict, clearing active_project_path and project_paths, and reinitializing the workspace manager. - src/app_controller.py: 6 new lines in _handle_reset_session - tests/test_handle_reset_session_clears_project.py: 3 tests (active_project_path, project_paths, self.project)
68 lines
2.7 KiB
Python
68 lines
2.7 KiB
Python
"""Red-phase test: _handle_reset_session must clear project state.
|
|
|
|
Background: the live_gui session-scoped fixture is shared across all 48 live
|
|
tests. Prior tests can leave stale `self.project`, `self.active_project_path`,
|
|
and `self.project_paths` on the controller, which leaks into
|
|
`test_full_live_workflow` and causes it to fail with "Project not switched".
|
|
|
|
The fix: `_handle_reset_session` should reset all three fields to a clean
|
|
default (matching what `__init__` does for an empty/unset project).
|
|
|
|
This test uses a real AppController() (per the test_view_presets pattern),
|
|
pollutes the state, then calls _handle_reset_session and asserts.
|
|
"""
|
|
import pytest
|
|
|
|
from src.app_controller import AppController
|
|
from src import project_manager
|
|
|
|
|
|
@pytest.fixture
|
|
def controller(tmp_path):
|
|
"""Build a real AppController with stale project state."""
|
|
proj_path = tmp_path / "stale_project.toml"
|
|
proj_path.write_text("[project]\nname = 'StaleProject'\n")
|
|
ctrl = AppController()
|
|
# Pollute with stale state mimicking what a prior live_gui test leaves behind
|
|
ctrl.project = {
|
|
"project": {"name": "StaleProject", "active_discussion": "main"},
|
|
"files": {"paths": [str(proj_path)]},
|
|
"discussion": {"discussions": {"main": {"history": ["stale msg"]}}},
|
|
}
|
|
ctrl.active_project_path = str(proj_path)
|
|
ctrl.project_paths = [str(proj_path)]
|
|
yield ctrl
|
|
|
|
|
|
def test_handle_reset_session_clears_active_project_path(controller):
|
|
"""Active project path must be cleared or reset to a default."""
|
|
assert controller.active_project_path.endswith("stale_project.toml") # precondition
|
|
controller._handle_reset_session()
|
|
assert not controller.active_project_path.endswith("stale_project.toml"), (
|
|
f"_handle_reset_session did not clear active_project_path "
|
|
f"(still {controller.active_project_path!r})"
|
|
)
|
|
|
|
|
|
def test_handle_reset_session_clears_project_paths(controller):
|
|
"""project_paths list must be cleared (or reset to defaults)."""
|
|
assert len(controller.project_paths) == 1 # precondition
|
|
controller._handle_reset_session()
|
|
assert controller.project_paths != [str(controller.active_project_path)], (
|
|
f"_handle_reset_session did not clear project_paths "
|
|
f"(still {controller.project_paths!r})"
|
|
)
|
|
|
|
|
|
def test_handle_reset_session_resets_project_to_valid_default(controller):
|
|
"""self.project must be a valid (non-stale) project dict after reset."""
|
|
assert controller.project["project"]["name"] == "StaleProject" # precondition
|
|
controller._handle_reset_session()
|
|
name = controller.project.get("project", {}).get("name", "")
|
|
assert name != "StaleProject", (
|
|
f"_handle_reset_session did not reset self.project (still {name!r})"
|
|
)
|
|
# And it must still be a usable project dict
|
|
assert isinstance(controller.project, dict)
|
|
assert "project" in controller.project
|