feat: add removable reference feature vertical slice
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { HttpResponse, http } from "msw";
|
||||
import { setupServer } from "msw/node";
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import {
|
||||
afterAll,
|
||||
afterEach,
|
||||
beforeAll,
|
||||
describe,
|
||||
expect,
|
||||
it,
|
||||
vi,
|
||||
} from "vitest";
|
||||
|
||||
import { createRuntimeComposition } from "../../../src/bootstrap/create-runtime-composition.js";
|
||||
import { RuntimeApplication } from "../../../src/bootstrap/runtime-application.jsx";
|
||||
|
||||
const runtimeConfig = {
|
||||
APP_ENV: "local",
|
||||
API_BASE_URL: "https://api.test",
|
||||
REQUEST_TIMEOUT_MS: 10_000,
|
||||
MAX_RETRY_ATTEMPTS: 0,
|
||||
TELEMETRY_ENABLED: false,
|
||||
AUTH_MODE: "demo",
|
||||
CONFIG_SCHEMA_VERSION: "1",
|
||||
API_CONTRACT_VERSION: "1",
|
||||
RELEASE_MANIFEST_URL: "/release-manifest.json",
|
||||
BUILD_ID: "local-build",
|
||||
RELEASE_ID: "local-release",
|
||||
};
|
||||
const releaseManifest = {
|
||||
schemaVersion: 1,
|
||||
appVersion: "0.1.0",
|
||||
buildId: "local-build",
|
||||
commitSha: "local",
|
||||
configSchemaVersion: "1",
|
||||
apiContractVersion: "1",
|
||||
assetManifestHash: "test-hash",
|
||||
releaseId: "local-release",
|
||||
builtAt: "2026-07-26T00:00:00.000Z",
|
||||
routeChunks: {
|
||||
"route-home": "assets/home.js",
|
||||
"route-examples-ui": "assets/ui.js",
|
||||
"route-examples-states": "assets/states.js",
|
||||
"route-examples-auth": "assets/auth.js",
|
||||
"route-reference-resources": "assets/reference.js",
|
||||
"route-not-found": "assets/not-found.js",
|
||||
},
|
||||
};
|
||||
|
||||
const listRequests = vi.fn();
|
||||
const createRequests = vi.fn();
|
||||
const resources = [{ id: "reference-1", name: "Existing" }];
|
||||
const server = setupServer(
|
||||
http.get("http://app.test/config.json", () =>
|
||||
HttpResponse.json(runtimeConfig),
|
||||
),
|
||||
http.get("http://app.test/release-manifest.json", () =>
|
||||
HttpResponse.json(releaseManifest),
|
||||
),
|
||||
http.get("https://api.test/api/reference-resources", ({ request }) => {
|
||||
listRequests(new URL(request.url).search);
|
||||
return HttpResponse.json({
|
||||
success: true,
|
||||
data: resources,
|
||||
meta: { requestId: "request-list", traceId: "trace-list" },
|
||||
});
|
||||
}),
|
||||
http.post("https://api.test/api/reference-resources", async ({ request }) => {
|
||||
const body = (await request.json()) as { name: string };
|
||||
createRequests(body);
|
||||
const created = { id: "reference-created", name: body.name };
|
||||
resources.push(created);
|
||||
return HttpResponse.json({
|
||||
success: true,
|
||||
data: created,
|
||||
meta: { requestId: "request-create", traceId: "trace-create" },
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
beforeAll(() => server.listen({ onUnhandledRequest: "error" }));
|
||||
afterEach(() => {
|
||||
listRequests.mockClear();
|
||||
createRequests.mockClear();
|
||||
resources.splice(1);
|
||||
});
|
||||
afterAll(() => server.close());
|
||||
|
||||
const absoluteFetch: typeof fetch = (input, init) => {
|
||||
if (input instanceof Request) return fetch(input, init);
|
||||
const url = new URL(
|
||||
input instanceof URL ? input.href : input,
|
||||
"http://app.test",
|
||||
);
|
||||
return fetch(url, init);
|
||||
};
|
||||
|
||||
describe("reference feature production vertical path", () => {
|
||||
it("traverses bootstrap, router, application, HTTP schema/mapper and query cache", async () => {
|
||||
const user = userEvent.setup();
|
||||
const composition = await createRuntimeComposition({
|
||||
fetcher: absoluteFetch,
|
||||
host: {},
|
||||
});
|
||||
window.history.pushState(
|
||||
{},
|
||||
"",
|
||||
"/examples/reference-resources?tags=open&tags=new&limit=5",
|
||||
);
|
||||
render(<RuntimeApplication composition={composition} />);
|
||||
|
||||
await user.click(
|
||||
await screen.findByRole("button", { name: "로그인 시작" }),
|
||||
);
|
||||
expect(await screen.findByText("Existing")).toBeVisible();
|
||||
expect(listRequests).toHaveBeenCalledWith(
|
||||
"?limit=5&tags=open&tags=new",
|
||||
);
|
||||
|
||||
await user.type(screen.getByLabelText("새 항목 이름"), " Created ");
|
||||
await user.click(screen.getByRole("button", { name: "추가" }));
|
||||
expect(await screen.findByText("Created")).toBeVisible();
|
||||
expect(createRequests).toHaveBeenCalledWith({ name: "Created" });
|
||||
expect(listRequests.mock.calls.length).toBeGreaterThanOrEqual(2);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user