import { describe, expect, it } from 'vitest'; import { DEFAULT_WEBHOOK_QUEUE_MAX_SIZE, InMemoryEventQueue } from '../src/queue/webhookQueue.js'; describe('InMemoryEventQueue (bounded transient buffer, ARN-003)', () => { it('defaults maxSize to 10000', () => { expect(DEFAULT_WEBHOOK_QUEUE_MAX_SIZE).toBe(10_000); expect(new InMemoryEventQueue().maxSize).toBe(10_000); }); it('rejects a non-positive or non-integer maxSize', () => { expect(() => new InMemoryEventQueue({ maxSize: 0 })).toThrow(/maxSize/); expect(() => new InMemoryEventQueue({ maxSize: -5 })).toThrow(/maxSize/); expect(() => new InMemoryEventQueue({ maxSize: 1.5 })).toThrow(/maxSize/); }); it('accepts up to maxSize events, then answers {accepted:false, reason:"full"} without growing', () => { const queue = new InMemoryEventQueue({ maxSize: 2 }); const first = queue.enqueue({ source: 'webhook', payload: { n: 1 } }); const second = queue.enqueue({ source: 'poll', payload: { n: 2 } }); expect(first.accepted).toBe(true); expect(second.accepted).toBe(true); if (first.accepted) expect(first.event.payload).toEqual({ n: 1 }); expect(queue.isFull).toBe(true); const third = queue.enqueue({ source: 'webhook', payload: { n: 3 } }); expect(third).toEqual({ accepted: false, reason: 'full' }); expect(queue.size).toBe(2); expect(queue.peekAll().map((e) => e.payload)).toEqual([{ n: 1 }, { n: 2 }]); }); it('accepts again once an event has been dequeued (FIFO)', () => { const queue = new InMemoryEventQueue({ maxSize: 1 }); queue.enqueue({ source: 'webhook', payload: 'a' }); expect(queue.enqueue({ source: 'webhook', payload: 'b' }).accepted).toBe(false); expect(queue.dequeue()?.payload).toBe('a'); expect(queue.isFull).toBe(false); expect(queue.enqueue({ source: 'webhook', payload: 'b' }).accepted).toBe(true); expect(queue.dequeue()?.payload).toBe('b'); expect(queue.dequeue()).toBeUndefined(); }); });