Pause suspended Reddit accounts

This commit is contained in:
jjbrunton committed 2026-08-14 16:00:37 +01:00
1 parent 94049ed9c4
commit 7d039265e7
21 files changed
+368 -26

No files matched your search

+43
View File
@@ -103,6 +103,28 @@ describe('RedditAccountRuntimeManager', () => {
expect(manager.list()).toHaveLength(1);
});
it('keeps healthy accounts running when one enabled account cannot start', async () => {
const broken = account('broken');
const healthy = account('healthy');
const store = accountStore([broken, healthy]);
const factory = new RedditAccountRuntimeFactory(async (session) => new RedditAccountRuntime(
session,
{ ...resources },
{
start: () => {
if (session.accountId === broken.accountId) throw new Error('Matrix account suspended');
},
stop: vi.fn(),
},
));
const manager = new RedditAccountRuntimeManager(store.repository, factory);
await manager.startEnabled();
expect(manager.get(broken.accountId)).toBeNull();
expect(manager.get(healthy.accountId)?.snapshot().state).toBe('running');
});
it('replaces only the refreshed account while other accounts keep running', async () => {
const first = account('first');
const second = account('second');
@@ -220,6 +242,27 @@ describe('RedditAccountRuntimeManager', () => {
});
describe('account runtime isolation', () => {
it('pauses an account immediately and refuses new work', async () => {
const stored = account('suspended');
const pause = vi.fn();
const runtime = new RedditAccountRuntime(
{
accountId: stored.accountId, redditUsername: stored.redditUsername,
matrixUserId: stored.matrixUserId!, cookies: [],
matrixCredentials: JSON.parse(stored.matrixCredentialsJson), updatedAt: stored.updatedAt,
},
{ ...resources },
{ start: vi.fn(), stop: vi.fn(), pause },
);
await runtime.start();
runtime.pause('Matrix returned M_FORBIDDEN: account suspended');
expect(runtime.snapshot()).toMatchObject({ state: 'paused', failure: expect.stringContaining('M_FORBIDDEN') });
expect(pause).toHaveBeenCalledOnce();
expect(await runtime.canScan()).toBe(false);
});
it('does not accept new outreach while the account has actionable replies', async () => {
const stored = account('reply_first');
const hasActionableReplies = vi.fn().mockResolvedValue(true);