/** * GATE 5 — Auth + entitlement HTTP tests */ import { describe, it, before, after, beforeEach, afterEach } from 'node:test'; import assert from 'node:assert/strict'; import { createApp } from '../../src/app.js'; import { useTempStore, seedFreeTenant } from '../helpers.js'; import { incrementUsage } from '../../src/store/usage.js'; import { PLAN_LIMITS } from '../../src/config.js'; import { checkEntitlement } from '../../src/services/entitlementService.js'; import { AppError } from '../../src/errors.js'; describe('auth + entitlements HTTP', () => { /** @type {ReturnType} */ let ctx; /** @type {import('http').Server} */ let server; /** @type {number} */ let port; /** @type {string} */ let apiKey; before(() => { ctx = useTempStore(); const seeded = seedFreeTenant(); apiKey = seeded.apiKey; const app = createApp({ load: false }); return new Promise((resolve) => { server = app.listen(0, '127.0.0.1', () => { port = server.address().port; resolve(); }); }); }); after(async () => { await new Promise((resolve) => server.close(resolve)); ctx.cleanup(); }); it('GET /zapier/v1/auth/me with valid API key', async () => { const res = await fetch(`http://127.0.0.1:${port}/zapier/v1/auth/me`, { headers: { Authorization: `Bearer ${apiKey}` }, }); assert.equal(res.status, 200); const body = await res.json(); assert.equal(body.valid, true); assert.equal(body.plan, 'free'); assert.ok(body.tenantId); assert.ok(body.usage); }); it('invalid key returns 401', async () => { const res = await fetch(`http://127.0.0.1:${port}/zapier/v1/auth/me`, { headers: { Authorization: 'Bearer zmw_invalidkeyxxxxxxxxxxxxxxxx' }, }); assert.equal(res.status, 401); const body = await res.json(); assert.equal(body.code, 'UNAUTHORIZED'); }); it('exceeding free timestamp quota throws 402 QUOTA_EXCEEDED', () => { const tenantId = 'tenant-test-free'; const limit = PLAN_LIMITS.free.timestamps; // force usage to limit for (let i = 0; i < limit; i += 1) { incrementUsage(tenantId, 'timestamps', 1); } assert.throws( () => checkEntitlement(tenantId, 'timestamp'), (err) => err instanceof AppError && err.status === 402 && err.code === 'QUOTA_EXCEEDED', ); }); });