Some checks failed
CI / Lint (pull_request) Has been cancelled
CI / Schema map up to date (pull_request) Has been cancelled
CI / Forbidden patterns (9 checks) (pull_request) Has been cancelled
CI / Migrations apply (node-pg-migrate) (pull_request) Has been cancelled
Visual diff / Should run? (pull_request) Has been cancelled
CI / Unit tests (vitest) (pull_request) Has been cancelled
Convoy metrics gate / Require role-event telemetry on convoy PRs (pull_request) Has been cancelled
PR Health rollup / Aggregate gate status (pull_request) Has been cancelled
Preview smoke / Should run? (pull_request) Has been cancelled
Preview smoke / Playwright smoke (pull_request) Has been cancelled
Visual diff / Screenshot diff (pull_request) Has been cancelled
Add pricing schema, free API integrations (MTG bulk, TCGdex, Foolio), valuation and sort-by-price, card detail pricing UI, and nearby store discovery via home zip and OSM geo clients. Co-authored-by: Cursor <cursoragent@cursor.com>
59 lines
1.8 KiB
JavaScript
59 lines
1.8 KiB
JavaScript
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);
|
|
});
|
|
});
|