Files
creator-hub/web/tests/account-management-list.test.cjs
T

119 lines
6.2 KiB
JavaScript

const assert = require('node:assert/strict');
const { readFileSync } = require('node:fs');
const { test } = require('node:test');
const ts = require('typescript');
const source = ts.createSourceFile(
'AccountManagementList.tsx',
readFileSync(`${__dirname}/../src/components/accounts/AccountManagementList.tsx`, 'utf8'),
ts.ScriptTarget.Latest,
true,
ts.ScriptKind.TSX,
);
const code = source.getFullText();
function accountRenderer(file, title = '账号') {
const ast = ts.createSourceFile(file, readFileSync(`${__dirname}/../src/components/accounts/${file}`, 'utf8'), ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
let renderer;
function visit(node) {
if (!renderer && ts.isObjectLiteralExpression(node) && node.properties.some(p => ts.isPropertyAssignment(p) && p.name.getText(ast) === 'title' && p.initializer.getText(ast) === `'${title}'`)) {
renderer = node.properties.find(p => ts.isPropertyAssignment(p) && p.name.getText(ast) === 'render').initializer.getText(ast);
}
ts.forEachChild(node, visit);
}
visit(ast);
assert.ok(renderer, `${file} 缺少账号列`);
const { createRequire } = require('node:module');
const requireWeb = createRequire(`${__dirname}/../package.json`);
const imports = { ...requireWeb('antd'), history: { push() {} }, formatCount: (value) => value == null ? '—' : String(value), dateTime: (value) => value };
const js = ts.transpileModule(`const render = ${renderer};`, { compilerOptions: { jsx: ts.JsxEmit.ReactJSX, module: ts.ModuleKind.CommonJS } }).outputText;
return require('node:vm').runInNewContext(`${js}\nrender`, { ...imports, exports: {}, require: requireWeb });
}
test('我的账号列不显示 UID,头像与监控账号一致且详情入口不变', () => {
const renderOwned = accountRenderer('AccountManagementList.tsx');
const renderMonitoring = accountRenderer('MonitoringAccountList.tsx');
for (const [name, avatar] of [['豪的抖音', 'https://example.com/avatar.jpg'], ['a', ''], ['', undefined]]) {
const data = { id: 'account-1', name, nickname: name, avatar_url: avatar, platform_account_key: '99491952055' };
const owned = renderOwned(undefined, data);
const monitored = renderMonitoring(undefined, data);
assert.equal(owned.type, monitored.type);
assert.equal(owned.props.align, 'center');
assert.equal(owned.props.gap, monitored.props.gap);
const [ownedAvatar, ownedName] = owned.props.children;
const [monitoredAvatar, monitoredName] = monitored.props.children;
assert.deepEqual(Object.keys(ownedAvatar.props), Object.keys(monitoredAvatar.props));
for (const key of Object.keys(monitoredAvatar.props)) assert.equal(ownedAvatar.props[key], monitoredAvatar.props[key]);
assert.equal(ownedName.props.children, name || '待登录');
if (name) assert.equal(ownedName.props.children, monitoredName.props.children);
assert.equal(data.name, name, '显示占位文案不修改原始昵称');
const requireWeb = require('node:module').createRequire(`${__dirname}/../package.json`);
const html = requireWeb('react-dom/server').renderToStaticMarkup(owned);
assert.ok(!html.includes(data.platform_account_key), '账号列不应显示 UID');
}
assert.match(code, /history\.push\(`\/accounts\/\$\{account\.id\}`\)/);
});
test('作品总数来自抖音,已采集数量只表示进度', () => {
const render = accountRenderer('AccountManagementList.tsx', '作品数据');
const requireWeb = require('node:module').createRequire(`${__dirname}/../package.json`);
const html = requireWeb('react-dom/server').renderToStaticMarkup(render(undefined, { aweme_count: 100, work_count: 7 }));
assert.match(html, /100 个作品/);
assert.match(html, /已采集 7 \/ 总计 100/);
assert.doesNotMatch(html, />7 个作品/);
const unknown = requireWeb('react-dom/server').renderToStaticMarkup(render(undefined, { work_count: 7 }));
assert.match(unknown, /作品总数未知/);
assert.match(unknown, /已采集 7 \/ 总计 未知/);
const zero = requireWeb('react-dom/server').renderToStaticMarkup(render(undefined, { aweme_count: 0, work_count: 0 }));
assert.match(zero, /0 个作品/);
assert.match(zero, /已采集 0 \/ 总计 0/);
});
test('未登录环境没有真实作品总数,不把占位零当作抖音数据', () => {
const render = accountRenderer('AccountManagementList.tsx', '作品数据');
const requireWeb = require('node:module').createRequire(`${__dirname}/../package.json`);
const html = requireWeb('react-dom/server').renderToStaticMarkup(render(undefined, {
pending_environment: true, aweme_count: 0, work_count: 0,
}));
assert.match(html, /登录后显示作品数据/);
assert.doesNotMatch(html, /0 个作品|总计 0/);
});
test('列表展示粉丝、关注、获赞、互关、评论独立数值列', () => {
for (const [title, value] of [
['粉丝', 'account.follower_count'],
['关注', 'account.following_count'],
['获赞', 'account.total_favorited'],
['互关', 'account.friend_count'],
['评论', 'account.comment_total'],
]) {
assert.ok(
code.includes(`title: '${title}',\n render: (_, account) => formatCount(${value}),`),
`${title} 应为独立数值列`,
);
}
});
test('操作列包含「启动」:先启动环境再弹出登录画面', () => {
assert.match(code, /onClick=\{\(\) => startAccount\(account\)\}/);
assert.match(code, /\/phase-a\/accounts\/\$\{encodeURIComponent\(row\.id\)\}\/start/);
assert.match(code, /setLoginTarget\(row\)/);
assert.match(code, /<AccountLoginModal accountID=\{loginTarget\.id\}/);
assert.ok(code.indexOf('await creatorAction(`/phase-a/accounts/') < code.indexOf('setLoginTarget(row)'));
});
test('登录弹窗共享自动流程,成功刷新列表,关闭后卸载弹窗', () => {
assert.match(code, /loginTarget \? \(/);
assert.match(code, /onClose=\{\(\) => setLoginTarget\(null\)\}/);
assert.match(code, /onSuccess=\{\(\) => \{ void load\(\); \}\}/);
assert.doesNotMatch(code, /刷新登录画面|核验浏览器身份|requestLoginQR|verifyLogin/);
});
test('启动失败走 conflictMessage 透传 409 就绪原因', () => {
assert.ok(
code.includes(
"messageApi.error(conflictMessage(startError, '启动未完成:账号或环境不满足就绪条件,请按不可运行原因处理后重试。'));",
),
);
});