feat: add location autocomplete
This commit is contained in:
111
tests/location-autocomplete.test.ts
Normal file
111
tests/location-autocomplete.test.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { createElement } from "react";
|
||||
import { renderToStaticMarkup } from "react-dom/server";
|
||||
import {
|
||||
getGoogleMapsLocationCapability,
|
||||
getGoogleMapsPlaceLabel,
|
||||
mapGooglePlacesSuggestions,
|
||||
} from "@/lib/google-maps";
|
||||
|
||||
const renderLocationAutocomplete = async (capability: {
|
||||
enabled: boolean;
|
||||
region: string;
|
||||
reason: "configured" | "missing_server_api_key" | "disabled";
|
||||
}) => {
|
||||
const { LocationAutocomplete } = await import("@/components/location-autocomplete");
|
||||
|
||||
return renderToStaticMarkup(
|
||||
createElement(LocationAutocomplete, {
|
||||
capability,
|
||||
id: "event-location",
|
||||
onChange: () => {},
|
||||
value: "",
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
describe("Google Maps location capability boundary", () => {
|
||||
test("disables Google Maps search when the server API key is missing", () => {
|
||||
expect(getGoogleMapsLocationCapability({ serverApiKey: "" })).toEqual({
|
||||
enabled: false,
|
||||
reason: "missing_server_api_key",
|
||||
region: "us",
|
||||
});
|
||||
});
|
||||
|
||||
test("enables Google Maps search when the server API key is present", () => {
|
||||
expect(
|
||||
getGoogleMapsLocationCapability({ serverApiKey: "maps-server-key", region: "gb" }),
|
||||
).toEqual({
|
||||
enabled: true,
|
||||
reason: "configured",
|
||||
region: "gb",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("LocationAutocomplete fallback mode", () => {
|
||||
test("renders a plain text location field when Google Maps configuration is unavailable", async () => {
|
||||
const markup = await renderLocationAutocomplete({
|
||||
enabled: false,
|
||||
reason: "missing_server_api_key",
|
||||
region: "us",
|
||||
});
|
||||
|
||||
expect(markup).toContain('data-location-mode="manual"');
|
||||
expect(markup).toContain('placeholder="Location"');
|
||||
expect(markup).not.toContain("Search Google Maps");
|
||||
});
|
||||
});
|
||||
|
||||
describe("LocationAutocomplete configured mode", () => {
|
||||
test("renders a server-backed Google Maps-assisted input path while keeping manual typing available", async () => {
|
||||
const markup = await renderLocationAutocomplete({
|
||||
enabled: true,
|
||||
reason: "configured",
|
||||
region: "us",
|
||||
});
|
||||
|
||||
expect(markup).toContain('data-location-mode="google-maps-server"');
|
||||
expect(markup).toContain('placeholder="Search Google Maps or type a location"');
|
||||
expect(markup).toContain("Search Google Maps or keep typing a custom location.");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Google Maps place label selection", () => {
|
||||
test("prefers the chosen prediction label for the visible location value", () => {
|
||||
expect(
|
||||
getGoogleMapsPlaceLabel({
|
||||
displayName: "Google HQ",
|
||||
formattedAddress: "1600 Amphitheatre Parkway, Mountain View, CA",
|
||||
predictionText: "Googleplex",
|
||||
}),
|
||||
).toBe("Googleplex");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Google Places server response mapping", () => {
|
||||
test("maps server autocomplete predictions into lightweight suggestion records", () => {
|
||||
expect(
|
||||
mapGooglePlacesSuggestions({
|
||||
suggestions: [
|
||||
{
|
||||
placePrediction: {
|
||||
place: "places/abc123",
|
||||
structuredFormat: {
|
||||
secondaryText: { text: "Mountain View, CA" },
|
||||
},
|
||||
text: { text: "Googleplex" },
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
).toEqual([
|
||||
{
|
||||
formattedAddress: "Mountain View, CA",
|
||||
placeId: "abc123",
|
||||
text: "Googleplex",
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user