mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
fix(geo): read the Nominatim override the way the schema validates it
Follow-up to #2379. NOMINATIM_URL arrives from a compose file or a ConfigMap with whatever whitespace was typed around it. The schema validates the trimmed string and calls a blank one unset, the derivation did neither, so " " passed startup as "use the default" and then became the base URL that cannot be fetched, and a padded value lost every geocoding call the same way. It trims now, which is also what the places client next door does with its own override. The chart could not pass the variable at all: the ConfigMap is an allowlist and an unknown key is dropped without a word, which is exactly the locked-down cluster the override exists for. The docs said what to set and not what it costs. They now say that it replaces the public service with no fallback, that the endpoint has to speak the Nominatim API, and that the one-per-second spacing stays either way, so nobody stands up their own instance expecting it to run faster. Test IDs follow the file again.
This commit is contained in:
@@ -214,10 +214,17 @@ describe('derivePlugins', () => {
|
||||
});
|
||||
|
||||
describe('deriveIntegrations', () => {
|
||||
it('pins unsplash trim, transit base strip + default, overpass timeout', () => {
|
||||
it('pins unsplash trim, transit base strip + default, nominatim trim + default, overpass timeout', () => {
|
||||
expect(deriveIntegrations({ UNSPLASH_ACCESS_KEY: ' key ' }).unsplashAccessKey).toBe('key');
|
||||
expect(deriveIntegrations({}).transitApiBase).toBe('https://api.transitous.org');
|
||||
expect(deriveIntegrations({ TRANSIT_API_URL: 'https://t.example//' }).transitApiBase).toBe('https://t.example');
|
||||
expect(deriveIntegrations({}).nominatimUrl).toBe('https://nominatim.openstreetmap.org');
|
||||
// Padded and whitespace-only both come back from a compose file or a ConfigMap,
|
||||
// and the schema already called the second one unset.
|
||||
expect(deriveIntegrations({ NOMINATIM_URL: ' http://nominatim:8080/geo// ' }).nominatimUrl).toBe(
|
||||
'http://nominatim:8080/geo',
|
||||
);
|
||||
expect(deriveIntegrations({ NOMINATIM_URL: ' ' }).nominatimUrl).toBe('https://nominatim.openstreetmap.org');
|
||||
// Against the constant, not a literal: the client budget is derived from the timeout
|
||||
// the query itself carries, and pinning the number here is how the two drifted apart.
|
||||
expect(deriveIntegrations({}).overpassTimeoutMs).toBe(OVERPASS_TIMEOUT_DEFAULT_MS);
|
||||
|
||||
@@ -55,26 +55,6 @@ async function drain<T>(fn: () => Promise<T>): Promise<T> {
|
||||
}
|
||||
|
||||
describe('nominatimFetch', () => {
|
||||
it('uses the public endpoint for an empty override', async () => {
|
||||
vi.stubEnv('NOMINATIM_URL', '');
|
||||
await drain(() => nominatimFetch('search', new URLSearchParams({ q: 'Berlin' })));
|
||||
expect(fetchMock.mock.calls[0][0]).toBe('https://nominatim.openstreetmap.org/search?q=Berlin');
|
||||
});
|
||||
|
||||
it.each(['search', 'reverse', 'lookup'] as const)('routes %s to the configured path prefix', async (path) => {
|
||||
vi.stubEnv('NOMINATIM_URL', 'http://nominatim:8080/geocoding///');
|
||||
const params = new URLSearchParams({ q: 'New York & Berlin' });
|
||||
await drain(() => nominatimFetch(path, params));
|
||||
expect(fetchMock.mock.calls[0][0]).toBe(`http://nominatim:8080/geocoding/${path}?q=New+York+%26+Berlin`);
|
||||
expect(fetchMock.mock.calls[0][1].headers['User-Agent']).toBe(UA);
|
||||
});
|
||||
|
||||
it('supports an HTTPS override without a trailing slash', async () => {
|
||||
vi.stubEnv('NOMINATIM_URL', 'https://geo.example.com');
|
||||
await drain(() => nominatimFetch('lookup', new URLSearchParams({ osm_ids: 'N1' })));
|
||||
expect(fetchMock.mock.calls[0][0]).toBe('https://geo.example.com/lookup?osm_ids=N1');
|
||||
});
|
||||
|
||||
it('GEO-001: identifies the instance on every request', async () => {
|
||||
await drain(() => nominatimFetch('search', new URLSearchParams({ q: 'Berlin' })));
|
||||
|
||||
@@ -156,6 +136,43 @@ describe('nominatimFetch', () => {
|
||||
const order = fetchMock.mock.calls.slice(1).map(([url]) => (url as string).includes('q=ui') ? 'ui' : 'bg');
|
||||
expect(order[0]).toBe('ui');
|
||||
});
|
||||
|
||||
it('GEO-012: an unset or blank override keeps the public endpoint', async () => {
|
||||
vi.stubEnv('NOMINATIM_URL', '');
|
||||
await drain(() => nominatimFetch('search', new URLSearchParams({ q: 'Berlin' })));
|
||||
expect(fetchMock.mock.calls[0][0]).toBe('https://nominatim.openstreetmap.org/search?q=Berlin');
|
||||
});
|
||||
|
||||
it.each(['search', 'reverse', 'lookup'] as const)(
|
||||
'GEO-013: routes %s under the configured path prefix',
|
||||
async (path) => {
|
||||
vi.stubEnv('NOMINATIM_URL', 'http://nominatim:8080/geocoding///');
|
||||
const params = new URLSearchParams({ q: 'New York & Berlin' });
|
||||
await drain(() => nominatimFetch(path, params));
|
||||
expect(fetchMock.mock.calls[0][0]).toBe(`http://nominatim:8080/geocoding/${path}?q=New+York+%26+Berlin`);
|
||||
},
|
||||
);
|
||||
|
||||
it('GEO-014: takes an override with no trailing slash as it is', async () => {
|
||||
vi.stubEnv('NOMINATIM_URL', 'https://geo.example.com');
|
||||
await drain(() => nominatimFetch('lookup', new URLSearchParams({ osm_ids: 'N1' })));
|
||||
expect(fetchMock.mock.calls[0][0]).toBe('https://geo.example.com/lookup?osm_ids=N1');
|
||||
});
|
||||
|
||||
// A compose file or a ConfigMap hands the value over with whatever whitespace
|
||||
// was typed around it. The schema validates the trimmed string and calls a
|
||||
// blank one unset, so the derivation has to read it the same way or the value
|
||||
// that passed startup is the one that cannot be fetched.
|
||||
it('GEO-015: trims the override, so a padded value still resolves', async () => {
|
||||
vi.stubEnv('NOMINATIM_URL', ' https://geo.example.com/geocoding/ ');
|
||||
await drain(() => nominatimFetch('search', new URLSearchParams({ q: 'Berlin' })));
|
||||
expect(fetchMock.mock.calls[0][0]).toBe('https://geo.example.com/geocoding/search?q=Berlin');
|
||||
|
||||
fetchMock.mockClear();
|
||||
vi.stubEnv('NOMINATIM_URL', ' ');
|
||||
await drain(() => nominatimFetch('search', new URLSearchParams({ q: 'Berlin' })));
|
||||
expect(fetchMock.mock.calls[0][0]).toBe('https://nominatim.openstreetmap.org/search?q=Berlin');
|
||||
});
|
||||
});
|
||||
|
||||
describe('geo cache', () => {
|
||||
|
||||
Reference in New Issue
Block a user