Files
flyer-crawler.projectium.com/src/services/googleGeocodingService.server.test.ts
Torben Sorensen 08c39afde4
All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 25m33s
more test improvements
2026-01-02 21:33:31 -08:00

133 lines
4.2 KiB
TypeScript

// 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;
beforeEach(() => {
vi.clearAllMocks();
// Mock the global fetch function before each test
vi.stubGlobal('fetch', vi.fn());
vi.unstubAllEnvs();
googleGeocodingService = new GoogleGeocodingService();
});
afterEach(() => {
vi.unstubAllEnvs();
});
it('should return coordinates for a valid address when API key is present', async () => {
// Arrange
vi.stubEnv('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
vi.stubEnv('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
vi.stubEnv('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
vi.stubEnv('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
vi.stubEnv('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.',
);
});
});