import test, { beforeEach } from 'node:test'; import assert from 'node:assert/strict'; import request from 'supertest'; import { createApp } from '../src/app.js'; import { __resetIdempotencyStoreForTests } from '../src/services/idempotency-store.js'; process.env.AUTH_BYPASS = 'true'; const tenantId = '11111111-1111-4111-8111-111111111111'; const businessId = '22222222-2222-4222-8222-222222222222'; const shiftId = '33333333-3333-4333-8333-333333333333'; function validOrderCreatePayload() { return { tenantId, businessId, orderNumber: 'ORD-1001', title: 'Cafe Event Staffing', serviceType: 'EVENT', shifts: [ { shiftCode: 'SHIFT-1', title: 'Morning Shift', startsAt: '2026-03-11T08:00:00.000Z', endsAt: '2026-03-11T16:00:00.000Z', requiredWorkers: 2, roles: [ { roleCode: 'BARISTA', roleName: 'Barista', workersNeeded: 2, payRateCents: 2200, billRateCents: 3500, }, ], }, ], }; } beforeEach(() => { process.env.IDEMPOTENCY_STORE = 'memory'; delete process.env.IDEMPOTENCY_DATABASE_URL; delete process.env.DATABASE_URL; __resetIdempotencyStoreForTests(); }); test('GET /healthz returns healthy response', async () => { const app = createApp(); const res = await request(app).get('/healthz'); assert.equal(res.status, 200); assert.equal(res.body.ok, true); assert.equal(typeof res.body.requestId, 'string'); }); test('GET /readyz reports database not configured when no database env is present', async () => { const app = createApp(); const res = await request(app).get('/readyz'); assert.equal(res.status, 503); assert.equal(res.body.ok, false); assert.equal(res.body.status, 'DATABASE_NOT_CONFIGURED'); }); test('createApp fails fast in protected env when auth bypass is enabled', async () => { process.env.APP_ENV = 'staging'; process.env.AUTH_BYPASS = 'true'; assert.throws(() => createApp(), /AUTH_BYPASS must be disabled/); delete process.env.APP_ENV; process.env.AUTH_BYPASS = 'true'; }); test('command route requires idempotency key', async () => { const app = createApp(); const res = await request(app) .post('/commands/orders/create') .set('Authorization', 'Bearer test-token') .send(validOrderCreatePayload()); assert.equal(res.status, 400); assert.equal(res.body.code, 'MISSING_IDEMPOTENCY_KEY'); }); test('command route is idempotent by key and only executes handler once', async () => { let callCount = 0; const app = createApp({ commandHandlers: { createOrder: async () => { callCount += 1; return { orderId: '44444444-4444-4444-8444-444444444444', orderNumber: 'ORD-1001', status: 'OPEN', shiftCount: 1, shiftIds: [shiftId], }; }, acceptShift: async () => assert.fail('acceptShift should not be called'), clockIn: async () => assert.fail('clockIn should not be called'), clockOut: async () => assert.fail('clockOut should not be called'), addFavoriteStaff: async () => assert.fail('addFavoriteStaff should not be called'), removeFavoriteStaff: async () => assert.fail('removeFavoriteStaff should not be called'), createStaffReview: async () => assert.fail('createStaffReview should not be called'), }, }); const first = await request(app) .post('/commands/orders/create') .set('Authorization', 'Bearer test-token') .set('Idempotency-Key', 'abc-123') .send(validOrderCreatePayload()); const second = await request(app) .post('/commands/orders/create') .set('Authorization', 'Bearer test-token') .set('Idempotency-Key', 'abc-123') .send(validOrderCreatePayload()); assert.equal(first.status, 200); assert.equal(second.status, 200); assert.equal(callCount, 1); assert.equal(first.body.orderId, second.body.orderId); assert.equal(first.body.idempotencyKey, 'abc-123'); assert.equal(second.body.idempotencyKey, 'abc-123'); });