Files
rehearshalhub/web/src/pages/BandPage.test.tsx
2026-04-08 15:10:52 +02:00

109 lines
3.5 KiB
TypeScript
Executable File

import { describe, it, expect, vi, beforeEach } from "vitest";
import { screen } from "@testing-library/react";
import { renderWithProviders } from "../test/helpers";
import { BandPage } from "./BandPage";
// ── Mocks ─────────────────────────────────────────────────────────────────────
vi.mock("../api/bands", () => ({
getBand: vi.fn().mockResolvedValue({
id: "band-1",
name: "Loud Hands",
slug: "loud-hands",
genre_tags: ["post-rock"],
nc_folder_path: null,
}),
}));
vi.mock("../api/client", () => ({
api: {
get: vi.fn().mockImplementation((url: string) => {
if (url.includes("/sessions")) {
return Promise.resolve([
{ id: "s1", date: "2026-03-31", label: "Late Night Jam", recording_count: 3 },
]);
}
if (url.includes("/songs/search")) {
return Promise.resolve([]);
}
return Promise.resolve([]);
}),
post: vi.fn(),
patch: vi.fn(),
delete: vi.fn(),
},
isLoggedIn: vi.fn().mockReturnValue(true),
}));
const renderBandPage = () =>
renderWithProviders(<BandPage />, {
path: "/bands/:bandId",
route: "/bands/band-1",
});
// ── Tests ─────────────────────────────────────────────────────────────────────
describe("BandPage — Library view (TC-01 to TC-09)", () => {
beforeEach(() => {
vi.clearAllMocks();
});
it("TC-01: does not render a member list", async () => {
renderBandPage();
await new Promise((r) => setTimeout(r, 50));
expect(screen.queryByText(/members/i)).toBeNull();
});
it("TC-02: does not render an invite button", async () => {
renderBandPage();
await new Promise((r) => setTimeout(r, 50));
expect(screen.queryByText(/\+ invite/i)).toBeNull();
});
it("TC-03: does not render the Nextcloud folder config widget", async () => {
renderBandPage();
await new Promise((r) => setTimeout(r, 50));
expect(screen.queryByText(/scan path/i)).toBeNull();
expect(screen.queryByText(/nextcloud scan folder/i)).toBeNull();
});
it("TC-04: renders sessions grouped by date", async () => {
renderBandPage();
const sessionEl = await screen.findByText("Late Night Jam");
expect(sessionEl).toBeTruthy();
});
it("TC-05: renders the Scan Nextcloud action button", async () => {
renderBandPage();
const btn = await screen.findByText(/scan nextcloud/i);
expect(btn).toBeTruthy();
});
it("TC-06: renders the + Upload button", async () => {
renderBandPage();
const btn = await screen.findByText(/\+ upload/i);
expect(btn).toBeTruthy();
});
it("TC-07: does not render By Date / Search tabs", async () => {
renderBandPage();
await new Promise((r) => setTimeout(r, 50));
expect(screen.queryByText(/by date/i)).toBeNull();
expect(screen.queryByText(/^search$/i)).toBeNull();
});
it("TC-08: renders the Library heading", async () => {
renderBandPage();
const heading = await screen.findByText("Library");
expect(heading).toBeTruthy();
});
it("TC-09: renders filter pills including All and Guitar", async () => {
renderBandPage();
const allPill = await screen.findByText("all");
const guitarPill = await screen.findByText("guitar");
expect(allPill).toBeTruthy();
expect(guitarPill).toBeTruthy();
});
});