Files
headquarter/apps/api/tests/integration/test_workspace_instances.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

152 lines
4.6 KiB
Python

"""Integration tests for workspace instance endpoints."""
import asyncio
import tempfile
import uuid
from datetime import datetime
from unittest.mock import patch
import pytest
from fastapi.testclient import TestClient
from sqlalchemy.ext.asyncio import AsyncSession
from src.models import GitRepository, Project, ToolInstance, ToolType, Workspace
def _get_user_id(client: TestClient) -> uuid.UUID:
from src.auth.session import decode_session_cookie
from src.config import Settings
settings = Settings()
cookie = client.cookies.get("session")
data = decode_session_cookie(settings=settings, cookie_value=cookie)
if not data:
raise RuntimeError("No session")
return uuid.UUID(data["user_id"])
@pytest.fixture
def test_workspace_with_tool_type(
db_session: AsyncSession, authenticated_client: TestClient
):
"""Create a project, repo, workspace, and tool type."""
user_id = _get_user_id(authenticated_client)
async def _create():
project = Project(name="Instance Test Project", owner_id=user_id)
db_session.add(project)
await db_session.flush()
repo = GitRepository(
name="instance-test-repo",
path="/tmp/instance-test-repo",
remote_url="https://example.com/repo.git",
project_id=project.id,
owner_id=user_id,
)
db_session.add(repo)
await db_session.flush()
tmpdir = tempfile.mkdtemp()
ws = Workspace(
name="dev",
repo_id=repo.id,
user_id=user_id,
branch="main",
path=tmpdir,
)
db_session.add(ws)
await db_session.flush()
tool_type = ToolType(
name="test-tool",
display_name="Test Tool",
default_port=8080,
category="dev",
)
db_session.add(tool_type)
await db_session.commit()
await db_session.refresh(ws)
await db_session.refresh(tool_type)
return ws, tool_type, project
return asyncio.run(_create())
class TestListWorkspaceInstances:
"""Tests for GET /workspaces/{id}/instances."""
def test_list_empty(
self, authenticated_client: TestClient, test_workspace_with_tool_type
):
ws, _, _ = test_workspace_with_tool_type
response = authenticated_client.get(f"/workspaces/{ws.id}/instances")
assert response.status_code == 200
assert response.json() == []
def test_list_instances(
self,
authenticated_client: TestClient,
db_session: AsyncSession,
test_workspace_with_tool_type,
):
ws, tool_type, project = test_workspace_with_tool_type
async def _create_instance():
instance = ToolInstance(
name="test-instance",
display_name="Test Instance",
tool_type_id=tool_type.id,
repository_id=ws.repo_id,
project_id=project.id,
owner_id=ws.user_id,
workspace_id=ws.id,
status="running",
)
db_session.add(instance)
await db_session.commit()
asyncio.run(_create_instance())
response = authenticated_client.get(f"/workspaces/{ws.id}/instances")
assert response.status_code == 200
data = response.json()
assert len(data) == 1
assert data[0]["display_name"] == "Test Instance"
class TestCreateWorkspaceInstance:
"""Tests for POST /workspaces/{id}/instances."""
def test_create_instance(
self,
authenticated_client: TestClient,
test_workspace_with_tool_type,
):
ws, tool_type, project = test_workspace_with_tool_type
mock_instance = ToolInstance(
id=uuid.uuid4(),
name="mock-instance",
display_name="Mock Instance",
tool_type_id=tool_type.id,
repository_id=ws.repo_id,
project_id=project.id,
owner_id=ws.user_id,
workspace_id=ws.id,
status="pending",
created_at=datetime.now(),
)
with patch(
"src.api.workspace.workspace_instances.create_tool_instance",
return_value=mock_instance,
):
response = authenticated_client.post(
f"/workspaces/{ws.id}/instances",
json={"tool_type_id": str(tool_type.id), "display_name": "New Instance"},
)
assert response.status_code == 201
data = response.json()
assert data["display_name"] == "Mock Instance"
assert data["status"] == "pending"