Refactor tests to use mockClient for database interactions, improve error handling, and enhance modal functionality
Some checks failed
Deploy to Test Environment / deploy-to-test (push) Has been cancelled

- Updated personalization.db.test.ts to use mockClient for query calls in addWatchedItem tests.
- Simplified error handling in shopping.db.test.ts, ensuring clearer error messages.
- Added comprehensive tests for VoiceAssistant component, including rendering and interaction tests.
- Introduced useModal hook with tests to manage modal state effectively.
- Created deals.db.test.ts to test deals repository functionality with mocked database interactions.
- Implemented error handling tests for custom error classes in errors.db.test.ts.
- Developed googleGeocodingService.server.test.ts to validate geocoding service behavior with mocked fetch.
This commit is contained in:
2025-12-14 01:12:33 -08:00
parent 7615d7746e
commit f891da687b
25 changed files with 786 additions and 290 deletions

View File

@@ -0,0 +1,128 @@
// src/services/googleGeocodingService.server.test.ts
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
// Un-mock the module we are testing to ensure we use the real implementation.
vi.unmock('./googleGeocodingService.server');
// Mock the logger to prevent console output and allow for assertions
vi.mock('./logger.server', () => ({
logger: {
info: vi.fn(),
warn: vi.fn(),
error: vi.fn(),
debug: vi.fn(),
},
}));
// Import the service to be tested and its mocked dependencies
import { GoogleGeocodingService } from './googleGeocodingService.server';
import { logger as mockLogger } from './logger.server';
describe('Google Geocoding Service', () => {
let googleGeocodingService: GoogleGeocodingService;
const originalEnv = process.env;
beforeEach(() => {
vi.clearAllMocks();
// Mock the global fetch function before each test
vi.stubGlobal('fetch', vi.fn());
// Restore process.env to a clean state for each test
process.env = { ...originalEnv };
googleGeocodingService = new GoogleGeocodingService();
});
afterEach(() => {
// Restore original environment variables after each test
process.env = originalEnv;
});
it('should return coordinates for a valid address when API key is present', async () => {
// Arrange
process.env.GOOGLE_MAPS_API_KEY = 'test-api-key';
const mockApiResponse = {
status: 'OK',
results: [{
geometry: {
location: { lat: 34.0522, lng: -118.2437 },
},
}],
};
vi.mocked(fetch).mockResolvedValue({
ok: true,
json: async () => mockApiResponse,
} as Response);
// Act
const result = await googleGeocodingService.geocode('Los Angeles, CA', mockLogger);
// Assert
expect(result).toEqual({ lat: 34.0522, lng: -118.2437 });
expect(fetch).toHaveBeenCalledWith(expect.stringContaining('https://maps.googleapis.com/maps/api/geocode/json'));
expect(mockLogger.info).toHaveBeenCalledWith(
{ address: 'Los Angeles, CA', result: { lat: 34.0522, lng: -118.2437 } },
'[GoogleGeocodingService] Successfully geocoded address'
);
});
it('should throw an error if GOOGLE_MAPS_API_KEY is not set', async () => {
// Arrange
delete process.env.GOOGLE_MAPS_API_KEY;
// Act & Assert
await expect(googleGeocodingService.geocode('Any Address', mockLogger))
.rejects.toThrow('GOOGLE_MAPS_API_KEY is not set.');
expect(mockLogger.error).toHaveBeenCalledWith('[GoogleGeocodingService] API key is missing.');
});
it('should return null if the API returns a status other than "OK"', async () => {
// Arrange
process.env.GOOGLE_MAPS_API_KEY = 'test-api-key';
const mockApiResponse = { status: 'ZERO_RESULTS', results: [] };
vi.mocked(fetch).mockResolvedValue({
ok: true,
json: async () => mockApiResponse,
} as Response);
// Act
const result = await googleGeocodingService.geocode('Invalid Address', mockLogger);
// Assert
expect(result).toBeNull();
expect(mockLogger.warn).toHaveBeenCalledWith(
{ address: 'Invalid Address', status: 'ZERO_RESULTS' },
'[GoogleGeocodingService] Geocoding failed or returned no results.'
);
});
it('should throw an error if the fetch response is not ok', async () => {
// Arrange
process.env.GOOGLE_MAPS_API_KEY = 'test-api-key';
vi.mocked(fetch).mockResolvedValue({
ok: false,
status: 403,
} as Response);
// Act & Assert
await expect(googleGeocodingService.geocode('Any Address', mockLogger))
.rejects.toThrow('Google Maps API returned status 403');
expect(mockLogger.error).toHaveBeenCalledWith(
{ err: expect.any(Error), address: 'Any Address' },
'[GoogleGeocodingService] An error occurred while calling the Google Maps API.'
);
});
it('should throw an error if the fetch call itself fails', async () => {
// Arrange
process.env.GOOGLE_MAPS_API_KEY = 'test-api-key';
const networkError = new Error('Network request failed');
vi.mocked(fetch).mockRejectedValue(networkError);
// Act & Assert
await expect(googleGeocodingService.geocode('Any Address', mockLogger))
.rejects.toThrow(networkError);
expect(mockLogger.error).toHaveBeenCalledWith(
{ err: networkError, address: 'Any Address' },
'[GoogleGeocodingService] An error occurred while calling the Google Maps API.'
);
});
});