/g)].length;
const wraps = [...source.matchAll(//g)].length;
assert.equal(wraps, tables);
@@ -264,7 +259,9 @@ test("the chart page shell is visible before the natal chart arrives", () => {
// 原因:2026-09-24 D1 仅授权星盘盘位骨架(BUG-1016)。
assert.match(markup, /data-skeleton="true"/);
assert.match(markup, /aria-busy="true"/);
- assert.equal((markup.match(/disabled=""/g) ?? []).length, 5);
+ // 原值: 5 个禁用 Tab;新值: 4 个(CHART_VIEW_TABS.length);原因: 七政 Tab 已删(TASK-chart-types D1)
+ assert.equal((markup.match(/disabled=""/g) ?? []).length, CHART_VIEW_TABS.length);
+ assert.equal(CHART_VIEW_TABS.length, 4);
assert.doesNotMatch(markup, /正在加载|InlineSpinner|spinner|打开即有/i);
assert.doesNotMatch(markup, /chart-page-eyebrow/);
});
@@ -332,18 +329,20 @@ test("varga pending shows the empty shared chart and failure replaces it", async
assert.match(render(true, "engine_busy"), /data-skeleton="true"/);
});
-test("western qizheng and chara failures are terminal copy rather than waiting", async () => {
+// 原值: western / qizheng / chara 三栏;新值: 去掉 qizheng;原因: 七政 Tab 已删(TASK-chart-types D1)
+test("western and chara failures are terminal copy rather than waiting", async () => {
const view = await okView();
- for (const [tab, layer] of [["western", "western"], ["qizheng", "qizheng"], ["dasha", "chara"]] as const) {
+ for (const [tab, layer] of [["western", "western"], ["dasha", "chara"]] as const) {
const markup = withSidebarProvider(React.createElement(ChartPageView, { view, initialTab: tab, layerFailures: new Map([[layer, "engine_busy" as const]]) }));
assert.ok(markup.includes(CHART_VIEW_COPY.busy)); assert.doesNotMatch(markup, /data-skeleton|这一栏还没拿到/);
if (tab === "dasha") assert.match(markup, /Vimshottari/);
}
});
-test("qizheng and chara pending remain static and only western has a wheel skeleton", async () => {
+// 原值: qizheng 与 chara 两栏;新值: 只剩 chara;原因: 七政 Tab 已删(TASK-chart-types D1)
+test("chara pending remains static and only western has a wheel skeleton", async () => {
const view = await okView();
- for (const [tab, layer] of [["qizheng", "qizheng"], ["dasha", "chara"]] as const) {
+ for (const [tab, layer] of [["dasha", "chara"]] as const) {
const markup = withSidebarProvider(React.createElement(ChartPageView, { view, initialTab: tab, pendingLayers: new Set([layer]) }));
assert.match(markup, /这一栏还没拿到/); assert.doesNotMatch(markup, /data-skeleton|InlineSpinner/);
}
diff --git a/frontend/tests/chart-view-engine.test.ts b/frontend/tests/chart-view-engine.test.ts
index 0381ae69..917ea0e4 100644
--- a/frontend/tests/chart-view-engine.test.ts
+++ b/frontend/tests/chart-view-engine.test.ts
@@ -121,5 +121,6 @@ test("engine cache keys include ayanamsa and node mode and expire", () => {
test("layer query parsing keeps only known layers in stable order", () => {
assert.deepEqual(parseChartViewLayers(null), []);
- assert.deepEqual(parseChartViewLayers("western,varga,nope,qizheng"), ["varga", "western", "qizheng"]);
+ // 原值: "qizheng" 被保留为已知层;新值: 与 "nope" 一样被丢弃;原因: 七政层已删(TASK-chart-types D1)
+ assert.deepEqual(parseChartViewLayers("western,varga,nope,qizheng"), ["varga", "western"]);
});
diff --git a/frontend/tests/chart-view-route.test.ts b/frontend/tests/chart-view-route.test.ts
index 955c20d7..c2e39b11 100644
--- a/frontend/tests/chart-view-route.test.ts
+++ b/frontend/tests/chart-view-route.test.ts
@@ -65,7 +65,6 @@ function engine(overrides: Record
assert.equal(body.billed, false);
assert.ok(body.vedic.vargas.some((item) => item.id === "D1"));
assert.equal(body.western.status, "unavailable");
- assert.equal(body.qizheng.status, "unavailable");
+ // 原值: body.qizheng.status === "unavailable";新值: 响应不再带 qizheng;原因: TASK-chart-types D1
+ assert.equal("qizheng" in body, false);
assert.deepEqual(calls, ["/api/chart"]);
});
-test("western and qizheng stay unavailable without failing the Indian tabs", async () => {
+test("western stays unavailable without failing the Indian tabs", async () => {
const { calls, postEngine } = engine();
const result = await assembleChartView({
userId: "user-1",
@@ -183,18 +183,18 @@ test("western and qizheng stay unavailable without failing the Indian tabs", asy
assert.equal(body.dasha.vimshottari.method, "Vimshottari");
assert.equal(body.dasha.chara.title, "Chara Dasha(kn_rao 变体)");
assert.equal(body.western.status, "unavailable");
- assert.equal(body.qizheng.status, "unavailable");
assert.ok(body.vedic.vargas.some((item) => item.id === "D9"));
// 原值: 无 layers 时也会打 /api/western 与 /api/qizheng
// 新值: 只有请求对应 layer 才打
// 原因: BUG-717 开页不得占满重计算配额;西洋/七政改按需
assert.equal(calls.includes("/api/western"), true);
- assert.equal(calls.includes("/api/qizheng"), true);
+ // 原值: 全部 layer 时会打 /api/qizheng;新值: 任何情况都不打;原因: 七政层已删(TASK-chart-types D1)
+ assert.equal(calls.includes("/api/qizheng"), false);
assert.doesNotMatch(calls.join(" "), /billing|mastra|consult/);
});
test("a real western engine packet lights the tropical tab without mixing sidereal longitudes", async () => {
- const { postEngine } = engine({ "/api/western": golden.western, "/api/qizheng": null });
+ const { postEngine } = engine({ "/api/western": golden.western });
const result = await assembleChartView({
userId: "user-1",
profile,
@@ -209,30 +209,10 @@ test("a real western engine packet lights the tropical tab without mixing sidere
assert.equal(body.western.houses.length, 12);
assert.match(body.western.boundary, /回归黄道/);
assert.notEqual(body.western.ascendantLongitude, body.vedic.planets[0]?.degreeInSign);
- assert.equal(body.qizheng.status, "unavailable");
-});
-
-test("qizheng ketuMode follows the engine field, not a request echo", async () => {
- const qizheng = {
- coordinate_system: "qizheng_mansion_degrees_from_jiao",
- calculation: { ketu_mode: "descending-node", engine_ketu_mode: "apogee" },
- palaces: [{ name: "午", branch: "午", lifePalace: "命宫", mansions: ["星"], occupants: [] }],
- bodies: { sun: { mansion: "奎", siderealLon: 177.94, palace: "亥宮", dignity: "陷" } },
- };
- const { postEngine } = engine({ "/api/qizheng": qizheng });
- const result = await assembleChartView({
- userId: "user-1",
- profile,
- postEngine,
- asOf: "2026-09-15",
- layers: ["qizheng"],
- });
- const body = chartViewOkSchema.parse(result.body);
- assert.equal(body.qizheng.status, "ok");
- if (body.qizheng.status !== "ok") throw new Error("expected qizheng ok");
- assert.equal(body.qizheng.ketuMode, "apogee");
});
+// 原值: 断言七政 ketuMode 取引擎字段;新值: 整条删除;原因: 七政层已从星盘页删除(TASK-chart-types D1),
+// ketu_mode 的引擎侧合同仍由 tests/test_qizheng_api_productization.py 守住
test("busy vs other natal engine failures split copy and each leave a log line", async () => {
const stubs: Array<{ status: EngineCallResult["status"]; httpStatus?: number; errorName?: string }> = [
{ status: "busy", httpStatus: 429 },
@@ -298,7 +278,9 @@ test("the golden chart-view envelope stays inside the page contract", () => {
});
assert.match(COORDINATE_BOUNDARY.vedic, /不能换算/);
assert.match(COORDINATE_BOUNDARY.western, /不能换算/);
- assert.match(COORDINATE_BOUNDARY.qizheng, /角宿/);
+ // 原值: COORDINATE_BOUNDARY.qizheng 含「角宿」;新值: 该条已删,印度/西洋两句不再提七政;原因: TASK-chart-types D1
+ assert.equal("qizheng" in COORDINATE_BOUNDARY, false);
+ assert.doesNotMatch(COORDINATE_BOUNDARY.vedic + COORDINATE_BOUNDARY.western, /七政/);
});
test("page.tsx does not host the chart page", () => {
diff --git a/frontend/tests/chart-view-zero-year.test.ts b/frontend/tests/chart-view-zero-year.test.ts
index d2c460c4..3f31177e 100644
--- a/frontend/tests/chart-view-zero-year.test.ts
+++ b/frontend/tests/chart-view-zero-year.test.ts
@@ -44,7 +44,6 @@ function viewFrom(chara: Record): ChartViewOk {
varga: null,
chara,
western: null,
- qizheng: null,
profile,
asOf: "2026-09-25",
});