Skip to content

Commit

Permalink
feat: autosuggest place id support (#173)
Browse files Browse the repository at this point in the history
* feat: add Geocoder APIs with test data - getSuggestions, searchByPlaceId

* chore: update getSuggestions and searchByPlaceId APIs with unit tests and proper return types

* fix: fix unit test and check for undefined return value

* chore: use newer version of maplibre-gl-geocoder

* chore: use latest @aws-amplify/geo

* chore: use latest @aws-amplify/geo
  • Loading branch information
sreeramsama committed Oct 19, 2022
1 parent c314eee commit 5f1a3a5
Show file tree
Hide file tree
Showing 4 changed files with 627 additions and 476 deletions.
102 changes: 102 additions & 0 deletions __tests__/AmplifyMapLibreGeocoder.test.ts
Expand Up @@ -7,6 +7,8 @@ describe("AmplifyGeocoderAPI", () => {
beforeEach(() => {
(Geo.searchByText as jest.Mock).mockClear();
(Geo.searchByCoordinates as jest.Mock).mockClear();
(Geo.searchForSuggestions as jest.Mock).mockClear();
(Geo.searchByPlaceId as jest.Mock).mockClear();
});

test("forwardGeocode returns some values in the expected format", async () => {
Expand Down Expand Up @@ -139,4 +141,104 @@ describe("AmplifyGeocoderAPI", () => {
promixity: [-122.431297, 37.773972],
};
});

test("getSuggestions returns some values in the expected format", async () => {
const config = {
query: "a map query",
};
(Geo.searchForSuggestions as jest.Mock).mockReturnValueOnce([
{
text: "a suggestion result",
placeId: "a1b2c3d4",
}
]);
const response = await AmplifyGeocoderAPI.getSuggestions(config);
expect(Geo.searchForSuggestions).toHaveBeenCalledTimes(1);
expect(response.suggestions).toHaveLength(1);
expect(response.suggestions[0].text).toBe("a suggestion result");
expect(response.suggestions[0].placeId).toBe("a1b2c3d4");
});

test("getSuggestions returns empty array on empty response", async () => {
const config = {
query: "a map query",
};
(Geo.searchForSuggestions as jest.Mock).mockReturnValueOnce([]);
const response = await AmplifyGeocoderAPI.getSuggestions(config);
expect(Geo.searchForSuggestions).toHaveBeenCalledTimes(1);
expect(response.suggestions).toHaveLength(0);
});

test("getSuggestions returns empty feature array on undefined response", async () => {
const config = {
query: "a map query",
};
(Geo.searchForSuggestions as jest.Mock).mockReturnValueOnce(undefined);
const response = await AmplifyGeocoderAPI.getSuggestions(config);
expect(Geo.searchForSuggestions).toHaveBeenCalledTimes(1);
expect(response.suggestions).toHaveLength(0);
});

test("getSuggestions returns empty feature array on error", async () => {
const config = {
query: "a map query",
};
(Geo.searchForSuggestions as jest.Mock).mockRejectedValueOnce("an error");
const response = await AmplifyGeocoderAPI.getSuggestions(config);
expect(Geo.searchForSuggestions).toHaveBeenCalledTimes(1);
expect(response.suggestions).toHaveLength(0);
});

test("searchByPlaceId returns some values in the expected format", async () => {
const config = {
query: "a1b2c3d4",
};
(Geo.searchByPlaceId as jest.Mock).mockReturnValueOnce({
addressNumber: "1401",
street: "Broadway",
country: "USA",
postalCode: "98122",
geometry: {
point: [
-122.32108099999999,
47.613897000000065
]
},
label: "Starbucks"
});
const response = await AmplifyGeocoderAPI.searchByPlaceId(config);
expect(Geo.searchByPlaceId).toHaveBeenCalledTimes(1);
expect(response.place?.text).toBe("Starbucks");
expect(response.place?.place_name).toBe("Starbucks");
});

test("searchByPlaceId returns place as undefined on empty request", async () => {
const config = {
query: "",
};
(Geo.searchByPlaceId as jest.Mock).mockReturnValueOnce(undefined);
const response = await AmplifyGeocoderAPI.searchByPlaceId(config);
expect(Geo.searchByPlaceId).toHaveBeenCalledTimes(1);
expect(response.place).toBe(undefined);
});

test("searchByPlaceId returns place as undefined on undefined request", async () => {
const config = {
query: undefined,
};
(Geo.searchByPlaceId as jest.Mock).mockReturnValueOnce(undefined);
const response = await AmplifyGeocoderAPI.searchByPlaceId(config);
expect(Geo.searchByPlaceId).toHaveBeenCalledTimes(1);
expect(response.place).toBe(undefined);
});

test("searchByPlaceId returns place as undefined on error", async () => {
const config = {
query: "something",
};
(Geo.searchByPlaceId as jest.Mock).mockRejectedValueOnce("an error");
const response = await AmplifyGeocoderAPI.searchByPlaceId(config);
expect(Geo.searchByPlaceId).toHaveBeenCalledTimes(1);
expect(response.place).toBe(undefined);
});
});
10 changes: 5 additions & 5 deletions package.json
Expand Up @@ -56,8 +56,8 @@
]
},
"devDependencies": {
"@aws-amplify/core": "^4.5.1",
"@aws-amplify/geo": "^1.3.0",
"@aws-amplify/core": "^4.7.8",
"@aws-amplify/geo": "^1.3.20",
"@babel/preset-env": "^7.16.4",
"@commitlint/cli": "^16.2.1",
"@commitlint/config-conventional": "^16.2.1",
Expand Down Expand Up @@ -91,13 +91,13 @@
"typescript": "^4.3.2"
},
"peerDependencies": {
"@aws-amplify/core": "^4.5.1",
"@aws-amplify/geo": "^1.3.0",
"@aws-amplify/core": "^4.7.8",
"@aws-amplify/geo": "^1.3.20",
"maplibre-gl": "^2.1.9"
},
"dependencies": {
"@mapbox/mapbox-gl-draw": "^1.3.0",
"@maplibre/maplibre-gl-geocoder": "^1.4.2",
"@maplibre/maplibre-gl-geocoder": "^1.5.0",
"@turf/along": "^6.5.0",
"@turf/circle": "^6.5.0",
"@turf/distance": "^6.5.0",
Expand Down
37 changes: 37 additions & 0 deletions src/AmplifyMapLibreGeocoder.ts
Expand Up @@ -58,6 +58,43 @@ export const AmplifyGeocoderAPI = {

return { features };
},
getSuggestions: async (config) => {
const suggestions = [];
try {
const response = await Geo.searchForSuggestions(config.query, {
biasPosition: config.proximity,
searchAreaConstraints: config.bbox,
countries: config.countries,
maxResults: config.limit,
});
suggestions.push(...response);
} catch (e) {
console.error(`Failed to get suggestions with error: ${e}`);
}

return { suggestions };
},
searchByPlaceId: async (config) => {
let feature = undefined;
try {
const place = await Geo.searchByPlaceId(config.query);
if (place) {
const { geometry, ...otherResults } = place;
feature = {
type: "Feature",
geometry: { type: "Point", coordinates: geometry.point },
properties: { ...otherResults },
place_name: otherResults.label,
text: otherResults.label,
center: geometry.point,
}
};
} catch (e) {
console.error(`Failed to get place with error: ${e}`);
}

return { place: feature };
}
};

// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down

0 comments on commit 5f1a3a5

Please sign in to comment.