Refactor: Improve test assertions and error messages in useAuth and recipe routes tests for clarity
All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 15m14s

This commit is contained in:
2025-12-15 23:31:59 -08:00
parent 74655a5f17
commit d1cd0b332e
3 changed files with 27 additions and 15 deletions

View File

@@ -140,10 +140,10 @@ describe('useAuth Hook and AuthProvider', () => {
const { result } = renderHook(() => useAuth(), { wrapper });
// Wait for the hook to stabilize after initial render
// Wait for the initial effect to complete and loading to be false
await waitFor(() => {
expect(result.current.isLoading).toBe(false);
}, { timeout: 1000 });
});
// Perform login
await act(async () => {
@@ -152,9 +152,12 @@ describe('useAuth Hook and AuthProvider', () => {
// Assertions
expect(localStorageMock.setItem).toHaveBeenCalledWith('authToken', 'new-valid-token');
expect(result.current.authStatus).toBe('AUTHENTICATED');
expect(result.current.user).toEqual(mockUser);
expect(result.current.profile).toEqual(mockProfile);
// We must wait for the state update inside the hook to propagate
await waitFor(() => {
expect(result.current.authStatus).toBe('AUTHENTICATED');
expect(result.current.user).toEqual(mockUser);
expect(result.current.profile).toEqual(mockProfile);
});
});
it('logs out and throws an error if profile fetch fails after login', async () => {

View File

@@ -126,7 +126,7 @@ describe('Recipe Routes (/api/recipes)', () => {
it('should return 400 if required query parameters are missing', async () => {
const response = await supertest(app).get('/api/recipes/by-ingredient-and-tag?ingredient=chicken');
expect(response.status).toBe(400);
expect(response.body.errors[0].message).toContain('received undefined');
expect(response.body.errors[0].message).toBe('Query parameter "tag" is required.');
});
});

View File

@@ -11,14 +11,9 @@ const mocks = vi.hoisted(() => {
return {
// Mock the withTransaction helper to immediately execute the callback.
mockWithTransaction: vi.fn().mockImplementation(async (callback) => {
// The callback will receive a mock client, but we don't need to use it
// since we are mocking the repository classes themselves.
return callback({});
}),
// Mock the repository classes.
MockAddressRepository: vi.fn().mockImplementation(() => ({
upsertAddress: mockUpsertAddress,
})),
// Mock the User repository class factory
MockUserRepository: vi.fn().mockImplementation(() => ({
updateUserProfile: mockUpdateUserProfile,
})),
@@ -29,13 +24,27 @@ const mocks = vi.hoisted(() => {
});
// --- Mock Modules ---
vi.mock('./db/index.db', () => ({
withTransaction: mocks.mockWithTransaction,
}));
vi.mock('./db/address.db', () => ({
AddressRepository: mocks.MockAddressRepository,
}));
// Apply the concept here: Use a standard function for the Constructor
vi.mock('./db/address.db', () => {
return {
// We define this as a standard function (not an arrow function)
// so that it can be instantiated with 'new AddressRepository()'
AddressRepository: vi.fn(function () {
return {
upsertAddress: mocks.mockUpsertAddress,
};
}),
};
});
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,
}));