// @vitest-environment jsdom import { render, screen } from "@testing-library/react"; import { describe, expect, it } from "vitest"; import { createAnonymousSessionAdapter } from "../../src/adapters/auth/external-session-adapter.ts"; import { ROUTE_REGISTRY } from "../../src/features/installed-feature-contracts.ts"; import { INSTALLED_PRODUCT_FEATURE_IDS } from "../../src/features/installed-product-manifest.ts"; import { ApplicationProvider } from "../../src/presentation/providers/application-provider.tsx"; import { AppRouter } from "../../src/presentation/routes/app-router.tsx"; import { createTestApplication } from "../helpers/create-test-application.ts"; import { createProductFeaturesStub } from "../helpers/runtime-capabilities-stub.ts"; /** * ยง3.5. The runtime kill switch, exercised through the running app rather than * through the resolver that computes it. * * Withdrawing a feature from navigation is not the same as taking it out of * service: a typed deep link would still mount it. Both halves are asserted * here, on the same render, so the switch cannot be half-wired. */ const FEATURE_ID = INSTALLED_PRODUCT_FEATURE_IDS[0]!; const FEATURE_ROUTE = ROUTE_REGISTRY.REFERENCE_RESOURCE_LIST; function renderAt(path: string, disabled: boolean) { window.history.pushState({}, "", path); return render( , ); } describe("runtime product feature switch", () => { it("advertises the feature's route while the feature is active", async () => { renderAt("/", false); expect( await screen.findByRole("link", { name: FEATURE_ROUTE.navigationLabel! }), ).toBeTruthy(); }); it("withdraws the feature's route from navigation when it is disabled", async () => { renderAt("/", true); // The shell itself still renders: disabling a feature is not an outage. expect(await screen.findByRole("navigation")).toBeTruthy(); expect( screen.queryByRole("link", { name: FEATURE_ROUTE.navigationLabel! }), ).toBeNull(); }); it("takes the feature out of service for a direct deep link", async () => { renderAt(FEATURE_ROUTE.path, true); const surface = await screen.findByText( (_, element) => element?.getAttribute("data-disabled-feature") === FEATURE_ID, {}, { timeout: 5000 }, ); expect(surface).toBeTruthy(); }); it("serves the same deep link while the feature is active", async () => { renderAt(FEATURE_ROUTE.path, false); expect( screen.queryByText( (_, element) => element?.getAttribute("data-disabled-feature") === FEATURE_ID, ), ).toBeNull(); }); });