import { describe, it, expect } from 'vitest';
import { EventEmitter } from 'events';
import type { IncomingMessage } from 'http';
import { readRequestBody, RequestBodyTooLargeError } from './httpBody.js';

class MockRequest extends EventEmitter {
  destroyed = false;

  destroy(): this {
    this.destroyed = true;
    return this;
  }
}

function asIncoming(req: MockRequest): IncomingMessage {
  return req as unknown as IncomingMessage;
}

describe('readRequestBody', () => {
  it('reads body under size limit', async () => {
    const req = new MockRequest();
    const bodyPromise = readRequestBody(asIncoming(req), { maxBytes: 1024 });

    req.emit('data', Buffer.from('hello'));
    req.emit('data', Buffer.from(' world'));
    req.emit('end');

    await expect(bodyPromise).resolves.toBe('hello world');
    expect(req.destroyed).toBe(false);
  });

  it('rejects oversized body and destroys request', async () => {
    const req = new MockRequest();
    const bodyPromise = readRequestBody(asIncoming(req), { maxBytes: 5 });

    req.emit('data', Buffer.from('12345'));
    req.emit('data', Buffer.from('6'));

    await expect(bodyPromise).rejects.toBeInstanceOf(RequestBodyTooLargeError);
    expect(req.destroyed).toBe(true);
  });
});
