|
1 | 1 | import { vi } from 'vitest'; |
2 | 2 |
|
3 | | -// Mock fetch globally for Vitest |
4 | | -global.fetch = vi.fn(); |
| 3 | +// Mock fetch for API testing - this will be used by the SDK to make HTTP requests |
| 4 | +(global.fetch as any) = vi.fn().mockResolvedValue({ |
| 5 | + ok: true, |
| 6 | + status: 200, |
| 7 | + statusText: 'OK', |
| 8 | + headers: new Map(), |
| 9 | + json: vi.fn().mockResolvedValue({}), |
| 10 | + text: vi.fn().mockResolvedValue(''), |
| 11 | + arrayBuffer: vi.fn().mockResolvedValue(new ArrayBuffer(0)), |
| 12 | + blob: vi.fn().mockResolvedValue(new Blob()), |
| 13 | + formData: vi.fn().mockResolvedValue(new FormData()), |
| 14 | + clone: vi.fn().mockReturnThis(), |
| 15 | + body: null, |
| 16 | + bodyUsed: false, |
| 17 | + url: '', |
| 18 | + type: 'basic', |
| 19 | + redirected: false, |
| 20 | +}); |
5 | 21 |
|
6 | | -// Cloudflare Workers environment setup |
7 | | -// This simulates the Cloudflare Workers environment for testing |
8 | | -if (process.env.CLOUDFLARE_WORKERS === 'true') { |
9 | | - // Set up Cloudflare Workers globals |
10 | | - globalThis.CloudflareWorkers = true; |
| 22 | +// Store the original Request constructor |
| 23 | +const OriginalRequest = globalThis.Request; |
11 | 24 |
|
12 | | - // Mock Cloudflare Workers specific APIs if needed |
13 | | - // globalThis.caches = new Map(); |
14 | | - // globalThis.crypto = require('crypto'); |
15 | | -} |
| 25 | +// Mock Request constructor to add headers.raw() method for compatibility with node-fetch tests |
| 26 | +globalThis.Request = class MockRequest extends OriginalRequest { |
| 27 | + constructor(url: string | URL, options?: RequestInit) { |
| 28 | + super(url, options); |
| 29 | + |
| 30 | + // Store original header names to preserve casing |
| 31 | + const originalHeaderNames: Record<string, string> = {}; |
| 32 | + if (options?.headers) { |
| 33 | + if (options.headers instanceof Headers) { |
| 34 | + options.headers.forEach((_value, key) => { |
| 35 | + originalHeaderNames[key.toLowerCase()] = key; |
| 36 | + }); |
| 37 | + } else if (Array.isArray(options.headers)) { |
| 38 | + options.headers.forEach(([key]) => { |
| 39 | + originalHeaderNames[key.toLowerCase()] = key; |
| 40 | + }); |
| 41 | + } else { |
| 42 | + Object.entries(options.headers).forEach(([key]) => { |
| 43 | + originalHeaderNames[key.toLowerCase()] = key; |
| 44 | + }); |
| 45 | + } |
| 46 | + } |
| 47 | + |
| 48 | + // Add raw() method to headers for compatibility with node-fetch |
| 49 | + const originalHeaders = this.headers; |
| 50 | + (originalHeaders as any).raw = (): Record<string, string[]> => { |
| 51 | + const rawHeaders: Record<string, string[]> = {}; |
| 52 | + originalHeaders.forEach((value, key) => { |
| 53 | + // Use original casing if available, otherwise use the key as-is |
| 54 | + const originalKey = originalHeaderNames[key.toLowerCase()] || key; |
| 55 | + rawHeaders[originalKey] = [value]; |
| 56 | + }); |
| 57 | + return rawHeaders; |
| 58 | + }; |
| 59 | + } |
| 60 | +} as any; |
| 61 | + |
| 62 | +// Mock mime-types for Cloudflare Workers compatibility |
| 63 | +// This is needed because mime-types uses CommonJS which doesn't work in Workers |
| 64 | +vi.mock('mime-types', () => ({ |
| 65 | + default: { |
| 66 | + lookup: vi.fn((filePath: string) => { |
| 67 | + // Simple mock implementation for common file types |
| 68 | + const ext = filePath.split('.').pop()?.toLowerCase(); |
| 69 | + const mimeTypes: Record<string, string> = { |
| 70 | + txt: 'text/plain', |
| 71 | + html: 'text/html', |
| 72 | + css: 'text/css', |
| 73 | + js: 'application/javascript', |
| 74 | + json: 'application/json', |
| 75 | + png: 'image/png', |
| 76 | + jpg: 'image/jpeg', |
| 77 | + jpeg: 'image/jpeg', |
| 78 | + gif: 'image/gif', |
| 79 | + pdf: 'application/pdf', |
| 80 | + zip: 'application/zip', |
| 81 | + }; |
| 82 | + return mimeTypes[ext || ''] || 'application/octet-stream'; |
| 83 | + }), |
| 84 | + }, |
| 85 | + lookup: vi.fn((filePath: string) => { |
| 86 | + // Simple mock implementation for common file types |
| 87 | + const ext = filePath.split('.').pop()?.toLowerCase(); |
| 88 | + const mimeTypes: Record<string, string> = { |
| 89 | + txt: 'text/plain', |
| 90 | + html: 'text/html', |
| 91 | + css: 'text/css', |
| 92 | + js: 'application/javascript', |
| 93 | + json: 'application/json', |
| 94 | + png: 'image/png', |
| 95 | + jpg: 'image/jpeg', |
| 96 | + jpeg: 'image/jpeg', |
| 97 | + gif: 'image/gif', |
| 98 | + pdf: 'application/pdf', |
| 99 | + zip: 'application/zip', |
| 100 | + }; |
| 101 | + return mimeTypes[ext || ''] || 'application/octet-stream'; |
| 102 | + }), |
| 103 | +})); |
16 | 104 |
|
17 | 105 | // Export for TypeScript module resolution |
18 | 106 | export {}; |
0 commit comments