fix(web): add repository creation to project settings

- Add repository creation dialog to the project settings repositories tab
- Reuse shared repository API for list/create/delete operations
- Add coverage for the create flow in the settings tab

Quality gates: tsc --noEmit, vitest run src/components/repositories-settings-tab.test.tsx
This commit is contained in:
2026-05-22 18:34:02 +02:00
parent ae377baa74
commit cc1507a33e
2 changed files with 163 additions and 22 deletions
@@ -0,0 +1,59 @@
import { cleanup, fireEvent, render, screen, waitFor } from "@testing-library/react";
import { afterEach, describe, expect, it, vi } from "vitest";
import { RepositoriesSettingsTab } from "./repositories-settings-tab";
import * as gitRepositoriesApi from "../api/git_repositories";
const mockRepositories = [
{
id: "repo-1",
name: "Main Repo",
path: "/repos/main",
project_id: "proj-1",
owner_id: "user-1",
is_mirror: false,
remote_url: null,
last_push: null,
created_at: null,
},
];
vi.mock("react-router-dom", async () => {
const actual = await vi.importActual<typeof import("react-router-dom")>("react-router-dom");
return {
...actual,
useParams: () => ({ projectId: "proj-1" }),
};
});
afterEach(() => {
cleanup();
vi.restoreAllMocks();
});
describe("RepositoriesSettingsTab", () => {
it("opens create dialog and submits a repository", async () => {
const listMock = vi.spyOn(gitRepositoriesApi, "listRepositories").mockResolvedValue(mockRepositories);
const createMock = vi.spyOn(gitRepositoriesApi, "createRepository").mockResolvedValue(mockRepositories[0]);
render(<RepositoriesSettingsTab />);
await waitFor(() => {
expect(screen.getByText("Main Repo")).toBeInTheDocument();
});
fireEvent.click(screen.getByRole("button", { name: /add repository/i }));
fireEvent.change(screen.getByPlaceholderText(/repository-name/i), {
target: { value: "New Repo" },
});
fireEvent.click(screen.getByRole("button", { name: /create/i }));
await waitFor(() => {
expect(createMock).toHaveBeenCalledWith("proj-1", {
name: "New Repo",
remote_url: undefined,
});
});
expect(listMock).toHaveBeenCalledTimes(2);
});
});