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.
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
"""Integration tests for workspace git endpoints."""
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
import subprocess
|
||||
import tempfile
|
||||
import uuid
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from src.models import GitRepository, Project, Workspace
|
||||
|
||||
|
||||
def _run_git(*args: str, cwd: str) -> None:
|
||||
subprocess.run(["git", *args], cwd=cwd, check=True, capture_output=True)
|
||||
|
||||
|
||||
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_repo_with_git_workspace(
|
||||
db_session: AsyncSession, authenticated_client: TestClient
|
||||
):
|
||||
"""Create a workspace backed by a real git repo with commits."""
|
||||
user_id = _get_user_id(authenticated_client)
|
||||
|
||||
async def _create():
|
||||
project = Project(name="Git Test Project", owner_id=user_id)
|
||||
db_session.add(project)
|
||||
await db_session.flush()
|
||||
|
||||
repo = GitRepository(
|
||||
name="git-test-repo",
|
||||
path="/tmp/git-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()
|
||||
_run_git("init", cwd=tmpdir)
|
||||
_run_git("config", "user.email", "test@test.com", cwd=tmpdir)
|
||||
_run_git("config", "user.name", "Test User", cwd=tmpdir)
|
||||
with open(os.path.join(tmpdir, "README.md"), "w") as f:
|
||||
f.write("# Test\n")
|
||||
_run_git("add", "README.md", cwd=tmpdir)
|
||||
_run_git("commit", "-m", "Initial commit", cwd=tmpdir)
|
||||
|
||||
ws = Workspace(
|
||||
name="dev",
|
||||
repo_id=repo.id,
|
||||
user_id=user_id,
|
||||
branch="main",
|
||||
path=tmpdir,
|
||||
)
|
||||
db_session.add(ws)
|
||||
await db_session.commit()
|
||||
await db_session.refresh(ws)
|
||||
return ws
|
||||
|
||||
return asyncio.run(_create())
|
||||
|
||||
|
||||
class TestGitStatus:
|
||||
"""Tests for GET /workspaces/{id}/git/status."""
|
||||
|
||||
def test_status_clean(
|
||||
self, authenticated_client: TestClient, test_repo_with_git_workspace: Workspace
|
||||
):
|
||||
response = authenticated_client.get(
|
||||
f"/workspaces/{test_repo_with_git_workspace.id}/git/status"
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["branch"] == "main"
|
||||
assert data["modified"] == []
|
||||
|
||||
def test_status_modified(
|
||||
self, authenticated_client: TestClient, test_repo_with_git_workspace: Workspace
|
||||
):
|
||||
with open(os.path.join(test_repo_with_git_workspace.path, "README.md"), "a") as f:
|
||||
f.write("modified\n")
|
||||
|
||||
response = authenticated_client.get(
|
||||
f"/workspaces/{test_repo_with_git_workspace.id}/git/status"
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert "README.md" in response.json()["modified"]
|
||||
|
||||
|
||||
class TestGitCommit:
|
||||
"""Tests for POST /workspaces/{id}/git/commit."""
|
||||
|
||||
def test_commit(
|
||||
self, authenticated_client: TestClient, test_repo_with_git_workspace: Workspace
|
||||
):
|
||||
with open(os.path.join(test_repo_with_git_workspace.path, "new.py"), "w") as f:
|
||||
f.write("print('hello')\n")
|
||||
|
||||
response = authenticated_client.post(
|
||||
f"/workspaces/{test_repo_with_git_workspace.id}/git/commit",
|
||||
json={"message": "Add new file"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert response.json()["status"] == "committed"
|
||||
|
||||
def test_commit_missing_message(
|
||||
self, authenticated_client: TestClient, test_repo_with_git_workspace: Workspace
|
||||
):
|
||||
response = authenticated_client.post(
|
||||
f"/workspaces/{test_repo_with_git_workspace.id}/git/commit",
|
||||
json={},
|
||||
)
|
||||
assert response.status_code == 400
|
||||
|
||||
|
||||
class TestGitHistory:
|
||||
"""Tests for GET /workspaces/{id}/git/history."""
|
||||
|
||||
def test_history(
|
||||
self, authenticated_client: TestClient, test_repo_with_git_workspace: Workspace
|
||||
):
|
||||
response = authenticated_client.get(
|
||||
f"/workspaces/{test_repo_with_git_workspace.id}/git/history"
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert len(data["commits"]) >= 1
|
||||
assert data["commits"][0]["message"] == "Initial commit"
|
||||
|
||||
|
||||
class TestGitCheckout:
|
||||
"""Tests for POST /workspaces/{id}/git/checkout."""
|
||||
|
||||
def test_checkout(
|
||||
self, authenticated_client: TestClient, test_repo_with_git_workspace: Workspace
|
||||
):
|
||||
_run_git("checkout", "-b", "feature", cwd=test_repo_with_git_workspace.path)
|
||||
_run_git("checkout", "main", cwd=test_repo_with_git_workspace.path)
|
||||
|
||||
response = authenticated_client.post(
|
||||
f"/workspaces/{test_repo_with_git_workspace.id}/git/checkout",
|
||||
json={"branch": "feature"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert response.json()["branch"] == "feature"
|
||||
Reference in New Issue
Block a user