UNPKG

@dbs-portal/tool-mock

Version:

API mocking toolkit using MSW for DBS Portal development workflows

317 lines 8.21 kB
/** * Response builder for creating mock HTTP responses */ import { HttpResponse } from 'msw'; import { applyDelay } from '../utils/delay'; import { generateId } from './data-generators'; /** * Implementation of mock response builder */ export class MockResponseBuilderImpl { responseData = null; statusCode = 200; responseHeaders = {}; responseDelay; responseError; metadata = {}; constructor(options = {}) { if (options.data !== undefined) this.responseData = options.data; if (options.status !== undefined) this.statusCode = options.status; if (options.headers) this.responseHeaders = { ...options.headers }; if (options.delay !== undefined) this.responseDelay = options.delay; if (options.error) this.responseError = options.error; if (options.meta) this.metadata = { ...options.meta }; } /** * Set response data */ data(data) { this.responseData = data; return this; } /** * Set status code */ status(code) { this.statusCode = code; return this; } /** * Set headers */ headers(headers) { this.responseHeaders = { ...this.responseHeaders, ...headers }; return this; } /** * Set delay */ delay(ms) { this.responseDelay = ms; return this; } /** * Add error */ error(error) { this.responseError = error; return this; } /** * Set metadata */ meta(metadata) { this.metadata = { ...this.metadata, ...metadata }; return this; } /** * Build the response */ build() { const startTime = performance.now(); // Prepare response body let responseBody; if (this.responseError) { responseBody = { success: false, errors: [this.responseError], meta: { timestamp: new Date().toISOString(), requestId: generateId(), version: '1.0.0', ...this.metadata, }, }; } else { responseBody = { success: true, data: this.responseData, meta: { timestamp: new Date().toISOString(), requestId: generateId(), version: '1.0.0', ...this.metadata, }, }; } // Set default headers const headers = { 'Content-Type': 'application/json', 'X-Mock-Response': 'true', ...this.responseHeaders, }; // Add generation time to metadata if available if (this.metadata.generatedAt) { const endTime = performance.now(); headers['X-Generation-Time'] = `${(endTime - startTime).toFixed(2)}ms`; } return HttpResponse.json(responseBody, { status: this.statusCode, headers, }); } /** * Build with async delay */ async buildAsync() { if (this.responseDelay) { await applyDelay(this.responseDelay); } return this.build(); } } /** * Create a new response builder */ export function mockResponseBuilder(options = {}) { return new MockResponseBuilderImpl(options); } /** * Create a success response */ export function createSuccessResponse(data, options = {}) { return mockResponseBuilder({ ...options, data, success: true, }).build(); } /** * Create an error response */ export function createErrorResponse(error, options = {}) { const status = error.status || 400; return mockResponseBuilder({ ...options, error, success: false, status, }).build(); } /** * Create a loading response (with delay) */ export function createLoadingResponse(data, delay = [1000, 3000], options = {}) { return mockResponseBuilder({ ...options, data, delay, }); } /** * Create a not found response */ export function createNotFoundResponse(message = 'Resource not found', options = {}) { return createErrorResponse({ code: 'NOT_FOUND', message, }, { ...options, status: 404 }); } /** * Create an unauthorized response */ export function createUnauthorizedResponse(message = 'Unauthorized', options = {}) { return createErrorResponse({ code: 'UNAUTHORIZED', message, }, { ...options, status: 401 }); } /** * Create a forbidden response */ export function createForbiddenResponse(message = 'Forbidden', options = {}) { return createErrorResponse({ code: 'FORBIDDEN', message, }, { ...options, status: 403 }); } /** * Create a validation error response */ export function createValidationErrorResponse(errors, message = 'Validation failed', options = {}) { return createErrorResponse({ code: 'VALIDATION_ERROR', message, details: errors, }, { ...options, status: 400 }); } /** * Create a server error response */ export function createServerErrorResponse(message = 'Internal server error', options = {}) { return createErrorResponse({ code: 'INTERNAL_SERVER_ERROR', message, }, { ...options, status: 500 }); } /** * Create a rate limit response */ export function createRateLimitResponse(message = 'Rate limit exceeded', retryAfter = 60, options = {}) { return mockResponseBuilder({ ...options, error: { code: 'RATE_LIMIT_EXCEEDED', message, }, headers: { 'Retry-After': retryAfter.toString(), ...options.headers, }, status: 429, }).build(); } /** * Create a maintenance response */ export function createMaintenanceResponse(message = 'Service temporarily unavailable', retryAfter = 3600, options = {}) { return mockResponseBuilder({ ...options, error: { code: 'SERVICE_UNAVAILABLE', message, }, headers: { 'Retry-After': retryAfter.toString(), ...options.headers, }, status: 503, }).build(); } /** * Create a response with custom status and message */ export function createCustomResponse(status, data, error, options = {}) { const builder = mockResponseBuilder({ ...options, status, }); if (error) { builder.error(error); } else if (data !== undefined) { builder.data(data); } return builder.build(); } /** * Create a response that simulates network conditions */ export function createNetworkResponse(data, networkCondition = 'fast', options = {}) { let delay; switch (networkCondition) { case 'fast': delay = [10, 50]; break; case 'slow': delay = [2000, 5000]; break; case 'unstable': delay = [100, 3000]; break; default: delay = [100, 300]; } return mockResponseBuilder({ ...options, data, delay, }); } /** * Create a response with cache headers */ export function createCachedResponse(data, cacheControl = 'public, max-age=3600', options = {}) { return mockResponseBuilder({ ...options, data, headers: { 'Cache-Control': cacheControl, 'ETag': `"${Date.now()}"`, ...options.headers, }, }).build(); } /** * Create a response with CORS headers */ export function createCorsResponse(data, origin = '*', options = {}) { return mockResponseBuilder({ ...options, data, headers: { 'Access-Control-Allow-Origin': origin, 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization', ...options.headers, }, }).build(); } //# sourceMappingURL=response-builder.js.map