From f79659074619475b3b0268ec2b685d3a4fac6c40 Mon Sep 17 00:00:00 2001 From: Felix Martin Date: Wed, 10 Jun 2026 21:01:54 -0400 Subject: [PATCH] test: use real directories in TUI/integration project tests ProjectService now rejects non-existent paths (path-validation feature), so the TUI and integration tests must seed projects with real tmp_path dirs. Completes the path-validation test updates beyond test_services.py. Co-Authored-By: Claude Opus 4.8 --- tests/test_integration.py | 4 +-- tests/test_tui.py | 63 ++++++++++++++++++++++++++++----------- 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/tests/test_integration.py b/tests/test_integration.py index fbbfa00..2a8c8fd 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -43,11 +43,11 @@ def setup(): @pytest.mark.asyncio -async def test_full_lifecycle(setup): +async def test_full_lifecycle(setup, tmp_path): proj_svc, sess_svc, tmux = setup # Create project - project = proj_svc.create(name="test-proj", path="/tmp/test-proj") + project = proj_svc.create(name="test-proj", path=str(tmp_path)) assert project.id == 1 # Create session diff --git a/tests/test_tui.py b/tests/test_tui.py index eaa972f..977678c 100644 --- a/tests/test_tui.py +++ b/tests/test_tui.py @@ -619,12 +619,12 @@ async def test_project_form_add_mode_defaults_name_to_basename(): @pytest.mark.asyncio -async def test_project_list_get_selected_project_id(): +async def test_project_list_get_selected_project_id(tmp_path): app = HqtApp() async with app.run_test(size=(120, 40)) as pilot: from hqt.tui.widgets.project_list import ProjectList - p = app._project_service.create("selproj", "/tmp/selproj") + p = app._project_service.create("selproj", str(tmp_path)) app._load_projects() await app.workers.wait_for_complete() await pilot.pause() @@ -669,14 +669,22 @@ async def test_edit_project_no_selection_warns(): @pytest.mark.asyncio -async def test_edit_project_opens_prefilled_form_and_updates(): +async def test_edit_project_opens_prefilled_form_and_updates(tmp_path): app = HqtApp() async with app.run_test(size=(120, 40)) as pilot: + from pathlib import Path from textual.widgets import Input from hqt.tui.screens.project_form import ProjectFormScreen from hqt.tui.widgets.project_list import ProjectList - p = app._project_service.create("oldname", "/tmp/oldpath") + old_dir = tmp_path / "oldpath" + old_dir.mkdir() + new_dir = tmp_path / "newpath" + new_dir.mkdir() + old_path = str(old_dir) + new_path = str(new_dir) + + p = app._project_service.create("oldname", old_path) app._load_projects() await app.workers.wait_for_complete() await pilot.pause() @@ -692,25 +700,35 @@ async def test_edit_project_opens_prefilled_form_and_updates(): assert isinstance(app.screen, ProjectFormScreen) assert app.screen.query_one("#name-input", Input).value == "oldname" - assert app.screen.query_one("#path-input", Input).value == "/tmp/oldpath" + assert app.screen.query_one("#path-input", Input).value == str( + Path(old_path).resolve() + ) - app.screen.dismiss(("newname", "/tmp/newpath")) + app.screen.dismiss(("newname", new_path)) await pilot.pause() refreshed = app._project_service.get(p.id) assert refreshed.name == "newname" - assert refreshed.path == "/tmp/newpath" + assert refreshed.path == str(Path(new_path).resolve()) @pytest.mark.asyncio -async def test_edit_project_duplicate_path_notifies_error(): +async def test_edit_project_duplicate_path_notifies_error(tmp_path): app = HqtApp() async with app.run_test(size=(120, 40)) as pilot: + from pathlib import Path from unittest.mock import patch from hqt.tui.widgets.project_list import ProjectList - app._project_service.create("first", "/tmp/first") - p2 = app._project_service.create("second", "/tmp/second") + first_dir = tmp_path / "first" + first_dir.mkdir() + second_dir = tmp_path / "second" + second_dir.mkdir() + first_path = str(first_dir) + second_path = str(second_dir) + + app._project_service.create("first", first_path) + p2 = app._project_service.create("second", second_path) app._load_projects() await app.workers.wait_for_complete() await pilot.pause() @@ -729,7 +747,8 @@ async def test_edit_project_duplicate_path_notifies_error(): ): await app.run_action("edit_project") await pilot.pause() - app.screen.dismiss(("second", "/tmp/first")) + # Move "second" onto "first"'s path to trigger the duplicate error. + app.screen.dismiss(("second", first_path)) await pilot.pause() assert any( @@ -737,7 +756,7 @@ async def test_edit_project_duplicate_path_notifies_error(): for msg, kw in notify_calls ), f"Expected duplicate-path error notification, got: {notify_calls}" # DB unchanged - assert app._project_service.get(p2.id).path == "/tmp/second" + assert app._project_service.get(p2.id).path == str(Path(second_path).resolve()) # --------------------------------------------------------------------------- @@ -882,14 +901,18 @@ async def test_dialog_button_focus_is_visibly_highlighted(): @pytest.mark.asyncio -async def test_first_project_selected_on_load(): +async def test_first_project_selected_on_load(tmp_path): """If a project exists, the first is selected on load with no key press.""" app = HqtApp() async with app.run_test(size=(120, 40)) as pilot: from hqt.tui.widgets.project_list import ProjectList - app._project_service.create("p1", "/tmp/p1-auto") - app._project_service.create("p2", "/tmp/p2-auto") + d1 = tmp_path / "p1-auto" + d1.mkdir() + d2 = tmp_path / "p2-auto" + d2.mkdir() + app._project_service.create("p1", str(d1)) + app._project_service.create("p2", str(d2)) app._load_projects() await app.workers.wait_for_complete() await pilot.pause() @@ -1152,14 +1175,18 @@ async def test_rename_session_opens_prefilled_and_updates(): @pytest.mark.asyncio -async def test_project_list_jk_navigation(): +async def test_project_list_jk_navigation(tmp_path): """j/k move the highlight down/up in the project list like the arrow keys.""" app = HqtApp() async with app.run_test(size=(120, 40)) as pilot: from hqt.tui.widgets.project_list import ProjectList - p1 = app._project_service.create("first", "/tmp/jk-first") - p2 = app._project_service.create("second", "/tmp/jk-second") + d1 = tmp_path / "jk-first" + d1.mkdir() + d2 = tmp_path / "jk-second" + d2.mkdir() + p1 = app._project_service.create("first", str(d1)) + p2 = app._project_service.create("second", str(d2)) app._load_projects() await app.workers.wait_for_complete() await pilot.pause()