92 lines
3.9 KiB
JavaScript
92 lines
3.9 KiB
JavaScript
'use strict';
|
|
|
|
const assert = require('assert');
|
|
const { TaskBrowserLifecycle } = require('../src/services/task_browser_lifecycle');
|
|
|
|
function createHarness(initialBrowsers = []) {
|
|
const order = [];
|
|
const notifications = [];
|
|
const rows = new Map();
|
|
let createCount = 0;
|
|
const lifecycle = new TaskBrowserLifecycle({
|
|
getBrowserListSimple: async () => initialBrowsers,
|
|
createBrowserFromAccount: async account => {
|
|
createCount++;
|
|
order.push(`create:${account.email}`);
|
|
return { browserId: `created-${createCount}`, browserSeq: createCount };
|
|
},
|
|
getApi: () => ({
|
|
updateBrowserProxy: async ids => {
|
|
order.push(`proxy:${ids[0]}`);
|
|
return { success: true };
|
|
},
|
|
getAliveBrowserPids: async () => ({ success: true, data: {} }),
|
|
}),
|
|
closeBrowser: async id => { order.push(`close:${id}`); return { success: true }; },
|
|
deleteBrowsersBatch: async (ids, callback) => {
|
|
order.push(`delete:${ids[0]}`);
|
|
callback(ids[0], true, '');
|
|
return { successCount: 1, total: 1 };
|
|
},
|
|
parseAccountProxy: value => (value
|
|
? { proxyMethod: 2, proxyType: 'socks5', host: '127.0.0.1', port: '1080' }
|
|
: { proxyMethod: 2, proxyType: 'noproxy' }),
|
|
dbWrite: async (fn, args) => {
|
|
if (fn === 'updateAccountBrowserId') {
|
|
const previous = rows.get(args[0]) || { email: args[0] };
|
|
rows.set(args[0], { ...previous, browser_id: args[1] || '', browser_seq: args[2] ?? null });
|
|
order.push(`db:${args[0]}:${args[1] || 'clear'}`);
|
|
return true;
|
|
}
|
|
if (fn === 'getAccount') return rows.get(args[0]) || null;
|
|
throw new Error(`unexpected db call: ${fn}`);
|
|
},
|
|
updateMessage: async () => {},
|
|
acquireRequestSlot: async () => { order.push('slot'); },
|
|
notify: message => notifications.push(message),
|
|
});
|
|
return { lifecycle, order, notifications, rows, getCreateCount: () => createCount };
|
|
}
|
|
|
|
(async () => {
|
|
{
|
|
const harness = createHarness([{ id: 'bit-existing', name: 'user@example.com', seq: 7 }]);
|
|
const account = { email: 'user@example.com', browser_id: 'stale-id', proxy_ip: '127.0.0.1:1080' };
|
|
const result = await harness.lifecycle.run(account, async prepared => {
|
|
harness.order.push(`work:${prepared.browser_id}`);
|
|
return { ok: true };
|
|
});
|
|
|
|
assert.deepStrictEqual(result, { ok: true });
|
|
assert.strictEqual(harness.getCreateCount(), 0, '同邮箱比特窗口应复用,旧 ID 不应阻止重绑');
|
|
assert(harness.order.indexOf('proxy:bit-existing') < harness.order.indexOf('work:bit-existing'));
|
|
assert(harness.order.indexOf('work:bit-existing') < harness.order.indexOf('delete:bit-existing'));
|
|
assert.strictEqual(account.browser_id, '', '任务结束后应清空账号浏览器绑定');
|
|
assert.strictEqual(harness.rows.get(account.email).browser_id, '');
|
|
assert.deepStrictEqual(harness.notifications.map(item => item.action), ['prepared', 'released']);
|
|
}
|
|
|
|
{
|
|
const harness = createHarness([]);
|
|
const account = { email: 'new@example.com', proxy_ip: '' };
|
|
const first = await harness.lifecycle.run(account, async prepared => ({
|
|
__defer: true,
|
|
browserId: prepared.browser_id,
|
|
}));
|
|
assert.strictEqual(first.__defer, true);
|
|
assert.strictEqual(account.browser_id, 'created-1', '延迟重试仍属于同一账号任务,不应提前删除窗口');
|
|
assert.strictEqual(harness.order.filter(item => item.startsWith('delete:')).length, 0);
|
|
|
|
const second = await harness.lifecycle.run(account, async prepared => ({ browserId: prepared.browser_id }));
|
|
assert.strictEqual(second.browserId, 'created-1');
|
|
assert.strictEqual(harness.getCreateCount(), 1, '延迟重试应继续复用当前临时窗口');
|
|
assert.strictEqual(account.browser_id, '');
|
|
assert.strictEqual(harness.order.filter(item => item === 'delete:created-1').length, 1);
|
|
}
|
|
|
|
console.log('task_browser_lifecycle.test.js PASS');
|
|
})().catch(error => {
|
|
console.error(error);
|
|
process.exitCode = 1;
|
|
});
|