import { http, HttpResponse } from "msw"; import { createMockStudioGateway } from "../../../src/features/tech-log/adapters/mock/mock-studio-gateway.ts"; import { isStudioGatewayError } from "../../../src/features/tech-log/application/ports/studio-gateway-error.ts"; const BASE = "http://api.test"; function problemResponse(error: unknown) { if (isStudioGatewayError(error)) { return HttpResponse.json(error.problem, { status: error.status, headers: { "content-type": "application/problem+json" }, }); } throw error; } async function json(work: () => Promise, status = 200) { try { return HttpResponse.json((await work()) as never, { status }); } catch (error) { return problemResponse(error); } } export function createTechLogStudioHandlers( gateway = createMockStudioGateway(), baseUrl = BASE, ) { const key = (request: Request) => request.headers.get("Idempotency-Key") ?? "missing-key"; return { gateway, handlers: [ http.get(`${baseUrl}/api/v1/studio/session`, () => HttpResponse.json({ authenticated: true, displayName: "테스트 편집자", roles: ["STUDIO_EDITOR"], csrfToken: "csrf-test-token", csrfHeaderName: "X-CSRF-TOKEN", }), ), http.get(`${baseUrl}/api/v1/studio/dashboard`, () => json(() => gateway.getDashboard()), ), http.get(`${baseUrl}/api/v1/studio/documents`, ({ request }) => { const url = new URL(request.url); const limit = url.searchParams.get("limit"); return json(() => gateway.listDocuments({ ...(url.searchParams.get("q") ? { q: url.searchParams.get("q")! } : {}), ...(limit ? { limit: Number(limit) } : {}), } as never), ); }), http.post(`${baseUrl}/api/v1/studio/documents`, async ({ request }) => json( async () => gateway.createDocument((await request.json()) as never, { idempotencyKey: key(request), }), 201, ), ), http.get(`${baseUrl}/api/v1/studio/documents/:documentId`, ({ params }) => json(() => gateway.getDocument(String(params.documentId))), ), http.put( `${baseUrl}/api/v1/studio/documents/:documentId`, async ({ request, params }) => json(async () => gateway.saveDocument( String(params.documentId), (await request.json()) as never, { idempotencyKey: key(request) }, ), ), ), http.post( `${baseUrl}/api/v1/studio/documents/:documentId/validate`, async ({ request, params }) => json(async () => gateway.validateDocument( String(params.documentId), (await request.json()) as never, { idempotencyKey: key(request) }, ), ), ), http.get( `${baseUrl}/api/v1/studio/documents/:documentId/preview`, ({ params }) => json(() => gateway.getCurrentPreview(String(params.documentId))), ), http.post( `${baseUrl}/api/v1/studio/documents/:documentId/preview`, async ({ request, params }) => json( async () => gateway.createPreview( String(params.documentId), (await request.json()) as never, { idempotencyKey: key(request) }, ), 201, ), ), http.post( `${baseUrl}/api/v1/studio/documents/:documentId/publish`, async ({ request, params }) => json(async () => gateway.publishDocument( String(params.documentId), (await request.json()) as never, { idempotencyKey: key(request) }, ), ), ), http.get(`${baseUrl}/api/v1/studio/publications`, () => json(() => gateway.listPublications({})), ), http.post( `${baseUrl}/api/v1/studio/publications/:publicationId/unpublish`, async ({ request, params }) => json(async () => gateway.unpublishPublication( String(params.publicationId), (await request.json()) as never, { idempotencyKey: key(request) }, ), ), ), http.get( `${baseUrl}/api/v1/studio/publications/:publicationEventId/preview`, ({ params }) => json(() => gateway.getPublicationSnapshot(String(params.publicationEventId))), ), http.get(`${baseUrl}/api/v1/studio/catalog`, ({ request }) => { const url = new URL(request.url); return json(() => gateway.getCatalog({ type: url.searchParams.get("type") as never }), ); }), ], }; }