* Use for situations where fetch() is required. This mock is stateful and has some additional methods to control its behavior: * * - pause() – stop resolving promises until you call resume() * - resume() - flush the queue of promises, and start resolving new promises immediately * - fail() - sta
(mockResponse?: Partial<Response>)
| 218 | * - success() - go back to returning a success response |
| 219 | */ |
| 220 | function createGlobalFetchMock(mockResponse?: Partial<Response>): MockFetch { |
| 221 | let queue: QueueItem[] = []; |
| 222 | // eslint-disable-next-line @typescript-eslint/no-explicit-any |
| 223 | let responses = new Map<string, (params: any) => OnyxResponse<any>>(); |
| 224 | let isPaused = false; |
| 225 | let shouldFail = false; |
| 226 | |
| 227 | const getResponse = (input: RequestInfo, options?: RequestInit): Partial<Response> => |
| 228 | shouldFail |
| 229 | ? { |
| 230 | ok: true, |
| 231 | json: () => Promise.resolve({jsonCode: 400}), |
| 232 | } |
| 233 | : { |
| 234 | ok: true, |
| 235 | json: async () => { |
| 236 | const commandMatch = typeof input === 'string' ? input.match(/https:\/\/www.expensify.com.dev\/api\/(\w+)\?/) : null; |
| 237 | const command = commandMatch ? commandMatch[1] : null; |
| 238 | |
| 239 | const responseHandler = command ? responses.get(command) : null; |
| 240 | if (responseHandler) { |
| 241 | const requestData = options?.body instanceof FormData ? Object.fromEntries(options.body) : {}; |
| 242 | return Promise.resolve({jsonCode: 200, ...responseHandler(requestData)}); |
| 243 | } |
| 244 | |
| 245 | return Promise.resolve({jsonCode: 200}); |
| 246 | }, |
| 247 | ...mockResponse, |
| 248 | }; |
| 249 | |
| 250 | const mockFetch = jest.fn().mockImplementation((input: RequestInfo, options?: RequestInit) => { |
| 251 | if (!isPaused) { |
| 252 | return Promise.resolve(getResponse(input, options)); |
| 253 | } |
| 254 | return new Promise((resolve) => { |
| 255 | queue.push({resolve, input, options}); |
| 256 | }); |
| 257 | }) as MockFetch; |
| 258 | |
| 259 | const baseMockReset = mockFetch.mockReset.bind(mockFetch); |
| 260 | mockFetch.mockReset = () => { |
| 261 | baseMockReset(); |
| 262 | queue = []; |
| 263 | responses = new Map(); |
| 264 | isPaused = false; |
| 265 | shouldFail = false; |
| 266 | return mockFetch; |
| 267 | }; |
| 268 | |
| 269 | mockFetch.pause = () => (isPaused = true); |
| 270 | mockFetch.resume = () => { |
| 271 | isPaused = false; |
| 272 | for (const {resolve, input} of queue) { |
| 273 | resolve(getResponse(input)); |
| 274 | } |
| 275 | return waitForBatchedUpdates(); |
| 276 | }; |
| 277 | mockFetch.fail = () => (shouldFail = true); |
no test coverage detected