Archived
app 装配 mail:channel 作首个订阅方、出站经 mail.send、mail.send 工具真发信(dryRun 只校验)、轮询工作者;上传件存取抽出共用
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TM4kUBvekALu9qqmp7D3wr
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
/** 轮询工作者:每 tick 调 pollDue;上一 tick 没跑完就跳过这一拍;出错的账号写 stderr;stop 后不再跑 */
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import type { MailPollOutcome } from '@contracts';
|
||||
import { pollMailOnce, startMailPoller } from '../workers/mail-poller.ts';
|
||||
|
||||
function fakeMail(outcomes: MailPollOutcome[], holdMs = 0) {
|
||||
const calls: Date[] = [];
|
||||
return {
|
||||
calls,
|
||||
mail: {
|
||||
pollDue: async (now: Date) => {
|
||||
calls.push(now);
|
||||
if (holdMs > 0) await new Promise((r) => setTimeout(r, holdMs));
|
||||
return outcomes;
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
describe('pollMailOnce', () => {
|
||||
it('回用例的结果;出错的账号写一行 stderr', async () => {
|
||||
const write = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
|
||||
const { mail } = fakeMail([{ accountId: 'a', pulled: 1, stored: 1, dispatched: 1, more: false }, { accountId: 'b', pulled: 0, stored: 0, dispatched: 0, more: false, error: '连不上' }]);
|
||||
const out = await pollMailOnce({ container: { mail: mail as never } });
|
||||
expect(out).toHaveLength(2);
|
||||
expect(write).toHaveBeenCalledWith(expect.stringContaining('[mail-poller] b:连不上'));
|
||||
write.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
describe('startMailPoller', () => {
|
||||
beforeEach(() => vi.useFakeTimers());
|
||||
afterEach(() => vi.useRealTimers());
|
||||
|
||||
it('按 tick 调;在跑时跳过;stop 后停', async () => {
|
||||
const { mail, calls } = fakeMail([], 1000);
|
||||
const poller = startMailPoller({ container: { mail: mail as never } }, 100);
|
||||
await vi.advanceTimersByTimeAsync(350);
|
||||
expect(calls).toHaveLength(1); // 第一拍 1000ms 没跑完,后面两拍跳过
|
||||
await vi.advanceTimersByTimeAsync(1000);
|
||||
expect(calls.length).toBeGreaterThanOrEqual(2);
|
||||
poller.stop();
|
||||
const before = calls.length;
|
||||
await vi.advanceTimersByTimeAsync(2000);
|
||||
expect(calls).toHaveLength(before);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user