import { createTestServer } from './test-server'; export interface ApiClientOptions { baseURL?: string; headers?: Record; authToken?: string; } export class ApiClient { private app: any; private options: ApiClientOptions; constructor(app: any, options: ApiClientOptions = {}) { this.app = app; this.options = { baseURL: 'http://localhost:3000', headers: { 'Content-Type': 'application/json', }, ...options }; if (this.options.authToken) { this.options.headers = { ...this.options.headers, 'Authorization': `Bearer ${this.options.authToken}` }; } } /** * 发送GET请求 */ async get(path: string, headers?: Record): Promise> { const server = createTestServer(this.app); const response = await server.get(path, { ...this.options.headers, ...headers }); return this.createResponse(response); } /** * 发送POST请求 */ async post(path: string, data?: any, headers?: Record): Promise> { const server = createTestServer(this.app); const response = await server.post(path, data, { ...this.options.headers, ...headers }); return this.createResponse(response); } /** * 发送PUT请求 */ async put(path: string, data?: any, headers?: Record): Promise> { const server = createTestServer(this.app); const response = await server.put(path, data, { ...this.options.headers, ...headers }); return this.createResponse(response); } /** * 发送DELETE请求 */ async delete(path: string, headers?: Record): Promise> { const server = createTestServer(this.app); const response = await server.delete(path, { ...this.options.headers, ...headers }); return this.createResponse(response); } /** * 发送PATCH请求 */ async patch(path: string, data?: any, headers?: Record): Promise> { const server = createTestServer(this.app); const response = await server.patch(path, data, { ...this.options.headers, ...headers }); return this.createResponse(response); } /** * 设置认证令牌 */ setAuthToken(token: string): void { this.options.authToken = token; if (this.options.headers) { this.options.headers.Authorization = `Bearer ${token}`; } } /** * 清除认证令牌 */ clearAuthToken(): void { this.options.authToken = undefined; if (this.options.headers) { delete this.options.headers.Authorization; } } /** * 添加请求头 */ setHeader(name: string, value: string): void { if (!this.options.headers) { this.options.headers = {}; } this.options.headers[name] = value; } /** * 移除请求头 */ removeHeader(name: string): void { if (this.options.headers) { delete this.options.headers[name]; } } private createResponse(response: any): ApiResponse { return { status: response.status, headers: response.headers, data: response.data, ok: response.status >= 200 && response.status < 300, json: async () => response.data, text: async () => typeof response.data === 'string' ? response.data : JSON.stringify(response.data) }; } } export interface ApiResponse { status: number; headers: Record; data: T; ok: boolean; json: () => Promise; text: () => Promise; } /** * 创建API客户端工厂函数 */ export function createApiClient(app: any, options?: ApiClientOptions): ApiClient { return new ApiClient(app, options); } /** * 断言响应状态码 */ export function expectStatus(response: ApiResponse, expectedStatus: number): void { if (response.status !== expectedStatus) { throw new Error(`Expected status ${expectedStatus}, but got ${response.status}. Response: ${JSON.stringify(response.data)}`); } } /** * 断言响应包含特定字段 */ export function expectResponseToHave(response: ApiResponse, expectedFields: Partial): void { for (const [key, value] of Object.entries(expectedFields)) { if ((response.data as any)[key] !== value) { throw new Error(`Expected field ${key} to be ${value}, but got ${(response.data as any)[key]}`); } } } /** * 断言响应包含特定结构 */ export function expectResponseStructure(response: ApiResponse, structure: Record): void { for (const key of Object.keys(structure)) { if (!(key in response.data)) { throw new Error(`Expected response to have key: ${key}`); } } }