feat: replace browser login with imported Reddit sessions

This commit is contained in:
jjbrunton committed 2026-08-08 16:48:59 +01:00
1 parent 2b0545afcf
commit c483c7b8be
76 files changed
+2048 -2828

No files matched your search

+50 -2
View File
@@ -1,5 +1,5 @@
import { describe, it, expect, beforeEach } from 'vitest';
import { RateLimiter } from '../src/utils/rate-limiter.js';
import { describe, it, expect, beforeEach, vi } from 'vitest';
import { RateLimiter, type SentMessageHistoryProvider } from '../src/utils/rate-limiter.js';
import { createMockLogger } from '../tests/mockLogger.js';
import { getTestConfig } from '../tests/testUtils.js';
@@ -121,6 +121,54 @@ describe('RateLimiter', () => {
});
});
describe('persisted send history', () => {
it('seeds the rolling hourly count from successful sends persisted before restart', async () => {
const now = Date.now();
const history: SentMessageHistoryProvider = vi.fn().mockResolvedValue([
now - 5_000,
now - 10_000,
now - 3_700_000,
]);
const config = getTestConfig({
rateLimit: { minDelayBetweenMessagesMs: 0, maxMessagesPerHour: 3, jitterMs: 0 },
});
limiter = new RateLimiter(config, logger, 3_600_000, { sentMessageHistory: history });
await limiter.initialize();
expect(history).toHaveBeenCalledWith(expect.any(Number));
expect(limiter.getStats().messagesThisHour).toBe(2);
expect(limiter.getTimers().messagesRemaining).toBe(1);
});
it('initializes persisted history only once when concurrent sends arrive', async () => {
const history: SentMessageHistoryProvider = vi.fn().mockResolvedValue([]);
limiter = new RateLimiter(getTestConfig(), logger, 3_600_000, { sentMessageHistory: history });
await Promise.all([
limiter.throttle(() => Promise.resolve('one')),
limiter.throttle(() => Promise.resolve('two')),
]);
expect(history).toHaveBeenCalledTimes(1);
});
it('cancels an hourly-limit wait when shutdown aborts it', async () => {
const controller = new AbortController();
const limiterWithHistory = new RateLimiter(
getTestConfig({ rateLimit: { minDelayBetweenMessagesMs: 0, maxMessagesPerHour: 1, jitterMs: 0 } }),
logger,
60_000,
{ sentMessageHistory: async () => [Date.now()] },
);
await limiterWithHistory.initialize();
const pending = limiterWithHistory.throttle(() => Promise.resolve('should not run'), () => true, controller.signal);
controller.abort();
await expect(pending).rejects.toMatchObject({ name: 'AbortError' });
});
});
describe('getTimers', () => {
it('returns null nextMessageAvailableAt initially', () => {
const timers = limiter.getTimers();