diff --git a/src/features/flyer/FlyerUploader.test.tsx b/src/features/flyer/FlyerUploader.test.tsx index 8561611f..ad0d142d 100644 --- a/src/features/flyer/FlyerUploader.test.tsx +++ b/src/features/flyer/FlyerUploader.test.tsx @@ -85,17 +85,14 @@ describe('FlyerUploader', () => { const input = screen.getByLabelText(/click to select a file/i); console.log('--- [TEST LOG] ---: 3. Firing file change event inside act().'); - await act(async () => { - fireEvent.change(input, { target: { files: [file] } }); - }); + // fireEvent is already wrapped in act(). No need for an explicit, outer act(). + fireEvent.change(input, { target: { files: [file] } }); console.log('--- [TEST LOG] ---: 4. File change event fired.'); - // --- FIX: Wait for the UI to update first to ensure async operations are complete --- console.log('--- [TEST LOG] ---: 5. Waiting for UI to update to polling state ("Checking...").'); await screen.findByText('Checking...'); console.log('--- [TEST LOG] ---: 6. UI updated to polling state.'); - // --- FIX: Now that the UI is updated, we can safely assert that the mocks were called --- expect(mockedAiApiClient.uploadAndProcessFlyer).toHaveBeenCalledWith(file, 'mock-checksum'); expect(mockedAiApiClient.getJobStatus).toHaveBeenCalledTimes(1); console.log('--- [TEST LOG] ---: 7. Verified upload and initial poll calls.'); @@ -110,7 +107,6 @@ describe('FlyerUploader', () => { await waitFor(() => { expect(mockedAiApiClient.getJobStatus).toHaveBeenCalledTimes(2); }); - console.log('--- [TEST LOG] ---: 11. Test finished successfully.'); }); it('should poll for status, complete successfully, and redirect', async () => { @@ -127,11 +123,8 @@ describe('FlyerUploader', () => { renderComponent(onProcessingComplete); const file = new File(['content'], 'flyer.pdf', { type: 'application/pdf' }); const input = screen.getByLabelText(/click to select a file/i); - await act(async () => { - fireEvent.change(input, { target: { files: [file] } }); - }); + fireEvent.change(input, { target: { files: [file] } }); - // --- FIX: Wait for the first poll's UI update to ensure synchronization --- console.log('--- [TEST LOG] ---: 3. Waiting for UI to update to "Analyzing...".'); await screen.findByText('Analyzing...'); expect(mockedAiApiClient.getJobStatus).toHaveBeenCalledTimes(1); @@ -158,7 +151,6 @@ describe('FlyerUploader', () => { expect(onProcessingComplete).toHaveBeenCalled(); expect(navigateSpy).toHaveBeenCalledWith('/flyers/42'); - console.log('--- [TEST LOG] ---: 11. Callback and navigation confirmed. Test finished successfully.'); }); it('should handle a failed job', async () => { @@ -174,17 +166,12 @@ describe('FlyerUploader', () => { renderComponent(); const file = new File(['content'], 'flyer.pdf', { type: 'application/pdf' }); const input = screen.getByLabelText(/click to select a file/i); - await act(async () => { - fireEvent.change(input, { target: { files: [file] } }); - }); + fireEvent.change(input, { target: { files: [file] } }); console.log('--- [TEST LOG] ---: 3. File upload triggered.'); - // --- FIX: Use findBy* to wait for the async operation to complete and update the UI --- console.log('--- [TEST LOG] ---: 4. Waiting for failure message.'); expect(await screen.findByText(/Processing failed: AI model exploded/i)).toBeInTheDocument(); console.log('--- [TEST LOG] ---: 5. Failure message found.'); - expect(screen.getByText('Upload Another Flyer')).toBeInTheDocument(); - console.log('--- [TEST LOG] ---: 6. "Upload Another" button confirmed. Test finished successfully.'); }); it('should handle a duplicate flyer error (409)', async () => { @@ -197,17 +184,13 @@ describe('FlyerUploader', () => { renderComponent(); const file = new File(['content'], 'flyer.pdf', { type: 'application/pdf' }); const input = screen.getByLabelText(/click to select a file/i); - await act(async () => { - fireEvent.change(input, { target: { files: [file] } }); - }); + fireEvent.change(input, { target: { files: [file] } }); console.log('--- [TEST LOG] ---: 3. File upload triggered.'); - // --- FIX: Use findBy* to wait for the async operation to complete and update the UI --- console.log('--- [TEST LOG] ---: 4. Waiting for duplicate flyer message.'); expect(await screen.findByText('This flyer has already been processed. You can view it here:')).toBeInTheDocument(); const link = screen.getByRole('link', { name: /Flyer #99/i }); expect(link).toHaveAttribute('href', '/flyers/99'); - console.log('--- [TEST LOG] ---: 5. Duplicate message and link confirmed. Test finished successfully.'); }); it('should allow the user to stop watching progress', async () => { @@ -223,26 +206,19 @@ describe('FlyerUploader', () => { renderComponent(); const file = new File(['content'], 'flyer.pdf', { type: 'application/pdf' }); const input = screen.getByLabelText(/click to select a file/i); - await act(async () => { - fireEvent.change(input, { target: { files: [file] } }); - }); + fireEvent.change(input, { target: { files: [file] } }); console.log('--- [TEST LOG] ---: 3. File upload triggered.'); - // --- FIX: Wait for the polling UI to appear to ensure async operations are complete --- console.log('--- [TEST LOG] ---: 4. Waiting for polling UI.'); const stopButton = await screen.findByRole('button', { name: 'Stop Watching Progress' }); console.log('--- [TEST LOG] ---: 5. Polling UI is visible.'); console.log('--- [TEST LOG] ---: 6. Clicking "Stop Watching Progress" button.'); - await act(async () => { - fireEvent.click(stopButton); - }); + fireEvent.click(stopButton); console.log('--- [TEST LOG] ---: 7. Click event fired.'); - // --- FIX: Wait for the idle UI to re-appear --- console.log('--- [TEST LOG] ---: 8. Waiting for UI to reset to idle state.'); expect(await screen.findByText(/click to select a file/i)).toBeInTheDocument(); expect(screen.queryByText('Analyzing...')).not.toBeInTheDocument(); - console.log('--- [TEST LOG] ---: 9. UI has reset. Test finished successfully.'); }); }); \ No newline at end of file diff --git a/src/pages/admin/components/ProfileManager.Authenticated.test.tsx b/src/pages/admin/components/ProfileManager.Authenticated.test.tsx index 384d528b..ee915845 100644 --- a/src/pages/admin/components/ProfileManager.Authenticated.test.tsx +++ b/src/pages/admin/components/ProfileManager.Authenticated.test.tsx @@ -181,19 +181,12 @@ describe('ProfileManager Authenticated User Features', () => { // Wait for initial data fetch (getUserAddress) to complete console.log('[TEST LOG] Waiting for initial address data to load...'); await waitFor(() => expect(screen.getByLabelText(/city/i)).toHaveValue(mockAddress.city)); - console.log('[TEST LOG] Initial address data loaded.'); - - const cityInput = screen.getByLabelText(/city/i); - console.log('[TEST LOG] City input initial value:', (cityInput as HTMLInputElement).value); console.log('[TEST LOG] Firing change event on city input.'); fireEvent.change(screen.getByLabelText(/city/i), { target: { value: 'NewCity' } }); - console.log('[TEST LOG] City input value after change:', (cityInput as HTMLInputElement).value); + // Use fireEvent.submit on the form for more robust testing of submission logic. + fireEvent.submit(screen.getByTestId('profile-form')); - console.log('[TEST LOG] Firing click event on "Save Profile" button.'); - fireEvent.click(screen.getByRole('button', { name: /save profile/i })); - - console.log('[TEST LOG] Waiting for notifyError to be called...'); // Since only the address changed and it failed, we expect an error notification (handled by useApi) // and NOT a success message. await waitFor(() => { diff --git a/src/pages/admin/components/ProfileManager.tsx b/src/pages/admin/components/ProfileManager.tsx index 355a95b1..4dc54109 100644 --- a/src/pages/admin/components/ProfileManager.tsx +++ b/src/pages/admin/components/ProfileManager.tsx @@ -372,7 +372,7 @@ export const ProfileManager: React.FC = ({ isOpen, onClose, {activeTab === 'profile' && ( -
+
setFullName(e.target.value)} className="mt-1 block w-full px-3 py-2 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm" /> diff --git a/src/utils/checksum.test.ts b/src/utils/checksum.test.ts index 3208763e..eb279041 100644 --- a/src/utils/checksum.test.ts +++ b/src/utils/checksum.test.ts @@ -5,6 +5,7 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { generateFileChecksum } from './checksum'; +import { logger } from '../services/logger.client'; describe('generateFileChecksum', () => { it('should generate the correct SHA-256 checksum for a simple text file', async () => { @@ -51,8 +52,8 @@ describe('generateFileChecksum', () => { describe('with fallback mechanisms', () => { beforeEach(() => { - // Mock console.warn to prevent logs from appearing in test output - vi.spyOn(console, 'warn').mockImplementation(() => {}); + // Mock logger.warn to prevent logs from appearing in test output + vi.spyOn(logger, 'warn').mockImplementation(() => {}); }); afterEach(() => { @@ -68,7 +69,7 @@ describe('generateFileChecksum', () => { const checksum = await generateFileChecksum(file); // Correct SHA-256 for "fallback test" (without a trailing newline). expect(checksum).toBe('c4c388111e0b74ec6f9b609d240d1f2e5df5270999118b442d6db6ce3cac6cce'); - expect(console.warn).toHaveBeenCalledWith(expect.stringContaining('file.arrayBuffer is not a function')); + expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining('file.arrayBuffer is not a function')); }); it('should use FileReader fallback if file.arrayBuffer throws an error', async () => { @@ -79,7 +80,7 @@ describe('generateFileChecksum', () => { const checksum = await generateFileChecksum(file); // Correct SHA-256 for "error fallback" (without a trailing newline). expect(checksum).toBe('786aaab58cd94f0d74de6895575dcfa7ace2733c9713121e1fac197eb02ec1c2'); - expect(console.warn).toHaveBeenCalledWith(expect.stringContaining('file.arrayBuffer() threw an error')); + expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining('file.arrayBuffer() threw an error')); }); it('should throw an error if crypto.subtle is not available', async () => {