diff --git a/server/providers/overpass/osmFeatures.js b/server/providers/overpass/osmFeatures.js index 5288af84a..5d2a1f62d 100644 --- a/server/providers/overpass/osmFeatures.js +++ b/server/providers/overpass/osmFeatures.js @@ -109,7 +109,13 @@ export function compileOsmFeatureQuery(request = {}) { ? 'That area is too large to search; narrow it down.' : 'That area is too large to list; count first or narrow it down.', ); - const requested = Number(request.limit); + // An absent or empty limit is the default, not Number(null) = 0. + const requested = + request.limit === null || + request.limit === undefined || + String(request.limit).trim() === '' + ? NaN + : Number(request.limit); const limit = Math.max( 1, Math.min( diff --git a/src/tooling/osmFeaturesRoute.test.mjs b/src/tooling/osmFeaturesRoute.test.mjs index 305980633..942e01f7b 100644 --- a/src/tooling/osmFeaturesRoute.test.mjs +++ b/src/tooling/osmFeaturesRoute.test.mjs @@ -256,6 +256,28 @@ function mount( return { request, start, writes }; } +test('a search without a limit lists up to 500 features', async () => { + const sent = []; + const { request } = mount(async (body) => { + sent.push(decodeURIComponent(body)); + return { status: 200, body: JSON.stringify({ elements: [] }) }; + }); + for (const search of [ + 'preset=hospital&bbox=0,0,1,1', + 'preset=school&bbox=0,0,1,1&limit=', + ]) { + const answer = await request(search); + assert.equal(answer.status, 200, search); + } + assert.equal(sent.length, 2); + for (const ql of sent) assert.match(ql, /out center tags 500;$/); + assert.equal( + compileOsmFeatureQuery({ preset: 'hospital', bbox: '0,0,1,1', limit: '7' }) + .limit, + 7, + ); +}); + test('the route answers, caches, and shares upstream slots fairly', async () => { const release = []; let upstream = 0;