165 lines
5.7 KiB
TypeScript
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();
|
|
});
|
|
});
|