deckhearth/test/lib/pricing/nominatim.test.js

60 lines
1.8 KiB
JavaScript
Raw Permalink Normal View History

import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { geocodeUsZip } from '../../../lib/pricing/nominatim.js';
describe('nominatim', () => {
afterEach(() => {
vi.useRealTimers();
vi.restoreAllMocks();
});
it('geocodes a US zip via allowlisted host', async () => {
const fetchImpl = vi.fn().mockResolvedValue({
ok: true,
json: async () => [{ lat: '40.7128', lon: '-74.0060', display_name: 'New York, NY' }],
});
const result = await geocodeUsZip('10001', { fetchImpl });
expect(result).toEqual({
lat: 40.7128,
lng: -74.006,
displayName: 'New York, NY',
});
const calledUrl = fetchImpl.mock.calls[0][0];
expect(calledUrl).toContain('nominatim.openstreetmap.org');
expect(calledUrl).toContain('postalcode=10001');
});
it('returns null when no results', async () => {
const fetchImpl = vi.fn().mockResolvedValue({
ok: true,
json: async () => [],
});
const result = await geocodeUsZip('00000', { fetchImpl });
expect(result).toBeNull();
});
it('enforces minimum 1s between requests', async () => {
vi.useFakeTimers({ now: new Date('2026-01-01T00:00:00Z') });
vi.resetModules();
const { geocodeUsZip: geocodeFresh } = await import('../../../lib/pricing/nominatim.js');
const fetchImpl = vi.fn().mockResolvedValue({
ok: true,
json: async () => [{ lat: '40.0', lon: '-74.0', display_name: 'Test' }],
});
await geocodeFresh('10001', { fetchImpl });
const secondPromise = geocodeFresh('10002', { fetchImpl });
await vi.advanceTimersByTimeAsync(500);
expect(fetchImpl).toHaveBeenCalledTimes(1);
await vi.advanceTimersByTimeAsync(500);
await secondPromise;
expect(fetchImpl).toHaveBeenCalledTimes(2);
});
});