feat: set up MSW for Storybook API mocking#930
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: ASSERTIVE Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (10)
📜 Recent review details⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
🧰 Additional context used📓 Path-based instructions (4)**/*.{ts,tsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
web/src/**/*.{ts,tsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
{web/.storybook/main.ts,web/.storybook/preview.tsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
web/**/*.stories.{ts,tsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
🧠 Learnings (21)📓 Common learnings📚 Learning: 2026-03-14T15:43:05.601ZApplied to files:
📚 Learning: 2026-03-30T10:09:41.160ZApplied to files:
📚 Learning: 2026-03-15T18:17:43.675ZApplied to files:
📚 Learning: 2026-03-30T10:09:41.160ZApplied to files:
📚 Learning: 2026-03-30T10:09:41.160ZApplied to files:
📚 Learning: 2026-03-30T10:09:41.160ZApplied to files:
📚 Learning: 2026-03-30T10:09:41.160ZApplied to files:
📚 Learning: 2026-03-30T10:09:41.160ZApplied to files:
📚 Learning: 2026-03-19T07:12:14.508ZApplied to files:
📚 Learning: 2026-03-15T21:20:09.993ZApplied to files:
📚 Learning: 2026-03-14T15:43:05.601ZApplied to files:
📚 Learning: 2026-03-17T22:08:13.456ZApplied to files:
📚 Learning: 2026-03-15T18:17:43.675ZApplied to files:
📚 Learning: 2026-03-21T12:54:22.557ZApplied to files:
📚 Learning: 2026-03-15T18:17:43.675ZApplied to files:
📚 Learning: 2026-03-19T11:19:40.044ZApplied to files:
📚 Learning: 2026-03-30T10:09:41.160ZApplied to files:
📚 Learning: 2026-03-30T10:09:41.160ZApplied to files:
📚 Learning: 2026-03-21T14:12:17.848ZApplied to files:
📚 Learning: 2026-03-15T21:32:02.880ZApplied to files:
🔇 Additional comments (12)
WalkthroughMock Service Worker (MSW) was integrated into the Storybook development environment by installing Suggested labels
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
Code Review
This pull request integrates Mock Service Worker (MSW) into the Storybook environment to provide a standardized way of mocking API responses. Key changes include adding the necessary dependencies, configuring the Storybook preview to use the MSW loader, and refactoring the LoginPage stories to utilize these new handlers instead of manual module patching. Feedback suggests enhancing the mocking utility with an apiError helper for failure scenarios and centralizing API route strings into constants to improve maintainability.
| export function apiSuccess<T>(data: T): ApiResponse<T> { | ||
| return { data, error: null, error_detail: null, success: true } | ||
| } |
There was a problem hiding this comment.
The apiSuccess helper is great for consistency. To make the mocking infrastructure more complete, consider adding a corresponding apiError helper. This would standardize error responses and make it easier to create stories for failure states.
For example:
/** Build a failed ApiResponse envelope for MSW handlers. */
export function apiError<T = never>(error: string, error_detail: string | null): ApiResponse<T> {
return { data: null, error, error_detail, success: false };
}This could then be used in handlers for failure scenarios, like an invalid login attempt.
| /** | ||
| * MSW request handlers for Storybook API mocking. | ||
| * | ||
| * Usage in stories: | ||
| * import { setupStatusComplete } from '@/mocks/handlers' | ||
| * | ||
| * export const MyStory: Story = { | ||
| * parameters: { | ||
| * msw: { handlers: [...setupStatusComplete] }, | ||
| * }, | ||
| * } | ||
| * | ||
| * Each export is an array of RequestHandler objects. Spread them into | ||
| * parameters.msw.handlers -- the mswLoader (configured in preview.tsx) | ||
| * activates them before the story renders and resets between stories. | ||
| * | ||
| * All responses use the ApiResponse<T> envelope via the apiSuccess() helper. | ||
| */ |
There was a problem hiding this comment.
To improve maintainability and prevent potential mismatches between your mocks and the actual API endpoints, it's a good practice to avoid hardcoding URL paths in your handlers (e.g., in auth.ts and setup.ts).
Consider defining API routes as constants in a shared file and importing them into your handlers. This ensures that if an API route changes, you only need to update it in one place, and both your application code and your mocks will stay in sync.
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Snapshot WarningsEnsure that dependencies are being submitted on PR branches. Re-running this action after a short time may resolve the issue. See the documentation for more information and troubleshooting advice. OpenSSF Scorecard
Scanned Files
|
Install msw + msw-storybook-addon and wire initialize()/mswLoader into Storybook preview. Create shared handler infrastructure in web/src/mocks/handlers/ with typed ApiResponse envelope helpers and reusable handlers for setup status and auth endpoints. Migrate LoginPage.stories.tsx from ESM namespace mutation workaround to declarative parameters.msw.handlers, eliminating the AdminCreationGate component and its non-standard module patching. Closes #898 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Pre-reviewed by 3 agents, 3 findings addressed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Exclude mockServiceWorker.js from production build via Vite plugin - Add apiError() helper for failure scenario mocking - Fix imprecise comment about MSW handler reset behavior - Fix misleading comment about MSW bypass mode Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
b1d8641 to
9eb88d7
Compare
🤖 I have created a release *beep* *boop* --- ## [0.5.1](v0.5.0...v0.5.1) (2026-03-30) ### Features * add linear variant to ProgressGauge component ([#927](#927)) ([89bf8d0](89bf8d0)) * frontend security hardening -- ESLint XSS ban + MotionConfig CSP nonce ([#926](#926)) ([6592ed0](6592ed0)) * set up MSW for Storybook API mocking ([#930](#930)) ([214078c](214078c)) ### Refactoring * **web:** replace Sidebar tablet overlay with shared Drawer component ([#928](#928)) ([ad5451d](ad5451d)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
Summary
msw+msw-storybook-addonand wireinitialize()/mswLoaderinto Storybook previewweb/src/mocks/handlers/with typedApiResponse<T>envelope helper and reusable handlers for setup status and auth endpointsLoginPage.stories.tsxfrom ESM namespace mutation workaround to declarativeparameters.msw.handlers, eliminating theAdminCreationGatecomponentTest plan
npm --prefix web run type-checkpassesnpm --prefix web run lintpasses (zero warnings)npm --prefix web run testpasses (2145 tests)npm --prefix web run storybook:buildsucceeds withmockServiceWorker.jsin outputnpm --prefix web run storybook-- verify DefaultLogin shows "Sign In" and AdminCreation shows "Create Admin Account"Review coverage
Pre-reviewed by 3 agents (docs-consistency, frontend-reviewer, issue-resolution-verifier). 3 findings addressed (all docs drift). Frontend code review: clean, no issues.
Closes #898
🤖 Generated with Claude Code