import { Either, HealthCheckActivityImpl, HealthCheckOutput, PenguenoError, PenguenoRequest, jsonModel, requireMethod, type BaseRequest, type ServerTrace, } from '../lib/index'; import { CollectingTrace, TestTraceable } from './test_utils'; const makeBaseRequest = (overrides: Partial = {}): BaseRequest => ({ url: 'https://example.com/hello', method: 'GET', header: () => ({}), formData: async () => new FormData(), json: async () => ({}), text: async () => '', param: () => undefined, query: () => ({}), queries: () => ({}), ...overrides, }); describe('server filters + activities', () => { beforeEach(() => { jest.useFakeTimers(); jest.setSystemTime(new Date('2020-01-01T00:00:00.000Z')); jest.spyOn(globalThis.crypto, 'randomUUID').mockReturnValue('00000000-0000-0000-0000-000000000000'); }); afterEach(() => { jest.useRealTimers(); jest.restoreAllMocks(); }); test('requireMethod rejects unallowed methods', () => { const trace = new CollectingTrace(); const req = PenguenoRequest.from(TestTraceable.of(makeBaseRequest({ method: 'GET' }), trace)); const res = requireMethod(['POST'])(req); const err = res.left().get(); expect(err).toBeInstanceOf(PenguenoError); expect(err.status).toBe(405); }); test('jsonModel transforms valid JSON', async () => { const trace = new CollectingTrace(); const req = PenguenoRequest.from( TestTraceable.of( makeBaseRequest({ json: async () => ({ hello: 'world' }), }), trace, ), ); const filter = jsonModel((json) => { const body = json.get() as { hello?: string }; return body.hello === 'world' ? Either.right('ok') : Either.left(new PenguenoError('bad json', 400)); }); const res = await filter(req); expect(res.right().get()).toBe('ok'); }); test('jsonModel returns 400 for invalid JSON', async () => { const trace = new CollectingTrace(); const req = PenguenoRequest.from( TestTraceable.of( makeBaseRequest({ json: async () => Promise.reject(new Error('nope')), }), trace, ), ); const filter = jsonModel((_json) => Either.right('never')); const res = await filter(req); expect(res.left().get().status).toBe(400); }); test('HealthCheckActivityImpl returns 200 on success', async () => { const trace = new CollectingTrace(); const req = PenguenoRequest.from(TestTraceable.of(makeBaseRequest(), trace)); const activity = new HealthCheckActivityImpl(async () => Either.right(HealthCheckOutput.YAASSSLAYQUEEN)); const res = await activity.checkHealth(req); expect(res.status).toBe(200); expect(res.body()).toBe('{"ok":"ok"}'); }); });