Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 21 additions & 3 deletions integrations/search-osm-aliases/__tests__/provider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ describe("OSM alias suggestion provider", () => {
it("uses normalized parameterized lookup and maps exact code evidence", async () => {
const execute = vi
.fn()
.mockResolvedValueOnce([{ exists: true }])
.mockResolvedValueOnce([{ epoch: "epoch-1", status: "ready" }])
.mockResolvedValueOnce([
{
Expand All @@ -32,7 +33,7 @@ describe("OSM alias suggestion provider", () => {
{ signal: new AbortController().signal, deadlineAt: Number.POSITIVE_INFINITY },
);

expect(execute.mock.calls[1]?.[1]).toEqual(["fra", true, 8, null, null, true]);
expect(execute.mock.calls[2]?.[1]).toEqual(["fra", true, 8, null, null, true]);
expect(result.suggestions[0]).toMatchObject({
id: "osm:node/42",
ids: { osm: "node/42", wikidata: "Q46033" },
Expand Down Expand Up @@ -63,6 +64,7 @@ describe("OSM alias suggestion provider", () => {
it("passes lowercase acronym intent and proximity to the SQL gate", async () => {
const execute = vi
.fn()
.mockResolvedValueOnce([{ exists: true }])
.mockResolvedValueOnce([{ epoch: "epoch-2", status: "ready" }])
.mockResolvedValueOnce([]);
const provider = createOsmAliasSuggestionProvider(
Expand All @@ -74,7 +76,23 @@ describe("OSM alias suggestion provider", () => {
{ signal: new AbortController().signal, deadlineAt: Number.POSITIVE_INFINITY },
);

expect(execute.mock.calls[1]?.[1]).toEqual(["uncc", true, 4, -80.73, 35.3, false]);
expect(String(execute.mock.calls[1]?.[0])).toContain("ST_DWithin");
expect(execute.mock.calls[2]?.[1]).toEqual(["uncc", true, 4, -80.73, 35.3, false]);
expect(String(execute.mock.calls[2]?.[0])).toContain("ST_DWithin");
});

it("returns nothing, without reading the index, until an index is built", async () => {
const execute = vi.fn().mockResolvedValueOnce([{ exists: false }]);
const provider = createOsmAliasSuggestionProvider(
createMockIntegrationContext({ db: { execute } }),
);

const result = await provider.searchSuggestions(
{ query: "FRA", lang: "en", limit: 8 },
{ signal: new AbortController().signal, deadlineAt: Number.POSITIVE_INFINITY },
);

expect(result).toEqual({ suggestions: [], attributions: [], freshnessSeconds: 86_400 });
expect(execute).toHaveBeenCalledTimes(1);
expect(String(execute.mock.calls[0]?.[0])).toContain("to_regclass('osm_search.index_state')");
});
});
10 changes: 10 additions & 0 deletions integrations/search-osm-aliases/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,16 @@ export function createOsmAliasSuggestionProvider(
): Promise<SearchSuggestionProviderResult> {
signal.throwIfAborted();
if (!ctx.db) return { suggestions: [], attributions: [], freshnessSeconds: 86_400 };
// Until the data-manager builds a first index there is no schema to
// read, which is not a fault of the provider.
const published = await ctx.db.execute<{ exists: boolean }[]>(
"SELECT to_regclass('osm_search.index_state') IS NOT NULL AS exists",
undefined,
{ signal },
);
if (!published[0]?.exists) {
return { suggestions: [], attributions: [], freshnessSeconds: 86_400 };
}
const states = await ctx.db.execute<IndexStateRow[]>(
"SELECT epoch, status FROM osm_search.index_state WHERE singleton = 1",
undefined,
Expand Down
Loading