refactor: extract dashboard, workspace, tool-types, and tool-configs components (Task 4.3)
- Extract DashboardSummary, ActiveSessionsList, ProjectsSection, QuickCreateForm, RecentSessionsSection from dashboard.tsx (480 → 110 lines) - Extract WorkspaceSidebar from repo-workspace.tsx - Extract ToolTypeList + ToolTypeForm from tool-types.tsx (409 → 135 lines) - Extract ToolConfigList + ToolConfigForm from tool-configs.tsx (391 → 178 lines) - Add use-dashboard-actions hook for shared dashboard action handlers - Update feature barrels with new exports Quality gates: tsc (pass), eslint (pass) Refs: repo-restructure Task 4.3
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
|
||||
import { describe, it, expect, vi } from "vitest";
|
||||
import { CreateSessionForm } from "./CreateSessionForm";
|
||||
|
||||
vi.mock("@/api/git_repositories", () => ({
|
||||
listRepositories: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("@/api/sessions", () => ({
|
||||
createInstance: vi.fn(),
|
||||
startInstance: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("@/api/settings", () => ({
|
||||
updateUserConfig: vi.fn(),
|
||||
}));
|
||||
|
||||
import { listRepositories } from "@/api/git_repositories";
|
||||
import { createInstance } from "@/api/sessions";
|
||||
|
||||
const mockProjects = [
|
||||
{ id: "p1", name: "Project One", description: null, owner_id: "u1", default_ssh_key_id: null },
|
||||
{ id: "p2", name: "Project Two", description: null, owner_id: "u1", default_ssh_key_id: null },
|
||||
];
|
||||
|
||||
const mockToolTypes = [
|
||||
{ id: "t1", name: "vscode", display_name: "VS Code", description: null, category: "editor", interfaces: ["web"] as string[], default_port: 8443, definition_type: "compose" as const, compose_template: "", dockerfile_template: null, readiness_probe: null, required_variables: [], is_builtin: true },
|
||||
{ id: "t2", name: "terminal", display_name: "Terminal", description: null, category: "shell", interfaces: ["terminal"] as string[], default_port: 22, definition_type: "dockerfile" as const, compose_template: null, dockerfile_template: "", readiness_probe: null, required_variables: [], is_builtin: true },
|
||||
];
|
||||
|
||||
describe("CreateSessionForm", () => {
|
||||
it("renders form with create button", () => {
|
||||
render(
|
||||
<CreateSessionForm
|
||||
projects={mockProjects}
|
||||
toolTypes={mockToolTypes}
|
||||
onCreated={vi.fn()}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(screen.getByText("Create New Session")).toBeInTheDocument();
|
||||
expect(screen.getByText("Create Session")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows validation error when fields are missing", async () => {
|
||||
render(
|
||||
<CreateSessionForm
|
||||
projects={mockProjects}
|
||||
toolTypes={mockToolTypes}
|
||||
onCreated={vi.fn()}
|
||||
/>
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByText("Create Session"));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(
|
||||
screen.getByText(/project, repository, and tool type are required/i)
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
expect(createInstance).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("loads repositories when project selected", async () => {
|
||||
const mockedList = listRepositories as ReturnType<typeof vi.fn>;
|
||||
mockedList.mockResolvedValueOnce([{ id: "r1", name: "repo-one" }]);
|
||||
|
||||
const { container } = render(
|
||||
<CreateSessionForm
|
||||
projects={mockProjects}
|
||||
toolTypes={mockToolTypes}
|
||||
onCreated={vi.fn()}
|
||||
/>
|
||||
);
|
||||
|
||||
const projectSelect = container.querySelector("select") as HTMLSelectElement;
|
||||
fireEvent.change(projectSelect, { target: { value: "p1" } });
|
||||
|
||||
await waitFor(() => {
|
||||
expect(listRepositories).toHaveBeenCalledWith("p1");
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user