import request from 'supertest'; import { buildApp } from '../src/app'; const ADMIN = { 'x-admin-key': 'admin-dev-key' }; const KEY = 'key-ada'; describe('admin API', () => { it('rejects calls without an admin key', async () => { const { app } = buildApp(); const res = await request(app).get('/admin/api/pricing'); expect(res.status).toBe(403); }); it('returns the current pricing', async () => { const { app } = buildApp(); const res = await request(app).get('/admin/api/pricing').set(ADMIN); expect(res.status).toBe(200); expect(res.body.rateCard.endpoints.status).toEqual({ kind: 'free' }); expect(res.body.tiers.map((t: { id: string }) => t.id)).toEqual(['free', 'pro', 'business']); }); it('rejects an invalid price rule with 400', async () => { const { app } = buildApp(); const res = await request(app) .put('/admin/api/endpoints/transform') .set(ADMIN) .send({ kind: 'sometimes' }); expect(res.status).toBe(400); }); it('reprices an endpoint live, without restart', async () => { const { app } = buildApp(); await request(app) .put('/admin/api/endpoints/transform') .set(ADMIN) .send({ kind: 'fixed', fixedCents: 10 }); const res = await request(app) .post('/v1/transform') .set('x-api-key', KEY) .send({ text: 'hi' }); expect(res.body.quote.totalCents).toBe(10); // was 4 }); it('creates a customer type live and prices calls for it', async () => { const { app } = buildApp(); await request(app) .put('/admin/api/tiers/edu') .set(ADMIN) .send({ id: 'edu', name: 'Education', multiplier: 0.5, monthlyCreditCents: 500 }); const created = await request(app) .post('/admin/api/customers') .set(ADMIN) .send({ name: 'School', tierId: 'edu' }); expect(created.status).toBe(201); expect(created.body.apiKey).toMatch(/^key-/); const res = await request(app) .post('/v1/transform') .set('x-api-key', created.body.apiKey) .send({ text: 'hi' }); expect(res.body.quote.totalCents).toBe(2); // list 4 x 0.5 }); it('sets a per-customer multiplier override live', async () => { const { app } = buildApp(); const res = await request(app) .put('/admin/api/customers/cust_1') .set(ADMIN) .send({ multiplierOverride: 0.5 }); expect(res.status).toBe(200); const call = await request(app) .post('/v1/transform') .set('x-api-key', KEY) .send({ text: 'hi' }); expect(call.body.quote.totalCents).toBe(2); // was 4 }); it('masks API keys in the customer list and 404s unknown customers', async () => { const { app } = buildApp(); const list = await request(app).get('/admin/api/customers').set(ADMIN); expect(list.status).toBe(200); expect(JSON.stringify(list.body)).not.toContain('key-ada'); const missing = await request(app) .put('/admin/api/customers/cust_nope') .set(ADMIN) .send({ tierId: 'pro' }); expect(missing.status).toBe(404); }); }); describe('admin login', () => { it('logs in the demo account and accepts the issued token', async () => { const { app } = buildApp(); const login = await request(app) .post('/admin/api/login') .send({ username: 'demo', password: '$$$Adm1n###' }); expect(login.status).toBe(200); expect(login.body.token).toMatch(/^[a-f0-9]{48}$/); const res = await request(app) .get('/admin/api/pricing') .set('authorization', `Bearer ${login.body.token}`); expect(res.status).toBe(200); }); it('logs in the primary admin account with the admin key as password', async () => { const { app } = buildApp(); const login = await request(app) .post('/admin/api/login') .send({ username: 'admin', password: 'admin-dev-key' }); expect(login.status).toBe(200); }); it('rejects bad credentials with 401 and issues no token', async () => { const { app } = buildApp(); const login = await request(app) .post('/admin/api/login') .send({ username: 'demo', password: 'wrong' }); expect(login.status).toBe(401); expect(login.body.token).toBeUndefined(); }); it('still accepts the legacy x-admin-key header', async () => { const { app } = buildApp(); const res = await request(app).get('/admin/api/pricing').set(ADMIN); expect(res.status).toBe(200); }); it('rejects unknown bearer tokens', async () => { const { app } = buildApp(); const res = await request(app) .get('/admin/api/pricing') .set('authorization', 'Bearer deadbeef'); expect(res.status).toBe(403); }); it('sets billingType and email on a customer', async () => { const { app } = buildApp(); const res = await request(app) .put('/admin/api/customers/cust_1') .set(ADMIN) .send({ billingType: 'purchase_order', email: 'ada@example.com' }); expect(res.status).toBe(200); const list = await request(app).get('/admin/api/customers').set(ADMIN); const ada = list.body.customers.find((c: { id: string }) => c.id === 'cust_1'); expect(ada.billingType).toBe('purchase_order'); expect(ada.email).toBe('ada@example.com'); }); it('rejects an invalid billingType with 400', async () => { const { app } = buildApp(); const res = await request(app) .put('/admin/api/customers/cust_1') .set(ADMIN) .send({ billingType: 'carrier-pigeon' }); expect(res.status).toBe(400); }); });