import { http, HttpResponse } from "msw"; import preview from "../../.storybook/preview.tsx"; import { sleep } from "../sleep.ts"; import type { CurrentUser, SessionInfo } from "../types.ts"; import { CurrentUserFetcher } from "./CurrentUserFetcher.tsx"; function createMocks(options?: { responseSpeed?: number }) { const simulateNetwork = () => sleep(options?.responseSpeed ?? 2000); const john: CurrentUser = { id: "john", email: "john@example.com", isVerified: true, }; const mary: CurrentUser = { id: "mary", email: "mary@example.com", isVerified: true, }; const vernon: CurrentUser = { id: "vernon", email: "vernon@example.com", isVerified: false, }; const sessionInfo: SessionInfo = { createdTs: 123, expiresTs: 123, }; return { data: { john, mary, vernon }, handlers: { refreshTokens: { success: () => { return http.post( "http://mock.api/v1/sessions/access-tokens", async () => { await simulateNetwork(); return HttpResponse.json({ sessionInfo }); }, ); }, failed: () => { return http.post( "http://mock.api/v1/sessions/access-tokens", async () => { await simulateNetwork(); return HttpResponse.text("Refresh token expired or missing", { status: 401, }); }, ); }, }, getCurrentUser: { success: (currentUser: CurrentUser) => { return http.get("http://mock.api/v1/users/me", async () => { await simulateNetwork(); return HttpResponse.json(currentUser); }); }, /** * Cookie is valid, but user doesn't exist any more. This can happen * after user deletion. */ notFound: () => { return http.get("http://mock.api/v1/users/me", async () => { await simulateNetwork(); return HttpResponse.text("User not found", { status: 404 }); }); }, noConnection: () => { return http.get("http://mock.api/v1/users/me", async () => { return HttpResponse.error(); }); }, unknownFailure: () => { return http.get("http://mock.api/v1/users/me", async () => { await simulateNetwork(); return HttpResponse.text("Internal server error", { status: 500 }); }); }, /** * Auth cookies no longer valid to make this request. */ notAuthenticated: () => { return http.get("http://mock.api/v1/users/me", async () => { await simulateNetwork(); return HttpResponse.text("Not authenticated", { status: 401 }); }); }, }, createNewSession: { success: (currentUser: CurrentUser) => { return http.post("http://mock.api/v1/sessions", async () => { await simulateNetwork(); return HttpResponse.json({ currentUser, sessionInfo }); }); }, invalidCredentials: () => { return http.post("http://mock.api/v1/sessions", async () => { await simulateNetwork(); return HttpResponse.text("Credentials do not match", { status: 401, }); }); }, userNotFound: () => { return http.post("http://mock.api/v1/sessions", async () => { await simulateNetwork(); return HttpResponse.text("User not found", { status: 404 }); }); }, unknownFailure: () => { return http.post("http://mock.api/v1/sessions", async () => { await simulateNetwork(); return HttpResponse.text("Internal server error", { status: 500 }); }); }, }, requestVerify: { success: () => { return http.post( "http://mock.api/v1/user-verification-tokens", async () => { await simulateNetwork(); return HttpResponse.json({ message: "OK", tokenId: "1" }); }, ); }, }, verify: { success: () => { return http.put( "http://mock.api/v1/user-verification-tokens/:id", async () => { await simulateNetwork(); return HttpResponse.json({ message: "OK" }); }, ); }, }, }, }; } const { data, handlers } = createMocks({ responseSpeed: 700 }); const meta = preview.meta({ title: "Account/Current User Fetcher", component: CurrentUserFetcher, tags: ["autodocs"], args: { children: (