mirror of
https://github.com/sinanyuntu/trade-message-center.git
synced 2026-09-17 13:22:11 +08:00
225 lines
8.6 KiB
JavaScript
225 lines
8.6 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
import { installOneTalkActionStatusTooltip } from "../src/onetalk/main-page/dom/action-status-tooltip.ts";
|
|
import { ConnectionStatusTooltip } from "../src/onetalk/main-page/connection-status-tooltip.ts";
|
|
import { HistoryBootstrapProgressTooltip } from "../src/onetalk/main-page/current-conversation-history/bootstrap-progress-tooltip.ts";
|
|
|
|
class FakeElement {
|
|
constructor() {
|
|
this.attributes = new Map();
|
|
this.children = [];
|
|
this.dataset = {};
|
|
this.parent = null;
|
|
this.style = { cssText: "" };
|
|
this.textContent = "";
|
|
}
|
|
|
|
setAttribute(name, value) {
|
|
this.attributes.set(name, value);
|
|
}
|
|
|
|
getAttribute(name) {
|
|
return this.attributes.get(name) ?? null;
|
|
}
|
|
|
|
append(element) {
|
|
if (element.parent) {
|
|
element.parent.children = element.parent.children.filter((child) => child !== element);
|
|
}
|
|
element.parent = this;
|
|
this.children.push(element);
|
|
}
|
|
|
|
get parentElement() {
|
|
return this.parent;
|
|
}
|
|
|
|
remove() {
|
|
if (!this.parent) return;
|
|
this.parent.children = this.parent.children.filter((child) => child !== this);
|
|
this.parent = null;
|
|
}
|
|
}
|
|
|
|
const hasAttribute = (element, attribute) => element.attributes.has(attribute);
|
|
|
|
const findByAttribute = (element, attribute) => {
|
|
if (hasAttribute(element, attribute)) return element;
|
|
for (const child of element.children) {
|
|
const match = findByAttribute(child, attribute);
|
|
if (match) return match;
|
|
}
|
|
return null;
|
|
};
|
|
|
|
const createPageWindow = () => {
|
|
const body = new FakeElement();
|
|
const document = {
|
|
body,
|
|
createElement: () => new FakeElement(),
|
|
querySelector: (selector) => {
|
|
const attribute = selector.match(/^div\[([^\]]+)\]$/u)?.[1];
|
|
return attribute ? findByAttribute(body, attribute) : null;
|
|
},
|
|
};
|
|
return { document };
|
|
};
|
|
|
|
const tooltipFor = (pageWindow) => {
|
|
installOneTalkActionStatusTooltip(pageWindow);
|
|
return pageWindow.__tradeMessageCenterOneTalk.tooltip;
|
|
};
|
|
|
|
test("starts one neutral status row and does not duplicate its id", () => {
|
|
const pageWindow = createPageWindow();
|
|
const tooltip = tooltipFor(pageWindow);
|
|
|
|
tooltip.start("collect-history", "正在收集所有对话历史");
|
|
tooltip.start("collect-history", "不应覆盖已有动作", "error");
|
|
|
|
const container = pageWindow.document.body.children[0];
|
|
assert.equal(container.getAttribute("aria-live"), "polite");
|
|
assert.match(container.style.cssText, /position: fixed/u);
|
|
assert.match(container.style.cssText, /top: 0/u);
|
|
assert.match(container.style.cssText, /pointer-events: none/u);
|
|
assert.equal(container.children.length, 1);
|
|
assert.equal(container.children[0].textContent, "正在收集所有对话历史");
|
|
assert.equal(container.children[0].dataset.tmcActionStatusId, "collect-history");
|
|
assert.equal(container.children[0].getAttribute("data-tmc-action-status-color"), "neutral");
|
|
assert.match(container.children[0].style.cssText, /background: #f5f5f5/u);
|
|
});
|
|
|
|
test("updates only its existing id and preserves insertion order", () => {
|
|
const pageWindow = createPageWindow();
|
|
const tooltip = tooltipFor(pageWindow);
|
|
|
|
tooltip.start("collect-history", "正在收集所有对话历史");
|
|
tooltip.start("sync-profile", "正在同步联系人资料", "info");
|
|
|
|
assert.equal(tooltip.update("missing", "不会创建"), false);
|
|
assert.equal(tooltip.update("collect-history", "已收集一半", "warning"), true);
|
|
|
|
const rows = pageWindow.document.body.children[0].children;
|
|
assert.deepEqual(
|
|
rows.map((row) => row.dataset.tmcActionStatusId),
|
|
["collect-history", "sync-profile"],
|
|
);
|
|
assert.equal(rows[0].textContent, "已收集一半");
|
|
assert.equal(rows[0].getAttribute("data-tmc-action-status-color"), "warning");
|
|
assert.match(rows[0].style.cssText, /color: #d48806/u);
|
|
assert.equal(rows[1].getAttribute("data-tmc-action-status-color"), "info");
|
|
});
|
|
|
|
test("rejects raw CSS colors and closes only the requested status", () => {
|
|
const pageWindow = createPageWindow();
|
|
const tooltip = tooltipFor(pageWindow);
|
|
|
|
assert.throws(() => tooltip.start("collect-history", "正在收集所有对话历史", "#ff0000"));
|
|
tooltip.start("collect-history", "正在收集所有对话历史", "error");
|
|
tooltip.start("sync-profile", "正在同步联系人资料");
|
|
assert.throws(() => tooltip.update("collect-history", "不应应用", "#ff0000"));
|
|
assert.equal(
|
|
pageWindow.document.body.children[0].children[0].textContent,
|
|
"正在收集所有对话历史",
|
|
);
|
|
|
|
assert.equal(tooltip.close("missing"), false);
|
|
assert.equal(tooltip.close("collect-history"), true);
|
|
assert.equal(pageWindow.document.body.children[0].children.length, 1);
|
|
assert.equal(
|
|
pageWindow.document.body.children[0].children[0].dataset.tmcActionStatusId,
|
|
"sync-profile",
|
|
);
|
|
assert.equal(tooltip.close("sync-profile"), true);
|
|
assert.equal(pageWindow.document.body.children.length, 0);
|
|
});
|
|
|
|
test("reuses the installed facade when page features install again", () => {
|
|
const pageWindow = createPageWindow();
|
|
const first = tooltipFor(pageWindow);
|
|
first.start("collect-history", "正在收集所有对话历史");
|
|
|
|
const second = tooltipFor(pageWindow);
|
|
|
|
assert.equal(second, first);
|
|
assert.equal(pageWindow.document.body.children[0].children.length, 1);
|
|
});
|
|
|
|
test("remounts active statuses after the page removes the extension container", () => {
|
|
const pageWindow = createPageWindow();
|
|
const tooltip = tooltipFor(pageWindow);
|
|
tooltip.start("collect-history", "正在收集所有对话历史");
|
|
pageWindow.document.body.children[0].remove();
|
|
|
|
assert.equal(tooltip.update("collect-history", "正在收集所有对话历史(已恢复)"), true);
|
|
|
|
assert.equal(pageWindow.document.body.children.length, 1);
|
|
assert.equal(pageWindow.document.body.children[0].children.length, 1);
|
|
assert.equal(
|
|
pageWindow.document.body.children[0].children[0].textContent,
|
|
"正在收集所有对话历史(已恢复)",
|
|
);
|
|
});
|
|
|
|
test("reinstalls active statuses when the existing facade is mounted again", () => {
|
|
const pageWindow = createPageWindow();
|
|
const tooltip = tooltipFor(pageWindow);
|
|
tooltip.start("collect-history", "正在收集所有对话历史");
|
|
pageWindow.document.body.children[0].remove();
|
|
|
|
installOneTalkActionStatusTooltip(pageWindow);
|
|
|
|
assert.equal(pageWindow.document.body.children.length, 1);
|
|
assert.equal(pageWindow.document.body.children[0].children.length, 1);
|
|
assert.equal(
|
|
pageWindow.document.body.children[0].children[0].textContent,
|
|
"正在收集所有对话历史",
|
|
);
|
|
});
|
|
|
|
test("restores a detached active row when its container remains mounted", () => {
|
|
const pageWindow = createPageWindow();
|
|
const tooltip = tooltipFor(pageWindow);
|
|
tooltip.start("collect-history", "正在收集所有对话历史");
|
|
const container = pageWindow.document.body.children[0];
|
|
container.children[0].remove();
|
|
|
|
assert.equal(tooltip.update("collect-history", "正在收集所有对话历史(已恢复)"), true);
|
|
|
|
assert.equal(container.children.length, 1);
|
|
assert.equal(container.children[0].textContent, "正在收集所有对话历史(已恢复)");
|
|
});
|
|
|
|
test("keeps the disconnect warning independent from history progress through remount and close", () => {
|
|
const pageWindow = createPageWindow();
|
|
const tooltip = tooltipFor(pageWindow);
|
|
const history = new HistoryBootstrapProgressTooltip(tooltip);
|
|
const connection = new ConnectionStatusTooltip(tooltip);
|
|
history.beginDiscovery();
|
|
connection.update(true);
|
|
connection.update(true);
|
|
|
|
let rows = pageWindow.document.body.children[0].children;
|
|
assert.deepEqual(
|
|
rows.map((row) => row.dataset.tmcActionStatusId),
|
|
["onetalk-history-bootstrap", "onetalk-connection-status"],
|
|
);
|
|
assert.equal(rows[1].textContent, "连接已断开,正在尝试重新连接");
|
|
assert.equal(rows[1].getAttribute("data-tmc-action-status-color"), "warning");
|
|
|
|
pageWindow.document.body.children[0].remove();
|
|
connection.update(true);
|
|
rows = pageWindow.document.body.children[0].children;
|
|
assert.deepEqual(
|
|
rows.map((row) => row.dataset.tmcActionStatusId),
|
|
["onetalk-history-bootstrap", "onetalk-connection-status"],
|
|
);
|
|
|
|
connection.update(false);
|
|
rows = pageWindow.document.body.children[0].children;
|
|
assert.deepEqual(
|
|
rows.map((row) => row.dataset.tmcActionStatusId),
|
|
["onetalk-history-bootstrap"],
|
|
);
|
|
});
|