Files
headquarter/apps/api/tests/unit/test_file_service.py
T
Developer c26e9eacfa feat: complete workspace-first-ui cleanup and tests
- Delete dead repo-workspace code: RepoWorkspacePage, useRepoWorkspace,
  WorkspaceLayout, FileBrowser, old git components (git-toolbar, file-editor,
  commit-panel), and repo-workspace.css.
- Fix stale backend test imports for moved models/services.
- Add GitOperations unit tests.
- Add integration tests for workspace files, git, and instances endpoints.
- Add frontend tests for WorkspaceDetailPage and ProjectCard.
- Update OpenSpec workspace-first-ui tasks and mark change completed.
- Regenerate project maps.

Quality gates: npm run typecheck, npm run lint, npm test -- --run (87 passed),
python3 -m py_compile on changed backend files, pytest backend workspace tests.
2026-06-12 17:25:09 +00:00

85 lines
3.1 KiB
Python

"""Unit tests for FileService."""
import os
import tempfile
import pytest
from src.models import Workspace
from src.services.shared.file_service import FileService
@pytest.fixture
def temp_workspace():
"""Create a temporary workspace directory."""
with tempfile.TemporaryDirectory() as tmpdir:
ws = Workspace(
id="00000000-0000-0000-0000-000000000001",
name="test-ws",
repo_id="00000000-0000-0000-0000-000000000002",
user_id="00000000-0000-0000-0000-000000000003",
branch="main",
path=tmpdir,
)
yield ws
class TestFileService:
"""Tests for FileService."""
def test_list_directory_empty(self, temp_workspace: Workspace):
"""Returns empty list for empty directory."""
service = FileService()
entries = service.list_directory(temp_workspace)
assert entries == []
def test_list_directory_with_files(self, temp_workspace: Workspace):
"""Returns entries sorted (dirs first, then files)."""
# Create files and dirs
os.makedirs(os.path.join(temp_workspace.path, "src"))
with open(os.path.join(temp_workspace.path, "README.md"), "w") as f:
f.write("# Test")
with open(os.path.join(temp_workspace.path, "main.py"), "w") as f:
f.write("print('hello')")
service = FileService()
entries = service.list_directory(temp_workspace)
assert len(entries) == 3
assert entries[0].name == "src" and entries[0].type == "directory"
assert entries[1].name == "main.py" and entries[1].type == "file"
assert entries[2].name == "README.md" and entries[2].type == "file"
def test_read_file(self, temp_workspace: Workspace):
"""Reads text file content."""
with open(os.path.join(temp_workspace.path, "test.txt"), "w") as f:
f.write("hello world")
service = FileService()
content = service.read_file(temp_workspace, "test.txt")
assert content == "hello world"
def test_read_binary_file_rejected(self, temp_workspace: Workspace):
"""Rejects binary files."""
with open(os.path.join(temp_workspace.path, "binary.bin"), "wb") as f:
f.write(b"\x00\x01\x02")
service = FileService()
with pytest.raises(ValueError, match="Binary"):
service.read_file(temp_workspace, "binary.bin")
def test_write_file(self, temp_workspace: Workspace):
"""Writes file to workspace."""
service = FileService()
service.write_file(temp_workspace, "nested/file.txt", "content")
assert os.path.exists(os.path.join(temp_workspace.path, "nested", "file.txt"))
with open(os.path.join(temp_workspace.path, "nested", "file.txt")) as f:
assert f.read() == "content"
def test_path_escapes_workspace(self, temp_workspace: Workspace):
"""Rejects paths that escape workspace directory."""
service = FileService()
with pytest.raises(ValueError, match="escapes"):
service.list_directory(temp_workspace, "../outside")