From 56adc38171d30df43d5b327aeef18fa176fb28a5 Mon Sep 17 00:00:00 2001 From: Torben Sorensen Date: Tue, 16 Dec 2025 00:01:38 -0800 Subject: [PATCH] Refactor: Update FlyerUploader tests to ensure proper timer advancement for polling cycles and improve clarity in assertions --- src/features/flyer/FlyerUploader.test.tsx | 17 +++++++++++++++-- src/services/userService.test.ts | 16 +++++++++------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/features/flyer/FlyerUploader.test.tsx b/src/features/flyer/FlyerUploader.test.tsx index 1bd0122c..b27da195 100644 --- a/src/features/flyer/FlyerUploader.test.tsx +++ b/src/features/flyer/FlyerUploader.test.tsx @@ -90,11 +90,24 @@ describe('FlyerUploader', () => { expect(mockedAiApiClient.uploadAndProcessFlyer).toHaveBeenCalledWith(file, 'mock-checksum'); }); - // Wait for the UI to switch to the polling/status view + // Wait for the UI to switch to the polling/status view after the FIRST poll await screen.findByText('Checking...'); - // Verify getJobStatus was called (immediate poll) + // Verify the immediate getJobStatus was called expect(mockedAiApiClient.getJobStatus).toHaveBeenCalledTimes(1); + + // --- ADD THIS SECTION TO PREVENT TIMEOUT --- + // Now, explicitly advance the timer to trigger the next polling cycle. + // This ensures the test doesn't hang with a pending timer. + await act(async () => { + // The component waits 3000ms, we advance by that much. + await vi.advanceTimersByTimeAsync(3000); + }); + + // After advancing the timer, the second poll should have been made. + await waitFor(() => { + expect(mockedAiApiClient.getJobStatus).toHaveBeenCalledTimes(2); + }); }); it('should poll for status, complete successfully, and redirect', async () => { diff --git a/src/services/userService.test.ts b/src/services/userService.test.ts index bd67a850..ea4317ba 100644 --- a/src/services/userService.test.ts +++ b/src/services/userService.test.ts @@ -13,10 +13,13 @@ const mocks = vi.hoisted(() => { mockWithTransaction: vi.fn().mockImplementation(async (callback) => { return callback({}); }), - // Mock the User repository class factory - MockUserRepository: vi.fn().mockImplementation(() => ({ - updateUserProfile: mockUpdateUserProfile, - })), + // FIX: Change this from an arrow function to a standard function + // so that it can be instantiated with `new`. + MockUserRepository: vi.fn(function () { + return { + updateUserProfile: mockUpdateUserProfile, + }; + }), // Expose the method mocks for assertions. mockUpsertAddress, mockUpdateUserProfile, @@ -29,7 +32,7 @@ vi.mock('./db/index.db', () => ({ withTransaction: mocks.mockWithTransaction, })); -// Apply the concept here: Use a standard function for the Constructor +// This mock is correct, using a standard function for the constructor. vi.mock('./db/address.db', () => { return { // We define this as a standard function (not an arrow function) @@ -42,9 +45,8 @@ vi.mock('./db/address.db', () => { }; }); +// This now correctly uses the hoisted mock which is a valid constructor. vi.mock('./db/user.db', () => ({ - // For consistency, we can rely on the hoisted mock, - // or convert this to a standard function as well if needed. UserRepository: mocks.MockUserRepository, }));