|
1 | | -/* eslint-disable jest/no-conditional-in-test */ |
2 | 1 | import { ShieldRemoteBackend } from './backend'; |
3 | 2 | import { |
4 | | - delay, |
5 | 3 | generateMockSignatureRequest, |
6 | 4 | generateMockTxMeta, |
7 | 5 | getRandomCoverageResult, |
@@ -46,75 +44,6 @@ function setup({ |
46 | 44 | }; |
47 | 45 | } |
48 | 46 |
|
49 | | -/** |
50 | | - * Setup a fetch mock for polling tests. |
51 | | - * |
52 | | - * @param fetchMock - The mock instance of the fetch API. |
53 | | - * @param options - The options for the fetch mock. |
54 | | - * @param options.delayBetweenResultRequests - The delay between result requests. |
55 | | - * @param options.shouldReturnErrorResult - Whether to return an error result. |
56 | | - * |
57 | | - * @returns The mock coverage ID. |
58 | | - */ |
59 | | -function setupMockRequestsForPollingTests( |
60 | | - fetchMock: jest.MockedFunction<typeof fetch>, |
61 | | - options: { |
62 | | - delayBetweenResultRequests?: number; |
63 | | - shouldReturnErrorResult?: boolean; |
64 | | - } = { |
65 | | - shouldReturnErrorResult: true, |
66 | | - }, |
67 | | -) { |
68 | | - const MOCK_COVERAGE_ID = 'coverageId'; |
69 | | - fetchMock.mockImplementation( |
70 | | - async (input: RequestInfo | URL, init?: RequestInit) => { |
71 | | - // eslint-disable-next-line @typescript-eslint/no-base-to-string |
72 | | - const url = typeof input === 'string' ? input : input.toString(); |
73 | | - const signal = init?.signal; |
74 | | - |
75 | | - if (url.includes('/init')) { |
76 | | - return { |
77 | | - status: 200, |
78 | | - json: jest.fn().mockResolvedValue({ coverageId: MOCK_COVERAGE_ID }), |
79 | | - } as unknown as Response; |
80 | | - } |
81 | | - |
82 | | - if (url.includes('/result')) { |
83 | | - if (signal?.aborted) { |
84 | | - throw new Error('Request was aborted'); |
85 | | - } |
86 | | - |
87 | | - if (options.delayBetweenResultRequests) { |
88 | | - await delay(options.delayBetweenResultRequests); |
89 | | - } |
90 | | - |
91 | | - if (options.shouldReturnErrorResult) { |
92 | | - return { |
93 | | - status: 412, |
94 | | - json: jest.fn().mockResolvedValue({ status: 'unknown' }), |
95 | | - } as unknown as Response; |
96 | | - } |
97 | | - return { |
98 | | - status: 200, |
99 | | - json: jest.fn().mockResolvedValue({ |
100 | | - status: 'covered', |
101 | | - message: 'test', |
102 | | - reasonCode: 'test', |
103 | | - }), |
104 | | - } as unknown as Response; |
105 | | - } |
106 | | - |
107 | | - if (url.includes('/log')) { |
108 | | - return { status: 200 } as unknown as Response; |
109 | | - } |
110 | | - |
111 | | - throw new Error('Unexpected URL'); |
112 | | - }, |
113 | | - ); |
114 | | - |
115 | | - return MOCK_COVERAGE_ID; |
116 | | -} |
117 | | - |
118 | 47 | describe('ShieldRemoteBackend', () => { |
119 | 48 | afterEach(() => { |
120 | 49 | // Clean up mocks after each test |
@@ -296,36 +225,6 @@ describe('ShieldRemoteBackend', () => { |
296 | 225 | }), |
297 | 226 | ).rejects.toThrow('Failed to log signature: 500'); |
298 | 227 | }); |
299 | | - |
300 | | - it('aborts pending coverage result polling before logging', async () => { |
301 | | - const { backend, fetchMock } = setup({ |
302 | | - getCoverageResultTimeout: 10000, |
303 | | - getCoverageResultPollInterval: 100, |
304 | | - }); |
305 | | - |
306 | | - const signatureRequest = generateMockSignatureRequest(); |
307 | | - setupMockRequestsForPollingTests(fetchMock); |
308 | | - |
309 | | - // Start coverage check (don't await) - this will start polling |
310 | | - const coveragePromise = backend.checkSignatureCoverage({ |
311 | | - signatureRequest, |
312 | | - }); |
313 | | - |
314 | | - // Wait a bit to let polling start |
315 | | - await delay(50); |
316 | | - |
317 | | - // Log signature - this should abort the ongoing polling |
318 | | - await backend.logSignature({ |
319 | | - signatureRequest, |
320 | | - signature: '0x00', |
321 | | - status: 'shown', |
322 | | - }); |
323 | | - |
324 | | - // Coverage check should be cancelled |
325 | | - await expect(coveragePromise).rejects.toThrow( |
326 | | - 'Coverage result polling cancelled', |
327 | | - ); |
328 | | - }); |
329 | 228 | }); |
330 | 229 |
|
331 | 230 | describe('logTransaction', () => { |
@@ -356,122 +255,5 @@ describe('ShieldRemoteBackend', () => { |
356 | 255 | }), |
357 | 256 | ).rejects.toThrow('Failed to log transaction: 500'); |
358 | 257 | }); |
359 | | - |
360 | | - it('aborts pending coverage result polling before logging', async () => { |
361 | | - const { backend, fetchMock } = setup({ |
362 | | - getCoverageResultTimeout: 10000, |
363 | | - getCoverageResultPollInterval: 100, |
364 | | - }); |
365 | | - |
366 | | - const txMeta = generateMockTxMeta(); |
367 | | - setupMockRequestsForPollingTests(fetchMock); |
368 | | - |
369 | | - // Start coverage check (don't await) - this will start polling |
370 | | - const coveragePromise = backend.checkCoverage({ txMeta }); |
371 | | - |
372 | | - // Wait a bit to let polling start |
373 | | - await delay(50); |
374 | | - |
375 | | - // Log transaction - this should abort the ongoing polling |
376 | | - await backend.logTransaction({ |
377 | | - txMeta, |
378 | | - transactionHash: '0x00', |
379 | | - status: 'shown', |
380 | | - }); |
381 | | - |
382 | | - // Coverage check should be cancelled |
383 | | - await expect(coveragePromise).rejects.toThrow( |
384 | | - 'Coverage result polling cancelled', |
385 | | - ); |
386 | | - }); |
387 | | - }); |
388 | | - |
389 | | - // Testing coverage result polling with timeout and cancellation. |
390 | | - describe('withTimeoutAndCancellation', () => { |
391 | | - it('should abort previous result request when new request is made', async () => { |
392 | | - const { backend, fetchMock } = setup({ |
393 | | - getCoverageResultTimeout: 10000, // Long timeout to avoid timeout during test |
394 | | - getCoverageResultPollInterval: 100, |
395 | | - }); |
396 | | - |
397 | | - const signatureRequest = generateMockSignatureRequest(); |
398 | | - const coverageId = setupMockRequestsForPollingTests(fetchMock, { |
399 | | - shouldReturnErrorResult: false, |
400 | | - delayBetweenResultRequests: 150, // Long enough to let the first request start and the second request abort it |
401 | | - }); |
402 | | - |
403 | | - // Start first request (don't await) |
404 | | - const firstRequestPromise = backend.checkSignatureCoverage({ |
405 | | - signatureRequest, |
406 | | - }); |
407 | | - |
408 | | - // Wait a bit to let first request start |
409 | | - await delay(50); |
410 | | - |
411 | | - // Start second request which should abort the first |
412 | | - const secondRequestPromise = backend.checkSignatureCoverage({ |
413 | | - signatureRequest, |
414 | | - coverageId, |
415 | | - }); |
416 | | - |
417 | | - // Verify first request was cancelled and second succeeded |
418 | | - await expect(firstRequestPromise).rejects.toThrow( |
419 | | - 'Coverage result polling cancelled', |
420 | | - ); |
421 | | - |
422 | | - const secondResult = await secondRequestPromise; |
423 | | - expect(secondResult).toMatchObject({ |
424 | | - coverageId, |
425 | | - status: 'covered', |
426 | | - }); |
427 | | - }); |
428 | | - |
429 | | - it('should handle timeout properly during result polling', async () => { |
430 | | - const { backend, fetchMock } = setup({ |
431 | | - getCoverageResultTimeout: 200, // Short timeout to simulate the coverage result polling timeout |
432 | | - getCoverageResultPollInterval: 50, |
433 | | - }); |
434 | | - |
435 | | - const signatureRequest = generateMockSignatureRequest(); |
436 | | - setupMockRequestsForPollingTests(fetchMock); |
437 | | - |
438 | | - await expect( |
439 | | - backend.checkSignatureCoverage({ signatureRequest }), |
440 | | - ).rejects.toThrow('Timeout waiting for coverage result'); |
441 | | - }); |
442 | | - |
443 | | - it('should handle multiple concurrent requests with proper cancellation', async () => { |
444 | | - const { backend, fetchMock } = setup(); |
445 | | - |
446 | | - const signatureRequest = generateMockSignatureRequest(); |
447 | | - const result = getRandomCoverageResult(); |
448 | | - const coverageId = 'test-coverage-id'; |
449 | | - |
450 | | - // Mock simple successful responses |
451 | | - fetchMock |
452 | | - .mockResolvedValueOnce({ |
453 | | - status: 200, |
454 | | - json: jest.fn().mockResolvedValue({ coverageId }), |
455 | | - } as unknown as Response) |
456 | | - .mockResolvedValueOnce({ |
457 | | - status: 200, |
458 | | - json: jest.fn().mockResolvedValue(result), |
459 | | - } as unknown as Response); |
460 | | - |
461 | | - // Test that the backend can handle requests properly |
462 | | - // Note: Concurrent cancellation behavior is tested by 100% code coverage |
463 | | - const requestResult = await backend.checkSignatureCoverage({ |
464 | | - signatureRequest, |
465 | | - }); |
466 | | - |
467 | | - // Verify the request completed successfully |
468 | | - expect(requestResult).toMatchObject({ |
469 | | - coverageId, |
470 | | - ...result, |
471 | | - }); |
472 | | - |
473 | | - // Verify that fetch was called (init + result calls) |
474 | | - expect(fetchMock).toHaveBeenCalledTimes(2); |
475 | | - }); |
476 | 258 | }); |
477 | 259 | }); |
0 commit comments