import assert from 'node:assert/strict'; import { readFile } from 'node:fs/promises'; import test from 'node:test'; import React from 'react'; import { renderToStaticMarkup } from 'react-dom/server'; import TestRenderer from 'react-test-renderer'; import { AccountCard, WecomSettingsTab, } from '../../../plugin-src/client/channels/wecom/index.js'; const { act, create } = TestRenderer; const CLIENT_URL = new URL('../../../plugin-src/client/channels/wecom/index.js', import.meta.url); async function flushMicrotasks() { for (let index = 0; index < 6; index += 1) await Promise.resolve(); } function textOf(node) { if (typeof node === 'string' || typeof node === 'number') return String(node); return node?.children?.map(textOf).join('') ?? ''; } function buttonNamed(root, name) { return root.findAllByType('button').find((button) => textOf(button) === name); } function account(botId, name) { return { botId, connected: true, state: 'connected', workspace: '/workspace/current', bot: { name, appIdMasked: `${botId}•••` }, health: { summary: '企业微信 WebSocket 长连接运行正常', lastCheckedAt: Date.now() }, error: null, }; } test('Enterprise WeChat settings uses the shared compact channel toolbar', () => { const markup = renderToStaticMarkup(React.createElement(WecomSettingsTab, { rpcCall: async () => ({ ok: true, value: {} }), })); assert.match(markup, /class="ddt-page dwecom-page dim-channelPage"/); assert.match(markup, /class="ddt-button dim-scanButton"/); assert.match(markup, /aria-label="扫码接入企业微信机器人"/); assert.match(markup, /class="dim-actionIcon"[^]*扫码接入机器人/); assert.doesNotMatch(markup, /凭据仅保存在本机|role="switch"|type="checkbox"/); }); test('Enterprise WeChat bot cards match the shared two-metric card treatment', () => { const markup = renderToStaticMarkup(React.createElement(AccountCard, { account: { botId: 'wecom_bot', connected: true, state: 'connected', bot: { name: '企业微信机器人', appIdMasked: 'bot••••001' }, health: { summary: '企业微信 WebSocket 长连接运行正常', lastCheckedAt: Date.now() }, error: null, }, onReconnect() {}, onRequestRemove() {}, onConfirmRemove() {}, onCancelRemove() {}, })); assert.match(markup, /class="ddt-card dim-botCard"/); assert.match(markup, /data-im-channel-logo="wecom"/); assert.equal((markup.match(/class="ddt-metric dim-botMetric"/g) ?? []).length, 2); assert.match(markup, />消息通道<[^]*>最近检查检查连接<[^]*>移除接入 { const markup = renderToStaticMarkup(React.createElement(AccountCard, { account: { ...account('wecom_bot', '企业微信机器人'), connected: false, state: 'error', error: { code: 'offline', message: '连接凭据已失效' }, }, feedback: '企业微信连接检查完成,测试消息已发送。', onReconnect() {}, onRequestRemove() {}, onConfirmRemove() {}, onCancelRemove() {}, })); assert.match(markup, />连接凭据已失效]*>企业微信连接检查完成,测试消息已发送。 { const previousWindow = globalThis.window; globalThis.window = { setInterval() { return 1; }, clearInterval() {}, setTimeout() { return 1; }, clearTimeout() {}, requestAnimationFrame(callback) { callback(); return 1; }, cancelAnimationFrame() {}, }; t.after(() => { if (previousWindow === undefined) delete globalThis.window; else globalThis.window = previousWindow; }); const bots = [account('wecom_first', 'First Bot'), account('wecom_second', 'Second Bot')]; const calls = []; const rpcCall = async (endpoint, payload) => { if (endpoint === 'connection.status') return { ok: true, value: { bots } }; if (endpoint === 'bot.reconnect') { calls.push(payload); return { ok: true, value: { bots, testMessage: { sent: true } } }; } throw new Error(`Unexpected endpoint: ${endpoint}`); }; let renderer; await act(async () => { renderer = create(React.createElement(WecomSettingsTab, { rpcCall })); await flushMicrotasks(); }); const first = renderer.root.findByProps({ 'data-bot-id': 'wecom_first' }); await act(async () => { buttonNamed(first, '检查连接').props.onClick(); await flushMicrotasks(); }); const firstAfter = renderer.root.findByProps({ 'data-bot-id': 'wecom_first' }); const secondAfter = renderer.root.findByProps({ 'data-bot-id': 'wecom_second' }); assert.match(textOf(firstAfter), /测试消息已发送/); assert.doesNotMatch(textOf(secondAfter), /测试消息已发送/); assert.deepEqual(calls, [{ botId: 'wecom_first', sendTest: true }]); await act(async () => { renderer.unmount(); }); }); test('Enterprise WeChat reconnect failure uses fixed translatable copy', async () => { const source = await readFile(CLIENT_URL, 'utf8'); assert.match(source, /'连接检查失败,请稍后重试。'/); assert.match(source, /'连接检查完成。机器人尚未收到可用于测试的私聊消息。'/); assert.doesNotMatch(source, /请先私聊机器人发送 \/status/); assert.doesNotMatch(source, /连接检查失败:\$\{presentError\(error\)\.message\}/); });