import test from 'node:test'; import assert from 'node:assert/strict'; import request from 'supertest'; import { createApp } from '../src/app.js'; process.env.AUTH_BYPASS = 'true'; function createMobileQueryService() { return { getClientDashboard: async () => ({ businessName: 'Google Cafes' }), getClientSession: async () => ({ business: { businessId: 'b1' } }), getCoverageStats: async () => ({ totalCoveragePercentage: 100 }), getCoverageReport: async () => ({ items: [{ shiftId: 'coverage-1' }] }), getCurrentAttendanceStatus: async () => ({ attendanceStatus: 'NOT_CLOCKED_IN' }), getCurrentBill: async () => ({ currentBillCents: 1000 }), getDailyOpsReport: async () => ({ totals: { workedAssignments: 4 } }), getForecastReport: async () => ({ totals: { projectedCoveragePercentage: 92 } }), getNoShowReport: async () => ({ totals: { noShows: 1 } }), getPaymentChart: async () => ([{ amountCents: 100 }]), getPaymentsSummary: async () => ({ totalEarningsCents: 500 }), getPersonalInfo: async () => ({ firstName: 'Ana' }), getPerformanceReport: async () => ({ totals: { averageRating: 4.8 } }), getProfileSectionsStatus: async () => ({ personalInfoCompleted: true }), getPrivacySettings: async () => ({ profileVisibility: 'TEAM_ONLY' }), getReportSummary: async () => ({ reportDate: '2026-03-13', totals: { orders: 3 } }), getSavings: async () => ({ savingsCents: 200 }), getSpendReport: async () => ({ totals: { amountCents: 2000 } }), getSpendBreakdown: async () => ([{ category: 'Barista', amountCents: 1000 }]), getStaffDashboard: async () => ({ staffName: 'Ana Barista' }), getStaffReliabilityStats: async () => ({ totalShifts: 12, reliabilityScore: 96.4 }), getStaffProfileCompletion: async () => ({ completed: true }), getStaffSession: async () => ({ staff: { staffId: 's1' } }), getStaffShiftDetail: async () => ({ shiftId: 'shift-1' }), listAssignedShifts: async () => ([{ shiftId: 'assigned-1' }]), listBusinessAccounts: async () => ([{ accountId: 'acc-1' }]), listCancelledShifts: async () => ([{ shiftId: 'cancelled-1' }]), listCertificates: async () => ([{ certificateId: 'cert-1' }]), listCostCenters: async () => ([{ costCenterId: 'cc-1' }]), listCoverageByDate: async () => ([{ shiftId: 'coverage-1' }]), listCoreTeam: async () => ([{ staffId: 'core-1' }]), listCompletedShifts: async () => ([{ shiftId: 'completed-1' }]), listCoverageDispatchCandidates: async () => ([{ staffId: 'dispatch-1' }]), listCoverageDispatchTeams: async () => ([{ membershipId: 'dispatch-team-1' }]), listEmergencyContacts: async () => ([{ contactId: 'ec-1' }]), listFaqCategories: async () => ([{ id: 'faq-1', title: 'Clock in' }]), listGeofenceIncidents: async () => ([{ incidentId: 'incident-1' }]), listHubManagers: async () => ([{ managerId: 'm1' }]), listHubs: async () => ([{ hubId: 'hub-1' }]), listIndustries: async () => (['CATERING']), listInvoiceHistory: async () => ([{ invoiceId: 'inv-1' }]), listAvailableOrders: async () => ([{ orderId: 'order-available-1', roleId: 'role-catalog-1' }]), listOpenShifts: async () => ([{ shiftId: 'open-1' }]), getOrderReorderPreview: async () => ({ orderId: 'order-1', lines: 2 }), listOrderItemsByDateRange: async () => ([{ itemId: 'item-1' }]), listPaymentsHistory: async () => ([{ paymentId: 'pay-1' }]), listPendingAssignments: async () => ([{ assignmentId: 'asg-1' }]), listPendingInvoices: async () => ([{ invoiceId: 'pending-1' }]), listProfileDocuments: async () => ([{ staffDocumentId: 'doc-1' }]), listRecentReorders: async () => ([{ id: 'order-1' }]), listBusinessTeamMembers: async () => ([{ userId: 'u-1' }]), listSkills: async () => (['BARISTA']), listStaffAvailability: async () => ([{ dayOfWeek: 1 }]), listStaffBankAccounts: async () => ([{ accountId: 'acc-2' }]), listStaffBenefits: async () => ([{ benefitId: 'benefit-1' }]), listTaxForms: async () => ([{ formType: 'W4' }]), listAttireChecklist: async () => ([{ documentId: 'attire-1' }]), listTimeCardEntries: async () => ([{ entryId: 'tc-1' }]), listSwapRequests: async () => ([{ swapRequestId: 'swap-1' }]), listTodayShifts: async () => ([{ shiftId: 'today-1' }]), listVendorRoles: async () => ([{ roleId: 'role-1' }]), listVendors: async () => ([{ vendorId: 'vendor-1' }]), searchFaqs: async () => ([{ id: 'faq-2', title: 'Payments' }]), }; } test('GET /query/client/session returns injected client session', async () => { const app = createApp({ mobileQueryService: createMobileQueryService() }); const res = await request(app) .get('/query/client/session') .set('Authorization', 'Bearer test-token'); assert.equal(res.status, 200); assert.equal(res.body.business.businessId, 'b1'); }); test('GET /query/client/coverage validates date query param', async () => { const app = createApp({ mobileQueryService: createMobileQueryService() }); const res = await request(app) .get('/query/client/coverage') .set('Authorization', 'Bearer test-token'); assert.equal(res.status, 400); assert.equal(res.body.code, 'VALIDATION_ERROR'); }); test('GET /query/staff/dashboard returns injected dashboard', async () => { const app = createApp({ mobileQueryService: createMobileQueryService() }); const res = await request(app) .get('/query/staff/dashboard') .set('Authorization', 'Bearer test-token'); assert.equal(res.status, 200); assert.equal(res.body.staffName, 'Ana Barista'); }); test('GET /query/staff/profile/stats returns injected reliability stats', async () => { const app = createApp({ mobileQueryService: createMobileQueryService() }); const res = await request(app) .get('/query/staff/profile/stats') .set('Authorization', 'Bearer test-token'); assert.equal(res.status, 200); assert.equal(res.body.totalShifts, 12); assert.equal(res.body.reliabilityScore, 96.4); }); test('GET /query/staff/shifts/:shiftId returns injected shift detail', async () => { const app = createApp({ mobileQueryService: createMobileQueryService() }); const res = await request(app) .get('/query/staff/shifts/shift-1') .set('Authorization', 'Bearer test-token'); assert.equal(res.status, 200); assert.equal(res.body.shiftId, 'shift-1'); }); test('GET /query/staff/orders/available returns injected order-level opportunities', async () => { const app = createApp({ mobileQueryService: createMobileQueryService() }); const res = await request(app) .get('/query/staff/orders/available') .set('Authorization', 'Bearer test-token'); assert.equal(res.status, 200); assert.equal(res.body.items[0].orderId, 'order-available-1'); assert.equal(res.body.items[0].roleId, 'role-catalog-1'); }); test('GET /query/client/shifts/scheduled returns injected shift timeline items', async () => { const app = createApp({ mobileQueryService: createMobileQueryService() }); const res = await request(app) .get('/query/client/shifts/scheduled?startDate=2026-03-13T00:00:00.000Z&endDate=2026-03-20T00:00:00.000Z') .set('Authorization', 'Bearer test-token'); assert.equal(res.status, 200); assert.equal(res.body.items[0].itemId, 'item-1'); }); test('GET /query/client/orders/view remains as deprecated compatibility alias', async () => { const app = createApp({ mobileQueryService: createMobileQueryService() }); const res = await request(app) .get('/query/client/orders/view?startDate=2026-03-13T00:00:00.000Z&endDate=2026-03-20T00:00:00.000Z') .set('Authorization', 'Bearer test-token'); assert.equal(res.status, 200); assert.equal(res.headers.deprecation, 'true'); assert.equal(res.headers.link, '; rel="successor-version"'); assert.equal(res.body.items[0].itemId, 'item-1'); }); test('GET /query/client/reports/summary returns injected report summary', async () => { const app = createApp({ mobileQueryService: createMobileQueryService() }); const res = await request(app) .get('/query/client/reports/summary?date=2026-03-13') .set('Authorization', 'Bearer test-token'); assert.equal(res.status, 200); assert.equal(res.body.totals.orders, 3); }); test('GET /query/client/coverage/core-team returns injected core team list', async () => { const app = createApp({ mobileQueryService: createMobileQueryService() }); const res = await request(app) .get('/query/client/coverage/core-team?date=2026-03-13') .set('Authorization', 'Bearer test-token'); assert.equal(res.status, 200); assert.equal(res.body.items[0].staffId, 'core-1'); }); test('GET /query/client/coverage/incidents returns injected incidents list', async () => { const app = createApp({ mobileQueryService: createMobileQueryService() }); const res = await request(app) .get('/query/client/coverage/incidents?startDate=2026-03-01&endDate=2026-03-16') .set('Authorization', 'Bearer test-token'); assert.equal(res.status, 200); assert.equal(res.body.items[0].incidentId, 'incident-1'); }); test('GET /query/client/coverage/swap-requests returns injected swap request list', async () => { const app = createApp({ mobileQueryService: createMobileQueryService() }); const res = await request(app) .get('/query/client/coverage/swap-requests?status=OPEN') .set('Authorization', 'Bearer test-token'); assert.equal(res.status, 200); assert.equal(res.body.items[0].swapRequestId, 'swap-1'); }); test('GET /query/client/coverage/dispatch-teams returns injected dispatch team memberships', async () => { const app = createApp({ mobileQueryService: createMobileQueryService() }); const res = await request(app) .get('/query/client/coverage/dispatch-teams') .set('Authorization', 'Bearer test-token'); assert.equal(res.status, 200); assert.equal(res.body.items[0].membershipId, 'dispatch-team-1'); }); test('GET /query/client/coverage/dispatch-candidates returns injected candidate list', async () => { const app = createApp({ mobileQueryService: createMobileQueryService() }); const res = await request(app) .get('/query/client/coverage/dispatch-candidates?shiftId=shift-1') .set('Authorization', 'Bearer test-token'); assert.equal(res.status, 200); assert.equal(res.body.items[0].staffId, 'dispatch-1'); }); test('GET /query/staff/profile/tax-forms returns injected tax forms', async () => { const app = createApp({ mobileQueryService: createMobileQueryService() }); const res = await request(app) .get('/query/staff/profile/tax-forms') .set('Authorization', 'Bearer test-token'); assert.equal(res.status, 200); assert.equal(res.body.items[0].formType, 'W4'); }); test('GET /query/staff/faqs/search returns injected faq search results', async () => { const app = createApp({ mobileQueryService: createMobileQueryService() }); const res = await request(app) .get('/query/staff/faqs/search?q=payments') .set('Authorization', 'Bearer test-token'); assert.equal(res.status, 200); assert.equal(res.body.items[0].title, 'Payments'); });