112 lines
3.1 KiB
TypeScript
112 lines
3.1 KiB
TypeScript
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",
|
|
},
|
|
]);
|
|
});
|
|
});
|