import request from 'supertest'; import { buildApp } from '../src/app'; const KEY = 'key-ada'; const ADMIN = { 'x-admin-key': 'admin-dev-key' }; describe('zappier-edge operational wiring', () => { it('GET /health is public', async () => { const { app } = buildApp(); const res = await request(app).get('/health'); expect(res.status).toBe(200); expect(res.body.role).toBe('zappier-edge'); }); it('proxies timestamp to middleware when ZAPPIER_UPSTREAM is set', async () => { process.env.ZAPPIER_UPSTREAM = 'http://upstream.test'; const orig = globalThis.fetch; globalThis.fetch = jest.fn(async (url: string | URL) => { expect(String(url)).toContain('/zapier/v1/timestamp'); return new Response(JSON.stringify({ jobId: 'mw-1', sha256: 'abc' }), { status: 202, headers: { 'content-type': 'application/json' }, }); }) as typeof fetch; try { const { app } = buildApp(); const res = await request(app).post('/v1/timestamp').set('x-api-key', KEY).send({ data: 'hello' }); expect(res.status).toBe(202); expect(res.body.jobId).toBe('mw-1'); expect(res.body.quote.totalCents).toBeGreaterThanOrEqual(0); } finally { globalThis.fetch = orig; delete process.env.ZAPPIER_UPSTREAM; } }); it('customers CS and sales can review a statement', async () => { const { app } = buildApp(); await request(app) .post('/admin/api/credits') .set(ADMIN) .send({ customerId: 'cust_1', cents: 250, reason: 'goodwill', agent: 'cs' }); const st = await request(app).get('/admin/api/statement/cust_1').set(ADMIN); expect(st.status).toBe(200); expect(st.body.prepaidCents).toBeGreaterThanOrEqual(250); expect(st.body.credits.length).toBeGreaterThan(0); }); it('customer service can add prepaid credits', async () => { const { app } = buildApp(); const add = await request(app) .post('/admin/api/credits') .set(ADMIN) .send({ customerId: 'cust_1', cents: 500, reason: 'goodwill', agent: 'cs-anna' }); expect(add.status).toBe(201); expect(add.body.cents).toBe(500); const list = await request(app).get('/admin/api/credits?customerId=cust_1').set(ADMIN); expect(list.body.credits[0].reason).toBe('goodwill'); }); it('sales quote returns per-customer multiplier', async () => { const { app } = buildApp(); const res = await request(app).get('/admin/api/sales/quote/cust_2').set(ADMIN); expect(res.status).toBe(200); expect(res.body.tierId).toBe('pro'); }); it('exports issued invoices as QuickBooks IIF', async () => { const { app, usage } = buildApp(); usage.record({ customerId: 'cust_2', endpointId: 'transform', cents: 400, metadataBytes: 0, attachmentBytes: 0, timestamp: new Date('2026-07-05T10:00:00Z'), }); await request(app).post('/admin/api/invoices/generate').set(ADMIN).send({ period: '2026-07' }); await request(app).post('/admin/api/invoices/INV-2026-07-0001/issue').set(ADMIN); const iif = await request(app).get('/admin/api/exports/quickbooks.iif?period=2026-07').set(ADMIN); expect(iif.status).toBe(200); expect(iif.text).toContain('TRNS'); expect(iif.text).toContain('INV-2026-07-0001'); const csv = await request(app).get('/admin/api/exports/accounting.csv?period=2026-07').set(ADMIN); expect(csv.text).toContain('invoice_id'); }); });