Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions frontend/src/__tests__/unitTests/fileQueries.errorHandling.test.tsx
Original file line number Diff line number Diff line change
@@ -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 }) => (
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
)
});

// 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');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the likely next step here would be to remove or modify this line and keep the next line that checks for the abseence of 'Unexpected token'.

The main point of the test is to make sure that we are not showing JSON parsing errors of other error messages. We may not want to test for a specific error message.

expect(error?.message).not.toContain('Unexpected token');
});
}, 15000);