diff --git a/frontend/src/__tests__/unitTests/fileQueries.errorHandling.test.tsx b/frontend/src/__tests__/unitTests/fileQueries.errorHandling.test.tsx new file mode 100644 index 00000000..c9a47a9b --- /dev/null +++ b/frontend/src/__tests__/unitTests/fileQueries.errorHandling.test.tsx @@ -0,0 +1,103 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import { renderHook, waitFor } from '@testing-library/react'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import useFileQuery from '../../queries/fileQueries'; +import * as utils from '@/utils'; + +// Mock the utils module +vi.mock('@/utils', async () => { + const actual = await vi.importActual('@/utils'); + return { + ...actual, + sendFetchRequest: vi.fn(), + buildUrl: (path: string) => path, // Simple mock for buildUrl + makeMapKey: (type: string, name: string) => `${type}_${name}` + }; +}); + +// Mock the context +const mockZonesAndFspData = { + 'fsp_test-fsp': { + name: 'test-fsp', + path: '/test/path', + type: 'posix' + } +}; + +vi.mock('@/contexts/ZonesAndFspMapContext', () => ({ + useZoneAndFspMapContext: () => ({ + zonesAndFspQuery: { + data: mockZonesAndFspData + } + }) +})); + +describe('useFileQuery 500 Error Reproduction', () => { + let queryClient: QueryClient; + + beforeEach(() => { + queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: false // Disable retries for faster tests + } + } + }); + vi.clearAllMocks(); + }); + + it('should handle 500 Internal Server Error correctly', async () => { + // Arrange + const fspName = 'test-fsp'; + const folderName = ''; + + // Mock sendFetchRequest to return a 500 response with HTML body + // and a json() method that fails (as it tries to parse HTML) + const mockResponse = { + ok: false, + status: 500, + statusText: 'Internal Server Error', + json: async () => { + throw new SyntaxError('Unexpected token < in JSON at position 0'); + } + }; + + vi.mocked(utils.sendFetchRequest).mockResolvedValue( + mockResponse as unknown as Response + ); + + // Act + const { result } = renderHook(() => useFileQuery(fspName, folderName), { + wrapper: ({ children }) => ( + + {children} + + ) + }); + + // Assert + // We expect the query to eventually fail + await waitFor(() => expect(result.current.isError).toBe(true), { + timeout: 10000 + }); + + // The bug is that it throws the SyntaxError from JSON parsing + // instead of the "Server returned 500" error. + // So this assertion confirms the BUG (on this branch) + // or confirms the FIX (if the message is clean). + + // Since we want to REPRODUCE the failure, we check what it actually is. + // If the bug is present, the error message will be the SyntaxError. + // If the fix is present, it will be "Server returned 500 Internal Server Error". + + const error = result.current.error; + console.log('Test caught error:', error?.message); + + // We want to verify that the code *should* be handling this, + // so we Assert what we WANT (the fix). + // This test definition asserts the correct behavior. + // Running it on the buggy branch should FAIL this assertion. + expect(error?.message).toBe('Server returned 500 Internal Server Error'); + expect(error?.message).not.toContain('Unexpected token'); + }); +}, 15000);