This repository has been archived on 2026-09-13. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
BPOS-TMP-REPO/apps/api/src/app/__tests__/mail-poller.test.ts
T

48 lines
1.9 KiB
TypeScript

/** 轮询工作者:每 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);
});
});