Files
Jyotisha/frontend/tests/ai-generated-notice-20261014.test.ts
T
jesse-uxandGrok (agent loop) 29949e0a29
Independent Staging Quality Gate / validate (push) Failing after 8m31s
Independent Staging Quality Gate / publish (push) Skipped
接受删除旧报告页,并跟上最新 staging
旧的结构化报告页已由另一单删除,标识留在现在用的阅读页。测试不再读取那个文件。更新日志和 Bug 历史两边都保留。

自测:tsc 退出码 0;lint 0 error、123 warning;修复单点名的 3 个测试 7 通过、0 失败、0 取消。

Co-Authored-By: Grok (agent loop)
2026-10-14 12:27:33 +08:00

71 lines
3.1 KiB
TypeScript

import assert from "node:assert/strict";
import { createElement, createRef } from "react";
import { readFileSync } from "node:fs";
import test from "node:test";
import { renderToStaticMarkup } from "react-dom/server";
import { ChatComposer } from "../src/components/chat-composer.tsx";
import { PersonalReportMarkdownView } from "../src/components/personal-report/personal-report-markdown-view.tsx";
import {
CHAT_AI_NOTICE_EN,
CHAT_AI_NOTICE_ZH,
REPORT_AI_NOTICE_EN,
REPORT_AI_NOTICE_ZH,
} from "../src/lib/ai-generated-notice.ts";
const styles = readFileSync(new URL("../src/app/globals.css", import.meta.url), "utf8");
const page = readFileSync(new URL("../src/app/(app)/page.tsx", import.meta.url), "utf8");
const rectification = readFileSync(new URL("../src/components/rectification-agentic-chat.tsx", import.meta.url), "utf8");
function composerHtml(): string {
return renderToStaticMarkup(createElement(ChatComposer, {
inputRef: createRef<HTMLTextAreaElement>(),
value: "",
inputLabel: "输入你的问题",
placeholder: "想聊什么都可以",
maxLength: 500,
inputDisabled: false,
submitLabel: "发送",
submitBlocked: false,
stopVisible: false,
stopLabel: "停止回答",
stopTitle: "停止回答",
onSubmit() {},
onChange() {},
onKeyDown() {},
onStop() {},
}));
}
test("both chat surfaces share the composer notice, under the field and not over the send control", () => {
assert.equal(CHAT_AI_NOTICE_ZH, "回答由 AI 生成,仅供参考,不构成医疗、法律或投资建议。");
assert.equal(CHAT_AI_NOTICE_EN, "AI-generated. For reference only; not medical, legal or financial advice.");
const html = composerHtml();
const noticeAt = html.indexOf("composer-ai-notice");
const sendAt = html.indexOf("发送");
assert.ok(noticeAt > sendAt, "the notice follows the send control");
assert.match(html, new RegExp(CHAT_AI_NOTICE_ZH));
assert.match(page, /<ChatComposer/);
assert.match(rectification, /<ChatComposer/);
assert.doesNotMatch(page, /CHAT_AI_NOTICE_ZH|composer-ai-notice/);
assert.doesNotMatch(rectification, /CHAT_AI_NOTICE_ZH|composer-ai-notice/);
assert.match(styles, /\.composer-ai-notice\s*\{[^}]*white-space:\s*nowrap/);
assert.match(styles, /\.composer-ai-notice\s*\{[^}]*overflow:\s*hidden/);
assert.doesNotMatch(styles, /\.composer-footer\s*\{/);
});
test("report readers show the AI notice in Chinese and English under the title", () => {
assert.equal(REPORT_AI_NOTICE_ZH, "本报告由 AI 生成,仅供参考。");
assert.equal(REPORT_AI_NOTICE_EN, "This report is AI-generated and for reference only.");
const chinese = renderToStaticMarkup(createElement(PersonalReportMarkdownView, {
markdown: "# 虚构报告\n\n一段说明。",
language: "zh",
}));
const english = renderToStaticMarkup(createElement(PersonalReportMarkdownView, {
markdown: "# Fictional report\n\nA paragraph.",
language: "en",
}));
assert.ok(chinese.indexOf("<h1>") < chinese.indexOf(REPORT_AI_NOTICE_ZH));
assert.match(english, new RegExp(REPORT_AI_NOTICE_EN.replaceAll(".", "\\.")));
});