// @vitest-environment jsdom import { render, screen, waitFor } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { describe, expect, it } from "vitest"; import { createAnonymousSessionAdapter } from "../../src/adapters/auth/external-session-adapter.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"; function renderRouter() { return render( , ); } describe("generic application router", () => { it("reaches the platform overview from the home starter actions", async () => { const user = userEvent.setup(); window.history.pushState({}, "", "/"); renderRouter(); // The starter action lives inside the lazily loaded home chunk, so this is // the first wait in the file that has to outlast a chunk load rather than // an already-mounted shell element. await user.click( await screen.findByRole( "link", { name: "플랫폼 구성 보기" }, { timeout: 5000 }, ), ); await waitFor(() => expect( screen.getByRole("heading", { name: "플랫폼 구성", level: 1 }), ).toHaveFocus(), ); }); it("renders the app shell and not-found route without a feature input", async () => { window.history.pushState({}, "", "/missing"); renderRouter(); expect( await screen.findByRole("heading", { name: "페이지를 찾을 수 없습니다.", }), ).toBeVisible(); expect(screen.getByRole("navigation", { name: "주요 탐색" })).toBeVisible(); expect(screen.getByRole("main")).toBeVisible(); }); it("navigates between registry-backed platform routes", async () => { const user = userEvent.setup(); window.history.pushState({}, "", "/"); renderRouter(); await user.click( await screen.findByRole("link", { name: "UI 구성요소" }), ); expect( await screen.findByRole("heading", { name: "UI 구성요소", level: 1 }), ).toBeVisible(); expect(window.location.pathname).toBe("/examples/ui"); expect(document.title).toBe("UI 구성요소 · Frontend Skeleton"); await waitFor(() => expect( screen.getByRole("heading", { name: "UI 구성요소", level: 1 }), ).toHaveFocus(), ); }); it("focuses the route heading again when the lazy chunk is already cached", async () => { // §9.7. The first visit resolves the route module asynchronously, so the // router lifecycle and the page header commit separately. A later visit // renders the cached module in the same commit, which is the ordering that // must still hand focus to the heading rather than leaving it on main. const user = userEvent.setup(); window.history.pushState({}, "", "/"); renderRouter(); for (const label of ["UI 구성요소", "화면 상태", "UI 구성요소"]) { await user.click(await screen.findByRole("link", { name: label })); await waitFor(() => expect( screen.getByRole("heading", { name: label, level: 1 }), ).toHaveFocus(), ); } }); });