All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 25m33s
133 lines
4.2 KiB
TypeScript
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.',
|
|
);
|
|
});
|
|
});
|