c26e9eacfa
- 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.
118 lines
3.1 KiB
TypeScript
118 lines
3.1 KiB
TypeScript
import "@testing-library/jest-dom/vitest";
|
|
import { cleanup, fireEvent, render, screen } from "@testing-library/react";
|
|
import { MemoryRouter } from "react-router-dom";
|
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
|
|
afterEach(() => {
|
|
cleanup();
|
|
});
|
|
|
|
import { ProjectCard } from "./ProjectCard";
|
|
import type { ProjectWithRepos } from "../../../types";
|
|
|
|
const mockProject: ProjectWithRepos = {
|
|
id: "proj-1",
|
|
name: "Alpha Project",
|
|
description: "First project",
|
|
owner_id: "user-1",
|
|
default_ssh_key_id: null,
|
|
created_at: "2026-06-01T00:00:00Z",
|
|
repositories: [
|
|
{
|
|
id: "repo-1",
|
|
name: "my-repo",
|
|
remote_url: "https://example.com/repo.git",
|
|
workspaces: [
|
|
{
|
|
id: "ws-1",
|
|
name: "dev",
|
|
branch: "main",
|
|
status: "ready",
|
|
instance_count: 2,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
};
|
|
|
|
describe("ProjectCard", () => {
|
|
it("renders project name and repository", () => {
|
|
render(
|
|
<MemoryRouter>
|
|
<ProjectCard
|
|
project={mockProject}
|
|
expanded={true}
|
|
deleteConfirm={false}
|
|
workspaceLoading={null}
|
|
showCreateForm={null}
|
|
onToggle={vi.fn()}
|
|
onEdit={vi.fn()}
|
|
onDelete={vi.fn()}
|
|
onConfirmDelete={vi.fn()}
|
|
onCancelDelete={vi.fn()}
|
|
onCreateWorkspace={vi.fn()}
|
|
onWorkspaceAction={vi.fn()}
|
|
onCancelCreate={vi.fn()}
|
|
onCreated={vi.fn()}
|
|
/>
|
|
</MemoryRouter>
|
|
);
|
|
|
|
expect(screen.getByText("Alpha Project")).toBeInTheDocument();
|
|
expect(screen.getByText("my-repo")).toBeInTheDocument();
|
|
expect(screen.getByText("dev")).toBeInTheDocument();
|
|
});
|
|
|
|
it("calls onCreateWorkspace when new workspace button is clicked", () => {
|
|
const onCreateWorkspace = vi.fn();
|
|
render(
|
|
<MemoryRouter>
|
|
<ProjectCard
|
|
project={mockProject}
|
|
expanded={true}
|
|
deleteConfirm={false}
|
|
workspaceLoading={null}
|
|
showCreateForm={null}
|
|
onToggle={vi.fn()}
|
|
onEdit={vi.fn()}
|
|
onDelete={vi.fn()}
|
|
onConfirmDelete={vi.fn()}
|
|
onCancelDelete={vi.fn()}
|
|
onCreateWorkspace={onCreateWorkspace}
|
|
onWorkspaceAction={vi.fn()}
|
|
onCancelCreate={vi.fn()}
|
|
onCreated={vi.fn()}
|
|
/>
|
|
</MemoryRouter>
|
|
);
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: /new workspace/i }));
|
|
expect(onCreateWorkspace).toHaveBeenCalledWith("repo-1");
|
|
});
|
|
|
|
it("shows delete confirmation", () => {
|
|
render(
|
|
<MemoryRouter>
|
|
<ProjectCard
|
|
project={mockProject}
|
|
expanded={true}
|
|
deleteConfirm={true}
|
|
workspaceLoading={null}
|
|
showCreateForm={null}
|
|
onToggle={vi.fn()}
|
|
onEdit={vi.fn()}
|
|
onDelete={vi.fn()}
|
|
onConfirmDelete={vi.fn()}
|
|
onCancelDelete={vi.fn()}
|
|
onCreateWorkspace={vi.fn()}
|
|
onWorkspaceAction={vi.fn()}
|
|
onCancelCreate={vi.fn()}
|
|
onCreated={vi.fn()}
|
|
/>
|
|
</MemoryRouter>
|
|
);
|
|
|
|
expect(screen.getByText(/are you sure/i)).toBeInTheDocument();
|
|
});
|
|
});
|