docs: add naming conventions and structure check script (Task 5.2)
- Add docs/development/naming.md with complete naming convention reference - Add scripts/check-structure.js to verify file sizes (target: ≤300 lines) - Note: 9 files slightly exceed limit (form-heavy tabs, complex hooks, test files, utilities.css) — documented as acceptable deviations Quality gates: tsc (pass), eslint (pass) Refs: repo-restructure Task 5.2
This commit is contained in:
@@ -5,91 +5,143 @@ import type { Project } from "@/types/project";
|
||||
import type { ToolType } from "@/types/tool-type";
|
||||
|
||||
vi.mock("@/api/git_repositories", () => ({
|
||||
listRepositories: vi.fn(),
|
||||
listRepositories: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("@/api/sessions", () => ({
|
||||
createInstance: vi.fn(),
|
||||
startInstance: vi.fn(),
|
||||
createInstance: vi.fn(),
|
||||
startInstance: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("@/api/settings", () => ({
|
||||
updateUserConfig: vi.fn(),
|
||||
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 },
|
||||
{
|
||||
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,
|
||||
},
|
||||
] as Project[];
|
||||
|
||||
const mockToolTypes = [
|
||||
{ id: "t1", name: "vscode", display_name: "VS Code", description: null, category: "editor", interfaces: ["web"], default_port: 8443, definition_type: "compose", compose_template: "", dockerfile_template: null, readiness_probe: null, required_variables: [], is_builtin: true, build_context: null, created_by_id: "u1", created_at: "", updated_at: "" },
|
||||
{ id: "t2", name: "terminal", display_name: "Terminal", description: null, category: "shell", interfaces: ["terminal"], default_port: 22, definition_type: "dockerfile", compose_template: null, dockerfile_template: "", readiness_probe: null, required_variables: [], is_builtin: true, build_context: null, created_by_id: "u1", created_at: "", updated_at: "" },
|
||||
{
|
||||
id: "t1",
|
||||
name: "vscode",
|
||||
display_name: "VS Code",
|
||||
description: null,
|
||||
category: "editor",
|
||||
interfaces: ["web"],
|
||||
default_port: 8443,
|
||||
definition_type: "compose",
|
||||
compose_template: "",
|
||||
dockerfile_template: null,
|
||||
readiness_probe: null,
|
||||
required_variables: [],
|
||||
is_builtin: true,
|
||||
build_context: null,
|
||||
created_by_id: "u1",
|
||||
created_at: "",
|
||||
updated_at: "",
|
||||
},
|
||||
{
|
||||
id: "t2",
|
||||
name: "terminal",
|
||||
display_name: "Terminal",
|
||||
description: null,
|
||||
category: "shell",
|
||||
interfaces: ["terminal"],
|
||||
default_port: 22,
|
||||
definition_type: "dockerfile",
|
||||
compose_template: null,
|
||||
dockerfile_template: "",
|
||||
readiness_probe: null,
|
||||
required_variables: [],
|
||||
is_builtin: true,
|
||||
build_context: null,
|
||||
created_by_id: "u1",
|
||||
created_at: "",
|
||||
updated_at: "",
|
||||
},
|
||||
] as ToolType[];
|
||||
|
||||
describe("CreateSessionForm", () => {
|
||||
it("renders form with create button", () => {
|
||||
render(
|
||||
<CreateSessionForm
|
||||
projects={mockProjects}
|
||||
toolTypes={mockToolTypes}
|
||||
onCreated={vi.fn()}
|
||||
/>
|
||||
);
|
||||
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();
|
||||
});
|
||||
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()}
|
||||
/>
|
||||
);
|
||||
it("shows validation error when fields are missing", async () => {
|
||||
render(
|
||||
<CreateSessionForm
|
||||
projects={mockProjects}
|
||||
toolTypes={mockToolTypes}
|
||||
onCreated={vi.fn()}
|
||||
/>,
|
||||
);
|
||||
|
||||
const { container } = render(
|
||||
<CreateSessionForm
|
||||
projects={mockProjects}
|
||||
toolTypes={mockToolTypes}
|
||||
onCreated={vi.fn()}
|
||||
/>
|
||||
);
|
||||
const { container } = render(
|
||||
<CreateSessionForm
|
||||
projects={mockProjects}
|
||||
toolTypes={mockToolTypes}
|
||||
onCreated={vi.fn()}
|
||||
/>,
|
||||
);
|
||||
|
||||
const submitBtn = container.querySelector('button[type="submit"]') as HTMLButtonElement;
|
||||
fireEvent.click(submitBtn);
|
||||
const submitBtn = container.querySelector(
|
||||
'button[type="submit"]',
|
||||
) as HTMLButtonElement;
|
||||
fireEvent.click(submitBtn);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(
|
||||
screen.getByText(/project, repository, and tool type are required/i)
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(
|
||||
screen.getByText(/project, repository, and tool type are required/i),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
expect(createInstance).not.toHaveBeenCalled();
|
||||
});
|
||||
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" }]);
|
||||
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 { container } = render(
|
||||
<CreateSessionForm
|
||||
projects={mockProjects}
|
||||
toolTypes={mockToolTypes}
|
||||
onCreated={vi.fn()}
|
||||
/>,
|
||||
);
|
||||
|
||||
const projectSelect = container.querySelector("select") as HTMLSelectElement;
|
||||
fireEvent.change(projectSelect, { target: { value: "p1" } });
|
||||
const projectSelect = container.querySelector(
|
||||
"select",
|
||||
) as HTMLSelectElement;
|
||||
fireEvent.change(projectSelect, { target: { value: "p1" } });
|
||||
|
||||
await waitFor(() => {
|
||||
expect(listRepositories).toHaveBeenCalledWith("p1");
|
||||
});
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(listRepositories).toHaveBeenCalledWith("p1");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user