Files
tech-log-frontend/tests/component/platform-overview-page.test.tsx
T

165 lines
5.7 KiB
TypeScript

// @vitest-environment jsdom
import { render, screen, waitFor, within } from "@testing-library/react";
import { describe, expect, it } from "vitest";
import { SERVER_STATE_PROFILES } from "../../src/contracts/server-state.ts";
import { COMPOSED_CONTRACT_CONTRIBUTIONS } from "../../src/features/installed-contract-contributions.ts";
import { ROUTE_REGISTRY } from "../../src/features/installed-feature-contracts.ts";
import PlatformOverviewPage from "../../src/presentation/examples/platform-overview-page.tsx";
import { LocaleProvider } from "../../src/presentation/i18n/index.ts";
import { ApplicationProvider } from "../../src/presentation/providers/application-provider.tsx";
import { createTestApplication } from "../helpers/create-test-application.ts";
import { createRuntimeCapabilitiesStub } from "../helpers/runtime-capabilities-stub.ts";
/**
* The page must stay a projection of the installed registries. Every assertion
* below derives its expectation from the same registry the page reads, so a
* template that removes its sample feature still satisfies this suite.
*/
function renderPage() {
return render(
<ApplicationProvider application={createTestApplication()}>
<LocaleProvider>
<PlatformOverviewPage />
</LocaleProvider>
</ApplicationProvider>,
);
}
function tableByCaption(caption: string): HTMLElement {
return screen.getByRole("table", { name: caption });
}
/** A metric is a `dt`/`dd` pair, which carries no ARIA role to query by. */
function metricByLabel(scope: HTMLElement, label: string): HTMLElement {
const term = within(scope).getByText(label).closest(".platform-metric");
if (!(term instanceof HTMLElement)) {
throw new Error(`No metric is labelled ${label}`);
}
return term;
}
describe("platform overview page", () => {
it("renders one route row per installed route registry entry", () => {
renderPage();
const table = tableByCaption("설치된 라우트 목록");
const dataRows = within(table).getAllByRole("row").slice(1);
expect(dataRows).toHaveLength(Object.keys(ROUTE_REGISTRY).length);
for (const definition of Object.values(ROUTE_REGISTRY)) {
expect(
within(table).getByText(definition.routeId),
).toBeInTheDocument();
}
});
it("renders one operation row per installed HTTP contract", () => {
const operationIds = [
...COMPOSED_CONTRACT_CONTRIBUTIONS.httpByOperationId.keys(),
];
renderPage();
if (operationIds.length === 0) {
expect(
screen.getByRole("heading", {
name: "설치된 HTTP 오퍼레이션이 없습니다.",
}),
).toBeVisible();
return;
}
const table = tableByCaption("설치된 HTTP 오퍼레이션");
expect(within(table).getAllByRole("row").slice(1)).toHaveLength(
operationIds.length,
);
for (const operationId of operationIds) {
expect(within(table).getByText(operationId)).toBeInTheDocument();
}
});
it("renders every fixed server-state profile with its own budget", () => {
renderPage();
const table = tableByCaption("서버 상태 프로파일");
for (const profile of Object.values(SERVER_STATE_PROFILES)) {
expect(within(table).getByText(profile.profileId)).toBeInTheDocument();
}
expect(within(table).getAllByRole("row").slice(1)).toHaveLength(
Object.keys(SERVER_STATE_PROFILES).length,
);
});
it("labels a capability that was never selected as unselected", () => {
renderPage();
const region = screen.getByRole("region", { name: "선택적 런타임 능력" });
expect(within(region).getAllByText("미선택")).toHaveLength(4);
expect(within(region).queryByText("운영자가 비활성화함")).toBeNull();
});
it("separates an operator disable from a capability that was never selected", () => {
render(
<ApplicationProvider
application={createTestApplication({
runtimeCapabilities: createRuntimeCapabilitiesStub({
SERVICE_WORKER: { selected: 1, active: 0, override: "DISABLED" },
OFFLINE_COMMANDS: { selected: 1, active: 1 },
}),
})}
>
<LocaleProvider>
<PlatformOverviewPage />
</LocaleProvider>
</ApplicationProvider>,
);
const region = screen.getByRole("region", { name: "선택적 런타임 능력" });
expect(within(region).getByText("운영자가 비활성화함")).toBeVisible();
expect(within(region).getByText("활성 (1)")).toBeVisible();
expect(within(region).getAllByText("미선택")).toHaveLength(2);
});
it("counts installed contract packages separately from template fixtures", () => {
const fixtures = COMPOSED_CONTRACT_CONTRIBUTIONS.contributions.filter(
(contribution) => contribution.source.kind === "TEMPLATE_FIXTURE",
).length;
renderPage();
const summary = screen.getByRole("region", { name: "설치 요약" });
const packages = metricByLabel(summary, "외부 계약 패키지");
expect(
within(packages).getByText(
`${COMPOSED_CONTRACT_CONTRIBUTIONS.externalPackages.length}개`,
),
).toBeVisible();
expect(
within(packages).getByText(`템플릿 픽스처 ${fixtures}개`),
).toBeVisible();
expect(
within(metricByLabel(summary, "라우트")).getByText(
`${Object.keys(ROUTE_REGISTRY).length}개`,
),
).toBeVisible();
});
it("renders the verified release identity once the runtime resolves it", async () => {
renderPage();
const region = screen.getByRole("region", { name: "릴리스 신원" });
await waitFor(() =>
expect(
within(metricByLabel(region, "빌드")).getByText("test-build"),
).toBeVisible(),
);
expect(
within(metricByLabel(region, "릴리스")).getByText("test-release"),
).toBeVisible();
});
});