react-antd-admin-panel
Version:
Modern TypeScript-first React admin panel builder with Ant Design 6
1 lines • 12.1 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","sources":["../../src/testing/createMockHttp.ts","../../src/testing/createMockMain.tsx","../../src/testing/createMockList.ts"],"sourcesContent":["/**\n * createMockHttp - Mock HTTP request utility for testing\n * \n * Provides a fluent API for mocking Get/Post requests with configurable responses.\n * \n * @example\n * const mockHttp = createMockHttp()\n * .onGet('/api/users', { data: mockUsers })\n * .onPost('/api/users', { data: newUser })\n * .onGet('/api/error', { error: new Error('Failed') });\n * \n * // Use in tests\n * await mockHttp.get('/api/users'); // Returns { data: mockUsers }\n */\n\nexport interface MockResponse<T = any> {\n /** Response data */\n data?: T;\n /** Error to throw */\n error?: Error;\n /** Delay in ms before responding */\n delay?: number;\n /** HTTP status code (default 200) */\n status?: number;\n}\n\nexport interface MockHttpConfig {\n /** Default delay for all requests */\n defaultDelay?: number;\n}\n\ntype RequestHandler = (url: string, params?: Record<string, any>) => Promise<any>;\n\n/**\n * MockHttp - Chainable mock HTTP handler\n */\nexport class MockHttp {\n private _getHandlers: Map<string, MockResponse> = new Map();\n private _postHandlers: Map<string, MockResponse> = new Map();\n private _defaultDelay: number = 0;\n\n constructor(config?: MockHttpConfig) {\n this._defaultDelay = config?.defaultDelay || 0;\n }\n\n /**\n * Register a mock GET response\n */\n onGet<T = any>(url: string, response: MockResponse<T>): this {\n this._getHandlers.set(url, response);\n return this;\n }\n\n /**\n * Register a mock POST response\n */\n onPost<T = any>(url: string, response: MockResponse<T>): this {\n this._postHandlers.set(url, response);\n return this;\n }\n\n /**\n * Clear all registered handlers\n */\n clear(): this {\n this._getHandlers.clear();\n this._postHandlers.clear();\n return this;\n }\n\n /**\n * Get the mock GET handler function\n */\n get: RequestHandler = async (url: string, params?: Record<string, any>) => {\n return this._handleRequest(this._getHandlers, url, params);\n };\n\n /**\n * Get the mock POST handler function\n */\n post: RequestHandler = async (url: string, data?: Record<string, any>) => {\n return this._handleRequest(this._postHandlers, url, data);\n };\n\n /**\n * Internal request handler\n */\n private async _handleRequest(\n handlers: Map<string, MockResponse>,\n url: string,\n _data?: Record<string, any>\n ): Promise<any> {\n const response = handlers.get(url);\n\n if (!response) {\n throw new Error(`No mock handler registered for ${url}`);\n }\n\n const delay = response.delay ?? this._defaultDelay;\n if (delay > 0) {\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n\n if (response.error) {\n throw response.error;\n }\n\n return {\n data: response.data,\n status: response.status ?? 200,\n };\n }\n\n /**\n * Get all registered GET handlers (for inspection in tests)\n */\n getRegisteredGetHandlers(): string[] {\n return Array.from(this._getHandlers.keys());\n }\n\n /**\n * Get all registered POST handlers (for inspection in tests)\n */\n getRegisteredPostHandlers(): string[] {\n return Array.from(this._postHandlers.keys());\n }\n}\n\n/**\n * Create a new MockHttp instance\n */\nexport function createMockHttp(config?: MockHttpConfig): MockHttp {\n return new MockHttp(config);\n}\n","import React from 'react';\nimport { MainContext } from '../main/MainContext';\nimport { GlobalStore } from '../main/Store';\nimport { UserState } from '../main/UserState';\nimport type { MainInstance, MainConfig } from '../main/types';\nimport type { User } from '../types';\nimport { createMockHttp, MockHttp } from './createMockHttp';\n\n/**\n * createMockMain - Create a mock MainProvider wrapper for testing\n * \n * @example\n * import { createMockMain } from 'react-antd-admin-panel/testing';\n * import { render, screen } from '@testing-library/react';\n * \n * const { wrapper, mockNavigate, mockHttp } = createMockMain({\n * user: { id: '1', name: 'Test User', roles: ['admin'] },\n * config: { pathToApi: '/api' }\n * });\n * \n * render(<MyComponent />, { wrapper });\n * expect(screen.getByText('Hello')).toBeInTheDocument();\n */\n\n/** Mock function interface compatible with Jest/Vitest */\nexport interface MockFunction {\n (...args: any[]): any;\n mock: { calls: any[][] };\n mockClear: () => void;\n}\n\nexport interface MockMainOptions {\n /** Initial user data */\n user?: User;\n /** Initial store values */\n store?: Record<string, any>;\n /** Main configuration overrides */\n config?: Partial<MainConfig['config']>;\n}\n\nexport interface MockMainResult {\n /** React wrapper component for testing-library */\n wrapper: React.FC<{ children: React.ReactNode }>;\n /** Mock navigate function spy */\n mockNavigate: MockFunction;\n /** Mock HTTP instance */\n mockHttp: MockHttp;\n /** Direct access to the mock Main instance */\n mainInstance: MainInstance;\n /** Direct access to UserState for manipulation */\n userState: UserState;\n /** Direct access to GlobalStore for manipulation */\n store: GlobalStore;\n}\n\n/**\n * Create a mock Main context wrapper for testing\n */\nexport function createMockMain(options: MockMainOptions = {}): MockMainResult {\n // Create instances\n const store = new GlobalStore();\n const userState = new UserState();\n const mockHttp = createMockHttp();\n\n // Initialize store with provided values\n if (options.store) {\n for (const [key, value] of Object.entries(options.store)) {\n store.set(key, value);\n }\n }\n\n // Initialize user with provided data\n if (options.user) {\n userState.set(options.user);\n }\n\n // Create mock navigate function with call tracking\n const calls: any[][] = [];\n const mockNavigate: MockFunction = Object.assign(\n (...args: any[]) => { calls.push(args); },\n {\n mock: { calls },\n mockClear: () => { calls.length = 0; },\n }\n );\n\n // Create the main instance\n const config = options.config || {};\n const mainInstance: MainInstance = {\n User: () => userState,\n Store: () => store,\n config: {\n pathToApi: config.pathToApi || '/api',\n defaultRoute: config.defaultRoute || '/',\n authRoute: config.authRoute || '/login',\n ...config,\n },\n navigate: mockNavigate,\n canAccess: (route) => {\n // Check required role\n if (route.requiredRole && !userState.hasRole(route.requiredRole)) {\n return false;\n }\n // Check required permissions\n if (route.requiredPermissions && !userState.hasAllPermissions(route.requiredPermissions)) {\n return false;\n }\n return true;\n },\n };\n\n // Create the wrapper component\n const wrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n return React.createElement(\n MainContext.Provider,\n { value: mainInstance },\n children\n );\n };\n\n return {\n wrapper,\n mockNavigate,\n mockHttp,\n mainInstance,\n userState,\n store,\n };\n}\n","import { List } from '../list';\n\n/**\n * createMockList - Create a mock List builder for testing\n * \n * @example\n * import { createMockList } from 'react-antd-admin-panel/testing';\n * \n * interface User {\n * id: string;\n * name: string;\n * email: string;\n * }\n * \n * const mockList = createMockList<User>({\n * data: [\n * { id: '1', name: 'John Doe', email: 'john@example.com' },\n * { id: '2', name: 'Jane Doe', email: 'jane@example.com' },\n * ],\n * loading: false,\n * pagination: { pageSize: 10, current: 1, total: 2 },\n * });\n * \n * // The list is ready to use with pre-configured data\n * mockList.column('name', 'Name').column('email', 'Email');\n */\n\nexport interface MockListOptions<T = any> {\n /** Test data to populate the list */\n data?: T[];\n /** Row key field (default: 'id') */\n rowKey?: string | ((record: T) => string);\n /** Loading state */\n loading?: boolean;\n /** Pagination configuration */\n pagination?: false | {\n pageSize?: number;\n current?: number;\n total?: number;\n showSizeChanger?: boolean;\n showQuickJumper?: boolean;\n };\n /** Simulate empty state */\n empty?: boolean;\n /** Custom empty text */\n emptyText?: string;\n}\n\n/**\n * Create a mock List with test configuration\n */\nexport function createMockList<T extends object = any>(options: MockListOptions<T> = {}): List<T> {\n const list = new List<T>();\n\n // Set row key\n if (options.rowKey) {\n list.rowKey(options.rowKey);\n } else {\n list.rowKey('id');\n }\n\n // Set data source\n if (options.empty) {\n list.dataSource([]);\n } else if (options.data) {\n list.dataSource(options.data);\n }\n\n // Set loading state\n if (options.loading !== undefined) {\n list.loading(options.loading);\n }\n\n // Set pagination\n if (options.pagination !== undefined) {\n list.pagination(options.pagination);\n }\n\n // Set empty text\n if (options.emptyText) {\n list.emptyText(options.emptyText);\n }\n\n return list;\n}\r\n"],"names":["GlobalStore","UserState","MainContext","List"],"mappings":"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"}