Files
Jyotisha/frontend/tests/people-archive-order.test.ts
T
jesse-uxandGrok (agent loop) eee8564b7f
Independent Staging Quality Gate / validate (push) Failing after 9m16s
Independent Staging Quality Gate / publish (push) Skipped
星盘档案可以拖动排序,合盘开始前先确认扣点。
人物卡、菜单、编辑和删除换成组件库。chart_profiles 增加可空的 archive_order,本人始终排在第一。合盘选人页两个名字并排,开始按钮居中,点了先说出点数和余额。

自测:tsc 0;lint 0 error(122 警告,与上一张相同);定向测试通过;next build 后 / 仍是 Static;首页 JS gzip-9 639609,相对 640131 少 0.08%。test:db 79 通过、13 失败,失败名单与 windows-known-failures.txt 一致,排序列断言在通过的那一组。没有浏览器登录态。

Co-Authored-By: Grok (agent loop)
2026-10-25 05:05:00 +08:00

51 lines
2.7 KiB
TypeScript

import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import test from "node:test";
import { archiveOrdersForIds, moveArchiveIds, sortByArchiveOrder } from "../src/lib/people-archive-order.ts";
import { synastryChargeCopy } from "../src/components/synastry/synastry-picker.tsx";
test("archive order keeps an untouched list, then puts numbered rows first", () => {
const rows = [
{ id: "b", archiveOrder: null },
{ id: "a", archiveOrder: null },
{ id: "c", archiveOrder: 10 },
];
assert.deepEqual(sortByArchiveOrder(rows.slice(0, 2)).map((row) => row.id), ["b", "a"]);
assert.deepEqual(sortByArchiveOrder(rows).map((row) => row.id), ["c", "b", "a"]);
});
test("moving archive ids never moves self and writes gaps of 10", () => {
assert.deepEqual(moveArchiveIds(["self", "a", "b"], "self", "b"), ["self", "a", "b"]);
assert.deepEqual(moveArchiveIds(["a", "b", "c"], "c", "a"), ["c", "a", "b"]);
assert.deepEqual(moveArchiveIds(["a", "b"], "a", "missing"), ["a", "b"]);
const orders = archiveOrdersForIds(["a", "b", "self"]);
assert.equal(orders.get("a"), 10);
assert.equal(orders.get("b"), 20);
assert.equal(orders.has("self"), false);
});
test("order writes do not touch updated_at, and the start button stays centered", () => {
const route = readFileSync(new URL("../src/app/api/chart-profiles/[id]/route.ts", import.meta.url), "utf8");
const patch = route.slice(route.indexOf("export async function PATCH"));
assert.match(patch, /archive_order: order/);
assert.doesNotMatch(patch, /updated_at/);
assert.match(patch, /id === "self"/);
const list = readFileSync(new URL("../src/app/api/chart-profiles/route.ts", import.meta.url), "utf8");
assert.match(list, /sortByArchiveOrder/);
assert.match(list, /\.order\("updated_at", \{ ascending: false \}\)/);
const css = readFileSync(new URL("../src/app/globals.css", import.meta.url), "utf8");
assert.match(css, /\.synastry-go \{[^}]*align-items:\s*center/);
assert.match(css, /\.synastry-start \{[^}]*margin-inline:\s*auto/);
assert.equal(css.includes(".synastry-times { display: none; }"), false);
assert.match(css, /\.synastry-pick \{ grid-template-columns: minmax\(0, 1fr\); \}/);
assert.match(css, /\.synastry-times \{ justify-self: center; padding-bottom: 0; \}/);
assert.match(css, /\.synastry-go \{ align-items: center; \}/);
});
test("the confirm copy reads the price and the balance", () => {
assert.deepEqual(synastryChargeCopy(19, 40), { short: false, text: "会用掉 19 点,余额 40 点。" });
assert.deepEqual(synastryChargeCopy(19, 3), { short: true, text: "需要 19 点,余额只有 3 点。" });
assert.equal(synastryChargeCopy(19, 19).short, false);
});