import { describe, it, expect } from 'vitest'; import { WebhookAdapter, hmacSign, hmacVerify, signedFixture, emailFixture } from './index'; describe('iios-adapter-sdk', () => { const secret = 'shh'; const adapter = new WebhookAdapter('WEBHOOK'); it('hmac verify: accepts a good sig, rejects tampered/absent', () => { const body = JSON.stringify({ a: 1 }); const sig = hmacSign(body, secret); expect(hmacVerify(body, secret, sig)).toBe(true); expect(hmacVerify(body + 'x', secret, sig)).toBe(false); expect(hmacVerify(body, secret, undefined)).toBe(false); }); it('verifySignature reads x-iios-signature', () => { const { body, headers } = signedFixture(emailFixture, secret); expect(adapter.verifySignature(body, headers, secret)).toBe(true); expect(adapter.verifySignature(body, { 'x-iios-signature': 'sha256=bad' }, secret)).toBe(false); }); it('normalize maps a provider payload into a valid ingest request', () => { const req = adapter.normalize(emailFixture, { scope: { orgId: 'o', appId: 'a' } }); expect(req.source.handleKind).toBe('EXTERNAL_VISITOR'); expect(req.source.externalId).toBe(emailFixture.from); expect(req.parts[0]?.bodyText).toBe(emailFixture.text); expect(req.providerEventId).toBe(emailFixture.eventId); expect(req.thread?.externalThreadId).toBe(emailFixture.threadRef); }); it('send goes to the sandbox (no network)', async () => { const r = await adapter.send({ channelType: 'WEBHOOK', target: 'x', payload: { text: 'hi' } }); expect(r.outcome).toBe('SENT'); expect(r.providerRef).toContain('sim-'); }); });