Files
silo-server/web/src/components/AdminSidebar.test.tsx
T

128 lines
3.3 KiB
TypeScript

import { renderToStaticMarkup } from "react-dom/server";
import { MemoryRouter } from "react-router";
import { describe, expect, it, vi } from "vitest";
import AdminSidebar from "./AdminSidebar";
import type { BuildInfo } from "@/hooks/queries/admin/system";
interface MockBuildInfoResult {
data?: BuildInfo;
isPending: boolean;
isError: boolean;
}
const mockUseServerBranding = vi.fn(() => ({
serverName: "Silo",
loginSubtitle: "Sign in with an existing account.",
}));
const defaultBuildInfo: BuildInfo = {
display: "b4c5aae1+dirty",
revision: "b4c5aae18aa653725ac697b29a05eac797576008",
dirty: true,
vcs_time: "2026-04-05T22:24:40Z",
available: true,
};
const mockUseBuildInfo = vi.fn<() => MockBuildInfoResult>(() => ({
data: defaultBuildInfo,
isPending: false,
isError: false,
}));
const mockUseAdminSessions = vi.fn(() => ({ data: [] }));
const mockUseAdminPluginInstallations = vi.fn(() => ({ data: [] }));
vi.mock("@/hooks/useServerBranding", () => ({
useServerBranding: () => mockUseServerBranding(),
}));
vi.mock("@/hooks/queries/admin/system", () => ({
useBuildInfo: () => mockUseBuildInfo(),
}));
vi.mock("@/hooks/queries/admin/stats", () => ({
useAdminSessions: () => mockUseAdminSessions(),
}));
vi.mock("@/hooks/queries/admin/plugins", () => ({
useAdminPluginInstallations: () => mockUseAdminPluginInstallations(),
}));
function renderSidebar() {
return renderToStaticMarkup(
<MemoryRouter initialEntries={["/admin"]}>
<AdminSidebar />
</MemoryRouter>,
);
}
describe("AdminSidebar", () => {
it("includes a Sections link in the manage navigation", () => {
const markup = renderSidebar();
expect(markup).toContain('href="/admin/sections"');
expect(markup).toContain(">Sections<");
});
it("includes a Maintenance link in the server navigation", () => {
const markup = renderSidebar();
expect(markup).toContain('href="/admin/maintenance"');
expect(markup).toContain(">Maintenance<");
});
it("includes a Recommendations link in the server navigation", () => {
const markup = renderSidebar();
expect(markup).toContain('href="/admin/recommendations"');
expect(markup).toContain(">Recommendations<");
});
it("renders the build identifier in the footer", () => {
const markup = renderSidebar();
expect(markup).toContain(">Build<");
expect(markup).toContain(">b4c5aae1+dirty<");
});
it("renders unavailable when build metadata is missing", () => {
mockUseBuildInfo.mockReturnValueOnce({
data: {
...defaultBuildInfo,
display: "unavailable",
revision: "",
dirty: false,
vcs_time: "",
available: false,
},
isPending: false,
isError: false,
});
const markup = renderSidebar();
expect(markup).toContain(">unavailable<");
});
it("renders load failed when the build info query errors", () => {
mockUseBuildInfo.mockReturnValueOnce({
data: undefined,
isPending: false,
isError: true,
});
const markup = renderSidebar();
expect(markup).toContain(">load failed<");
});
it("renders loading while the build info query is pending", () => {
mockUseBuildInfo.mockReturnValueOnce({
data: undefined,
isPending: true,
isError: false,
});
const markup = renderSidebar();
expect(markup).toContain(">loading...<");
});
});