Files
Jyotisha/frontend/tests/birth-place-picker.test.ts
Jesse_Chen 54269fcfcc
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled
refactor(chat): extract home helpers, chart library, and starter surfaces
page.tsx still owns the chat main chain, but the first product surfaces now
live in their own modules so later splits can land without editing the 4k-line
Home. Source-lock tests follow the moved tokens; the orphan user-data contract
is aligned and added to the quick gate.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-01 22:58:02 +08:00

149 lines
7.7 KiB
TypeScript

import assert from "node:assert/strict";
import { existsSync, readFileSync } from "node:fs";
import test from "node:test";
import {
birthPlaceDraftFromLevels,
formatBirthPlaceCoordinate,
formatBirthPlaceTimezone,
hasVirtualCityLevel,
findProvinceNode,
resolveBirthPlaceNode,
} from "../src/lib/china-birth-place.ts";
import { homeSurface as pageSource } from "./home-surface.ts";
const pickerSource = readFileSync(new URL("../src/components/birth-place-picker.tsx", import.meta.url), "utf8");
test("resolves a province, city and district to the district centre", () => {
const resolved = resolveBirthPlaceNode({ provinceCode: "130000", cityCode: "130400", districtCode: "130402" });
assert.ok(resolved);
assert.equal(resolved.label, "河北省 · 邯郸市 · 邯山区");
assert.equal(resolved.placeType, "district");
assert.equal(resolved.node.code, "130402");
assert.equal(resolved.latitude, 36.603196);
assert.equal(resolved.longitude, 114.484989);
});
test("falls back to the city centre when the district is left unnamed", () => {
const resolved = resolveBirthPlaceNode({ provinceCode: "130000", cityCode: "130400", districtCode: "" });
assert.ok(resolved);
assert.equal(resolved.label, "河北省 · 邯郸市");
assert.equal(resolved.placeType, "city");
assert.equal(resolved.node.code, "130400");
assert.equal(resolved.latitude, 36.612273);
});
test("collapses the repeated city level of municipalities and special regions", () => {
assert.equal(hasVirtualCityLevel(findProvinceNode("110000")!), true);
assert.equal(hasVirtualCityLevel(findProvinceNode("130000")!), false);
// The city code may be absent because the picker never shows that level.
const resolved = resolveBirthPlaceNode({ provinceCode: "110000", cityCode: "", districtCode: "110105" });
assert.ok(resolved);
assert.equal(resolved.label, "北京市 · 朝阳区");
assert.equal(resolved.placeType, "district");
});
test("completes at the city for prefecture cities that have no districts", () => {
const resolved = resolveBirthPlaceNode({ provinceCode: "440000", cityCode: "441900", districtCode: "" });
assert.ok(resolved);
assert.equal(resolved.label, "广东省 · 东莞市");
assert.equal(resolved.placeType, "city");
assert.equal(resolved.node.code, "441900");
});
test("completes at the province when neither lower level offers a choice", () => {
const resolved = resolveBirthPlaceNode({ provinceCode: "710000", cityCode: "", districtCode: "" });
assert.ok(resolved);
assert.equal(resolved.label, "台湾省");
assert.equal(resolved.placeType, "province");
});
test("rejects codes that do not belong together", () => {
assert.equal(resolveBirthPlaceNode({ provinceCode: "999999", cityCode: "", districtCode: "" }), null);
assert.equal(resolveBirthPlaceNode({ provinceCode: "130000", cityCode: "440100", districtCode: "" }), null);
assert.equal(resolveBirthPlaceNode({ provinceCode: "130000", cityCode: "130400", districtCode: "110105" }), null);
});
test("re-syncing a saved profile keeps the same draft so the picker cannot clear itself", () => {
const saved = { provinceCode: "130000", cityCode: "130400", districtCode: "" };
const draft = birthPlaceDraftFromLevels(saved);
assert.deepEqual(draft, { provinceCode: "130000", cityCode: "130400", districtCode: "", cityCentre: true });
assert.deepEqual(birthPlaceDraftFromLevels(draft), draft);
// A city without districts is complete without being marked as an unsure centre.
assert.deepEqual(birthPlaceDraftFromLevels({ provinceCode: "440000", cityCode: "441900", districtCode: "" }), {
provinceCode: "440000",
cityCode: "441900",
districtCode: "",
cityCentre: false,
});
// A municipality resumes with its virtual city filled in.
assert.deepEqual(birthPlaceDraftFromLevels({ provinceCode: "110000", cityCode: "", districtCode: "110105" }), {
provinceCode: "110000",
cityCode: "110000-city",
districtCode: "110105",
cityCentre: false,
});
});
test("states coordinates and the resolved offset in plain Chinese", () => {
assert.equal(formatBirthPlaceCoordinate(36.612273, 114.490686), "东经 114.49° · 北纬 36.61°");
assert.equal(formatBirthPlaceTimezone("Asia/Shanghai", 8), "Asia/Shanghai · UTC+8");
assert.equal(formatBirthPlaceTimezone("Asia/Kathmandu", 5.75), "Asia/Kathmandu · UTC+5:45");
assert.equal(formatBirthPlaceTimezone("Asia/Shanghai", null), "Asia/Shanghai");
});
test("the picker offers three cascading levels instead of a free-text search", () => {
assert.equal(existsSync(new URL("../src/components/location-search-combobox.tsx", import.meta.url)), false);
assert.doesNotMatch(pickerSource, /role="combobox"/);
assert.match(pickerSource, /aria-label="出生省份"/);
assert.match(pickerSource, /aria-label="出生城市"/);
assert.match(pickerSource, /aria-label="出生区县"/);
// The level is hidden rather than shown empty when it carries no choice.
assert.match(pickerSource, /\{isChina && province && !virtualCity && \(/);
assert.match(pickerSource, /\{isChina && city && districts\.length > 0 && \(/);
assert.match(pickerSource, /不确定,用市区中心/);
assert.match(pickerSource, /精确到区 \/ 县就足够/);
});
test("timezone is resolved once for the chosen place rather than during browsing", () => {
assert.equal(existsSync(new URL("../src/app/api/locations/timezone/route.ts", import.meta.url)), true);
assert.match(pickerSource, /fetch\("\/api\/locations\/timezone"/);
// Browsing the levels cannot spend a lookup: only a resolved place gets a sync key.
assert.match(pickerSource, /if \(syncKey === "empty"\)/);
assert.match(pickerSource, /: \{ status: "loading" \};/);
// An unresolved zone must not be reported upward as a usable birth place.
assert.match(pickerSource, /setOutcome\(\{ key: syncKey, state: \{ status: "error" \} \}\);\s*onChangeRef\.current\(null\);/);
const service = readFileSync(new URL("../src/lib/birth-location-timezone-service.ts", import.meta.url), "utf8");
assert.match(service, /\/api\/location\/timezone/);
assert.match(service, /timezoneSource: "iana_historical"/);
});
test("mounting a saved birth place neither refetches nor clears the stored location", () => {
// Reporting null on mount would look like a location edit and would drop a
// rectified birth-time candidate just because the profile dialog was opened.
assert.match(pickerSource, /const savedIsCurrent = resolved !== null/);
assert.match(pickerSource, /if \(syncKey === "saved"\) return;/);
assert.match(pickerSource, /if \(saved\.countryCode !== "CN" \|\| saved\.provinceCode \|\| saved\.timezoneId\) onChangeRef\.current\(null\);/);
// A changed birth date invalidates the stored offset, so the zone is resolved again.
assert.match(pickerSource, /mountedMoment === birthMoment/);
});
test("the profile stores administrative codes alongside coordinates and the IANA zone", () => {
assert.match(pageSource, /<BirthPlacePicker/);
assert.match(pageSource, /provinceCode: location\?\.provinceCode \|\| ""/);
assert.match(pageSource, /cityCode: location\?\.cityCode \|\| ""/);
assert.match(pageSource, /districtCode: location\?\.districtCode \|\| ""/);
assert.match(pageSource, /birthPlaceProvider: location\?\.provider \|\| ""/);
assert.match(pageSource, /timezoneSource: location \? "iana_historical" : ""/);
assert.match(pageSource, /birth_place_provider_id:\s*nextProfile\.birthPlaceProviderId/);
assert.match(pageSource, /timezone_id:\s*nextProfile\.timezoneId/);
});
test("profile accepts a selected IANA location before a numeric offset is resolved", () => {
assert.match(pageSource, /profile\.timezoneId\.trim\(\)/);
assert.match(pageSource, /profile\.timezoneOffset === null \|\| Number\.isFinite\(profile\.timezoneOffset\)/);
});