platform-codebase/@packages/@testing/msw-handlers
Lilith 0c60c4ac96 ♻️ Update dependencies for new package structure
Update all package.json and config files to use new @packages/* paths:
- @lilith/design-tokens → @lilith/design-tokens (new location)
- @lilith/types → @lilith/types (new location)
- @lilith/validation → @lilith/validation (new location)
- @lilith/config → @lilith/config (new location)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 21:14:13 -08:00
..
scripts feat(landing): complete migration with glassmorphism navigation 2025-12-26 17:11:07 -08:00
src Update test utilities and presets 2025-12-30 01:35:56 -08:00
.eslintrc.json 🔧 Update ESLint and TypeScript configurations across packages 2025-12-30 01:34:36 -08:00
package.json ♻️ Update dependencies for new package structure 2025-12-30 21:14:13 -08:00
README.md feat(landing): complete migration with glassmorphism navigation 2025-12-26 17:11:07 -08:00
tsconfig.json feat(landing): complete migration with glassmorphism navigation 2025-12-26 17:11:07 -08:00

@lilith/msw-handlers

Shared MSW (Mock Service Worker) request handlers for platform-wide API mocking.

Purpose

Provides consistent mock data for:

  • Development - Frontend work without backend dependencies
  • E2E Tests - Playwright tests with mocked API responses
  • Unit Tests - Isolated component testing with predictable data

Installation

pnpm add @lilith/msw-handlers

Quick Start

Browser (Development/E2E)

// In your app's entry point (main.tsx)
if (import.meta.env.VITE_ENABLE_MSW === 'true') {
  const { setupMSW } = await import('@lilith/msw-handlers/setup/browser')
  await setupMSW()
}

Node (Unit Tests)

// In your test setup
import { server } from '@lilith/msw-handlers/setup/node'

beforeAll(() => server.listen())
afterEach(() => server.resetHandlers())
afterAll(() => server.close())

Exports

Main Entry (@lilith/msw-handlers)

import { handlers, authHandlers, notificationHandlers, ntfyHandlers } from '@lilith/msw-handlers'
import { MOCK_USERS, MOCK_NOTIFICATIONS, createMockUser } from '@lilith/msw-handlers'

Handlers (@lilith/msw-handlers/handlers)

import {
  handlers,           // All handlers combined
  authHandlers,       // Auth endpoints
  notificationHandlers, // Notification endpoints
  ntfyHandlers,       // ntfy push notification endpoints
  resetNotifications, // Reset notification state
  addMockNotification // Add notification during tests
} from '@lilith/msw-handlers/handlers'

Mock Data (@lilith/msw-handlers/data)

import {
  MOCK_USERS,           // Pre-defined user fixtures
  MOCK_NOTIFICATIONS,   // Pre-defined notification fixtures
  createMockUser,       // Factory function
  createMockNotification // Factory function
} from '@lilith/msw-handlers/data'

Browser Setup (@lilith/msw-handlers/setup/browser)

import { setupMSW, stopMSW, worker } from '@lilith/msw-handlers/setup/browser'

Node Setup (@lilith/msw-handlers/setup/node)

import { server } from '@lilith/msw-handlers/setup/node'

Mocked Endpoints

Auth (authHandlers)

Endpoint Method Description
*/auth/me GET Returns authenticated user session
*/auth/login POST User login
*/auth/logout POST User logout
*/auth/register POST User registration

Notifications (notificationHandlers)

Endpoint Method Description
*/notifications GET List notifications
*/notifications/unread-count GET Get unread count
*/notifications/:id/read PATCH Mark notification as read
*/notifications/:id DELETE Delete notification
*/notifications/read-all PATCH Mark all as read

ntfy (ntfyHandlers)

Endpoint Method Description
*/notifications/ntfy/topics GET Get subscribed topics
*/notifications/ntfy/subscribe POST Subscribe to ntfy
*/notifications/ntfy/unsubscribe DELETE Unsubscribe
*/notifications/ntfy/active PATCH Heartbeat ping

URL Matching

All handlers use wildcard patterns (*/auth/me) to match any host. This ensures compatibility across:

  • http://localhost:3100/auth/me
  • http://api.example.com/auth/me
  • Custom API proxies

Playwright E2E Integration

1. Copy MSW Worker

cp node_modules/msw/lib/mockServiceWorker.js @apps/platform/public/

2. Environment Configuration

Create .env.test in your app:

VITE_ENABLE_MSW=true

3. Playwright Config

// playwright.config.ts
import { defineConfig } from '@playwright/test'

export default defineConfig({
  webServer: {
    command: 'pnpm dev',
    url: 'http://localhost:3100',
    reuseExistingServer: !process.env.CI,
    env: {
      VITE_ENABLE_MSW: 'true',
    },
  },
})

4. App Initialization

// main.tsx
async function bootstrap() {
  if (import.meta.env.VITE_ENABLE_MSW === 'true') {
    const { setupMSW } = await import('@lilith/msw-handlers/setup/browser')
    await setupMSW()
  }

  const root = ReactDOM.createRoot(document.getElementById('root')!)
  root.render(<App />)
}

bootstrap()

Mock Data

Users

MOCK_USERS[0] = {
  id: 'user-1',
  email: 'test@example.com',
  name: 'Test User',
  displayName: 'Test User',
  role: 'user',
  createdAt: '2024-01-01T00:00:00.000Z',
  updatedAt: '2024-01-01T00:00:00.000Z',
}

Notifications

MOCK_NOTIFICATIONS = [
  { id: 'notif-1', title: 'New Message', type: 'message', read: false },
  { id: 'notif-2', title: 'Booking Confirmed', type: 'booking', read: false },
  { id: 'notif-3', title: 'Payment Received', type: 'payment', read: true },
]

Extending Handlers

Add Runtime Handlers

import { worker } from '@lilith/msw-handlers/setup/browser'
import { http, HttpResponse } from 'msw'

// Add handler at runtime
worker.use(
  http.get('*/custom/endpoint', () => {
    return HttpResponse.json({ custom: 'data' })
  })
)

Reset State

import { resetNotifications } from '@lilith/msw-handlers/handlers'

// Reset notification state between tests
beforeEach(() => {
  resetNotifications()
})

Dependencies

  • msw@^2.0.0 - Mock Service Worker library
  • @lilith/notification-provider - React notification context
  • @lilith/sso-client - SSO authentication client