douyin-release-gate / verify (push) Failing after 18m54s
Add Douyin notification polling, event details, and manual multi-account private messaging. Refine environment memory settings, account operations, login collection recovery, and message UI; update tests and documentation.
134 lines
6.4 KiB
JavaScript
134 lines
6.4 KiB
JavaScript
const assert = require('node:assert/strict');
|
|
const { readFileSync } = require('node:fs');
|
|
const { createRequire, Module } = require('node:module');
|
|
const { resolve } = require('node:path');
|
|
const test = require('node:test');
|
|
const vm = require('node:vm');
|
|
const ts = require('typescript');
|
|
|
|
const requireWeb = createRequire(resolve(__dirname, '../package.json'));
|
|
function compile(relativePath, imports = {}) {
|
|
const path = resolve(__dirname, relativePath);
|
|
const loaded = new Module(path, module);
|
|
loaded.require = id => imports[id] || requireWeb(id);
|
|
loaded._compile(ts.transpileModule(readFileSync(path, 'utf8'), {
|
|
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 },
|
|
}).outputText, path);
|
|
return loaded.exports;
|
|
}
|
|
const helpers = compile('../src/utils/helpers.ts');
|
|
const actions = compile('../src/components/accounts/account-actions.ts', {
|
|
'@/services/api': {},
|
|
'@/utils/account-collection-status': compile('../src/utils/account-collection-status.ts'),
|
|
});
|
|
const account = {
|
|
id: '1004291301', runtime_status: 'active', login_status: 'logged_in',
|
|
environment: { alias: 'environment', schedule_block_reason: 'runtime_missing' },
|
|
};
|
|
const stopped = { alias: 'environment', state: 'missing', status: '未记录运行实例', gateway_reachable: true };
|
|
|
|
const source = ts.createSourceFile('AccountManagementList.tsx',
|
|
readFileSync(resolve(__dirname, '../src/components/accounts/AccountManagementList.tsx'), 'utf8'),
|
|
ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
|
|
let renderer;
|
|
function visit(node) {
|
|
if (ts.isObjectLiteralExpression(node) && node.properties.some(property =>
|
|
ts.isPropertyAssignment(property) && property.name.getText(source) === 'title' && property.initializer.text === '操作')) {
|
|
renderer = node.properties.find(property => ts.isPropertyAssignment(property) && property.name.getText(source) === 'render').initializer.getText(source);
|
|
}
|
|
ts.forEachChild(node, visit);
|
|
}
|
|
visit(source);
|
|
assert.ok(renderer, '必须存在账号操作列');
|
|
|
|
function renderActions(row = account, browser = stopped, actionBusy = '') {
|
|
const calls = [];
|
|
const code = ts.transpileModule(`exports.render = ${renderer};`, {
|
|
compilerOptions: { jsx: ts.JsxEmit.ReactJSX, module: ts.ModuleKind.CommonJS },
|
|
}).outputText;
|
|
const context = {
|
|
exports: {}, require: requireWeb, ...requireWeb('antd'),
|
|
DownOutlined: requireWeb('@ant-design/icons').DownOutlined,
|
|
...helpers, ...actions, browsers: browser ? [browser] : [], verifiedLogin: {}, actionBusy,
|
|
performPrimary: (row, intent) => calls.push([row.id, intent]), moreAction() {}, setEnvironmentTarget() {},
|
|
};
|
|
vm.runInNewContext(code, context);
|
|
const cell = context.exports.render(undefined, row);
|
|
const [tooltip, dropdown] = cell.props.children;
|
|
return { button: tooltip.props.children, tooltip, menu: dropdown.props.menu, calls };
|
|
}
|
|
|
|
test('未启动只阻止采集调度,不阻止启动环境', () => {
|
|
const readiness = helpers.accountReadiness(account, account.environment);
|
|
assert.equal(readiness.ready, false);
|
|
assert.equal(readiness.reason, 'runtime_missing');
|
|
assert.equal(readiness.label, '运行环境未启动');
|
|
assert.equal(readiness.canStart, true);
|
|
});
|
|
|
|
test('可调度账号仍可启动,未知阻塞原因不能绕过', () => {
|
|
assert.equal(helpers.accountReadiness(account, {}).canStart, true);
|
|
assert.equal(helpers.accountReadiness(account, { schedule_block_reason: 'unknown_block' }).canStart, false);
|
|
});
|
|
|
|
for (const [name, row, binding, error] of [
|
|
['未绑定', account, null],
|
|
['状态读取失败', account, account.environment, new Error('unavailable')],
|
|
['停止待确认', account, { ...account.environment, runtime_cleanup_pending: true }],
|
|
['固定出口异常', account, { ...account.environment, network_exit_id: 'proxy', network_exit_health: 'unhealthy' }],
|
|
['账号暂停', { ...account, runtime_status: 'paused' }, account.environment],
|
|
['暂停账号仍在停止', { ...account, runtime_status: 'paused' }, { ...account.environment, runtime_id: 'runtime' }],
|
|
]) {
|
|
test(`${name}不能通过启动环境绕过限制`, () => {
|
|
assert.equal(helpers.accountReadiness(row, binding, error).canStart, false);
|
|
});
|
|
}
|
|
|
|
test('1004291301 未启动时主按钮和更多菜单均允许启动', () => {
|
|
const { button, tooltip, menu, calls } = renderActions();
|
|
assert.equal(button.props.children, '启动环境');
|
|
assert.equal(button.props.disabled, false);
|
|
assert.equal(tooltip.props.title, undefined);
|
|
assert.equal(menu.items.find(item => item.key === 'start').disabled, false);
|
|
button.props.onClick();
|
|
assert.deepEqual(calls, [['1004291301', 'start']]);
|
|
});
|
|
|
|
test('需要重新登录的未启动账号可点击重新登录', () => {
|
|
const { button, calls } = renderActions({ ...account, login_status: 'manual_login' });
|
|
assert.equal(button.props.children, '重新登录');
|
|
assert.equal(button.props.disabled, false);
|
|
button.props.onClick();
|
|
assert.deepEqual(calls, [['1004291301', 'login']]);
|
|
});
|
|
|
|
for (const environment of [
|
|
{ ...account.environment, runtime_cleanup_pending: true },
|
|
{ ...account.environment, network_exit_id: 'proxy', network_exit_health: 'unhealthy' },
|
|
{ ...account.environment, schedule_block_reason: 'unknown_block' },
|
|
]) {
|
|
test(`列表启动入口仍遵守限制 ${JSON.stringify(environment)}`, () => {
|
|
const { button, tooltip, menu } = renderActions({ ...account, environment });
|
|
assert.equal(button.props.disabled, true);
|
|
assert.ok(tooltip.props.title);
|
|
assert.equal(menu.items.find(item => item.key === 'start').disabled, true);
|
|
});
|
|
}
|
|
|
|
test('暂停账号保留恢复运行入口,不能从更多菜单直接启动', () => {
|
|
const paused = { ...account, runtime_status: 'paused' };
|
|
const { button, menu } = renderActions(paused);
|
|
assert.equal(button.props.children, '恢复运行');
|
|
assert.equal(button.props.disabled, false);
|
|
assert.equal(menu.items.find(item => item.key === 'start').disabled, true);
|
|
});
|
|
|
|
test('操作执行中仍禁用主按钮,运行中不重复启动', () => {
|
|
assert.equal(renderActions(account, stopped, account.id).button.props.disabled, true);
|
|
const running = { ...stopped, state: 'running', status: 'ready' };
|
|
const { button, menu } = renderActions({ ...account, environment: { alias: 'environment' } }, running);
|
|
assert.equal(button.props.children, '同步资料');
|
|
assert.equal(button.props.disabled, false);
|
|
assert.equal(menu.items.find(item => item.key === 'start').disabled, true);
|
|
});
|