import assert from "node:assert/strict"; import { readFileSync } from "node:fs"; import test from "node:test"; import React from "react"; import { renderToStaticMarkup } from "react-dom/server"; import { PeopleArchiveView, type PeopleArchiveViewProps, type PersonRow } from "../src/components/people/people-page.tsx"; import { emptyProfile, type Profile } from "../src/lib/home-types.ts"; import { PEOPLE_AVATAR_TONES, peopleAvatarInitial, peopleAvatarTone, peopleAyanamsaLabel, peopleCityLabel, peopleRowMeta, peopleTimeRectified, } from "../src/lib/people-archive-view.ts"; import { cssDeclarations } from "./css-contract-test-support.ts"; Object.assign(globalThis, { React }); const css = readFileSync(new URL("../src/app/globals.css", import.meta.url), "utf8"); const source = readFileSync(new URL("../src/components/people/people-page.tsx", import.meta.url), "utf8"); /* Fictional people only (AGENTS §8). */ const selfProfile: Profile = { ...emptyProfile, name: "示例甲", date: "1990-01-02", time: "04:53", reportedTime: "05:00", birthTimeStatus: "accepted", rectificationCaseId: "fictional-case-1", activeDate: "1990-01-02", birthPlaceLabel: "中国 · 浙江省 · 杭州市 · 西湖区", latitude: 30.25, longitude: 120.13, timezoneId: "Asia/Shanghai", timezoneOffset: 8, ayanamsa: "raman", }; const otherProfile: Profile = { ...emptyProfile, name: "示例乙", date: "1992-03-12", time: "10:01", reportedTime: "10:01", birthTimeStatus: "reported", birthPlaceLabel: "Lisbon, Portugal", latitude: 38.72, longitude: -9.14, timezoneId: "Europe/Lisbon", timezoneOffset: 0, ayanamsa: "lahiri", }; const people: PersonRow[] = [ { id: "self", role: "self", profile: selfProfile, incomplete: false }, { id: "11111111-1111-4111-8111-111111111111", role: "other", profile: otherProfile, incomplete: false }, ]; function props(overrides: Partial = {}): PeopleArchiveViewProps { const noop = () => {}; const asyncNoop = async () => {}; return { people, subjectId: "self", selected: people[0], selectedId: "self", view: "list", editing: false, draft: emptyProfile, notice: "", pendingDelete: null, saving: false, atLimit: false, onSelect: noop, onBack: noop, onAdd: noop, onEdit: noop, onCancelEdit: noop, onDraftChange: noop, saveOther: asyncNoop, askDelete: asyncNoop, onCancelDelete: noop, confirmDelete: asyncNoop, openPerson: noop, ...overrides, }; } const render = (overrides: Partial = {}) => renderToStaticMarkup(React.createElement(PeopleArchiveView, props(overrides))); test("D2 list rows: avatar, name, 本人 tag, one monospace meta line, chevron", () => { const markup = render(); assert.equal([...markup.matchAll(/class="people-archive-row[ "]/g)].length, 2); assert.match(markup, /