import { describe, expect, it } from "vitest"; import { haversineDistanceKm, isPostalCodeListed, isWithinRadiusKm, normalizePostalCode, sortByDistance, } from "../../app/lib/geo"; // Known reference distances (verifiable against any mapping service): const TORONTO = { lat: 43.6532, lng: -79.3832 }; const OTTAWA = { lat: 45.4215, lng: -75.6972 }; const KITCHENER = { lat: 43.4516, lng: -80.4925 }; describe("haversineDistanceKm", () => { it("is zero for the same point", () => { expect(haversineDistanceKm(TORONTO, TORONTO)).toBeCloseTo(0, 5); }); it("is symmetric", () => { expect(haversineDistanceKm(TORONTO, OTTAWA)).toBeCloseTo(haversineDistanceKm(OTTAWA, TORONTO), 8); }); it("matches the known Toronto-Ottawa distance within a reasonable tolerance", () => { // Real-world straight-line distance is ~352 km. expect(haversineDistanceKm(TORONTO, OTTAWA)).toBeGreaterThan(340); expect(haversineDistanceKm(TORONTO, OTTAWA)).toBeLessThan(365); }); it("Kitchener is closer to Toronto than Ottawa is", () => { expect(haversineDistanceKm(TORONTO, KITCHENER)).toBeLessThan(haversineDistanceKm(TORONTO, OTTAWA)); }); }); describe("isWithinRadiusKm", () => { it("is true when distance is under the radius", () => { expect(isWithinRadiusKm(TORONTO, KITCHENER, 200)).toBe(true); }); it("is false when distance exceeds the radius", () => { expect(isWithinRadiusKm(TORONTO, OTTAWA, 100)).toBe(false); }); it("is true exactly at the boundary", () => { const d = haversineDistanceKm(TORONTO, OTTAWA); expect(isWithinRadiusKm(TORONTO, OTTAWA, d)).toBe(true); }); }); describe("normalizePostalCode / isPostalCodeListed", () => { it("normalizes case and whitespace", () => { expect(normalizePostalCode("v6b 1a1")).toBe("V6B1A1"); expect(normalizePostalCode(" M5V 3A8 ")).toBe("M5V3A8"); }); it("matches regardless of formatting differences", () => { expect(isPostalCodeListed("m5v3a8", ["M5V 3A8", "N2G 1A1"])).toBe(true); }); it("does not match a postal code outside the list", () => { expect(isPostalCodeListed("K1A 0A6", ["M5V 3A8", "N2G 1A1"])).toBe(false); }); }); describe("sortByDistance", () => { it("orders items nearest-first", () => { const items = [ { name: "Ottawa", coordinates: OTTAWA }, { name: "Kitchener", coordinates: KITCHENER }, ]; expect(sortByDistance(TORONTO, items).map((i) => i.name)).toEqual(["Kitchener", "Ottawa"]); }); it("does not mutate the input array", () => { const items = [ { name: "Ottawa", coordinates: OTTAWA }, { name: "Kitchener", coordinates: KITCHENER }, ]; const original = [...items]; sortByDistance(TORONTO, items); expect(items).toEqual(original); }); });