> rentaldrivego@1.0.0 test:api > npm run test --workspace @rentaldrivego/api > @rentaldrivego/api@1.0.0 pretest > npm run build --workspace @rentaldrivego/types > @rentaldrivego/types@1.0.0 build > tsc > @rentaldrivego/api@1.0.0 test > vitest run The CJS build of Vite's Node API is deprecated. See https://vite.dev/guide/troubleshooting.html#vite-cjs-node-api-deprecated for more details. RUN v1.6.1 /Volumes/ExternalApps/Documents/car_management_system/apps/api ❯ src/modules/site/site.service.boundary.test.ts (5 tests | 3 failed) 14ms ❯ src/modules/site/site.service.boundary.test.ts > site.service public booking/payment boundaries > calculates booking totals from base rate, free-day promo, pricing rules, insurance and additional drivers → Cannot read properties of undefined (reading 'catch') ❯ src/modules/site/site.service.boundary.test.ts > site.service public booking/payment boundaries > rejects payment initialization for already-paid reservations before provider calls → expected AppError: Booking access token is required { …(3) } to match object { statusCode: 409, …(1) } (3 matching properties omitted from actual) ❯ src/modules/site/site.service.boundary.test.ts > site.service public booking/payment boundaries > blocks payment when the primary or additional driver license requires review → expected AppError: Booking access token is required { …(3) } to match object { statusCode: 409, …(1) } (3 matching properties omitted from actual) ✓ src/modules/marketplace/marketplace.test.ts (16 tests) 17ms ✓ src/modules/vehicles/vehicle.pricing.service.test.ts (7 tests) 8ms ✓ src/modules/payments/payment.service.test.ts (7 tests) 8ms ✓ src/modules/subscriptions/subscription.service.edge.test.ts (7 tests) 8ms ✓ src/modules/reservations/reservation.test.ts (14 tests) 11ms ✓ src/modules/vehicles/vehicle.test.ts (15 tests) 10ms ❯ src/modules/site/site.test.ts (13 tests | 5 failed) 20ms ❯ src/modules/site/site.test.ts > createBooking > creates a booking and returns reservation with requiresManualApproval flag → [vitest] No "createReservationPublicAccess" export is defined on the "./site.repo" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: ❯ src/modules/site/site.test.ts > initPayment — payment guard paths > throws AppError when reservation is already paid → expected AppError: Booking access token is required { …(3) } to match object { error: 'already_paid' } (3 matching properties omitted from actual) ❯ src/modules/site/site.test.ts > initPayment — payment guard paths > throws AppError when license review is required → expected AppError: Booking access token is required { …(3) } to match object { error: 'license_review_required' } (3 matching properties omitted from actual) ❯ src/modules/site/site.test.ts > initPayment — payment guard paths > throws AppError when PayPal is not configured → expected AppError: Booking access token is required { …(3) } to match object { error: 'provider_not_configured' } (3 matching properties omitted from actual) ❯ src/modules/site/site.test.ts > initPayment — payment guard paths > returns checkoutUrl when PayPal is configured → Booking access token is required ✓ src/modules/menu/menu.service.test.ts (2 tests) 4ms ❯ src/modules/menu/menu.service.boundary.test.ts (7 tests | 4 failed) 13ms ❯ src/modules/menu/menu.service.boundary.test.ts > menu.service mutation boundaries > rejects external links that are not HTTPS before any write → expected AppError: External links must use HTTPS. { …(3) } to match object { statusCode: 400, …(1) } (3 matching properties omitted from actual) ❯ src/modules/menu/menu.service.boundary.test.ts > menu.service mutation boundaries > rejects duplicate routes under the same parent with a conflict error → expected AppError: Parent menu item was not found. { …(3) } to match object { statusCode: 409, …(1) } (3 matching properties omitted from actual) ❯ src/modules/menu/menu.service.boundary.test.ts > menu.service mutation boundaries > protects required menu items from non-super-admin disable attempts → expected AppError: Required system items can only … { …(3) } to match object { statusCode: 403, code: 'forbidden' } (3 matching properties omitted from actual) ❯ src/modules/menu/menu.service.boundary.test.ts > menu.service mutation boundaries > rejects company assignments when any company is cancelled or missing → expected AppError: Menu items can only be assigned… { …(3) } to match object { statusCode: 400, …(1) } (3 matching properties omitted from actual) ✓ src/services/containerService.test.ts (4 tests) 8ms ✓ src/middleware/requireAdminAuth.test.ts (9 tests) 7ms ✓ src/modules/customers/customer.test.ts (12 tests) 38ms ✓ src/modules/reservations/reservation.lifecycle.service.test.ts (5 tests) 6ms ✓ src/modules/reviews/review.service.test.ts (5 tests) 8ms ✓ src/modules/auth/auth.company.service.test.ts (6 tests) 6ms ✓ src/modules/customers/customer.edge.test.ts (6 tests) 6ms ✓ src/modules/analytics/analytics.service.test.ts (4 tests) 5ms ✓ src/modules/auth/auth.employee.service.edge.test.ts (8 tests) 8ms ❯ src/tests/api/auth-middleware.api.test.ts (8 tests | 2 failed) 55ms ❯ src/tests/api/auth-middleware.api.test.ts > auth middleware API boundaries > rejects employee-protected routes when a renter token is used → expected { error: 'invalid_token', …(2) } to deeply equal { error: 'invalid_token', …(2) } ❯ src/tests/api/auth-middleware.api.test.ts > auth middleware API boundaries > allows valid admin tokens through protected admin read routes → expected 403 to be 200 // Object.is equality ❯ src/tests/api/public-validation.api.test.ts (8 tests | 1 failed) 58ms ❯ src/tests/api/public-validation.api.test.ts > public validation API contracts > defaults site payment currency to MAD for valid public payment requests → expected 400 to be 200 // Object.is equality ✓ src/tests/api/auth-boundaries.api.test.ts (7 tests) 60ms ✓ src/tests/api/operations.api.test.ts (10 tests) 73ms ✓ src/modules/companies/company.service.edge.test.ts (7 tests) 8ms ✓ src/tests/api/customer-notification-analytics.api.test.ts (7 tests) 79ms ✓ src/tests/api/operations-validation.api.test.ts (6 tests) 60ms ✓ src/tests/api/company-configuration.api.test.ts (7 tests) 90ms ✓ src/modules/customers/customer.service.boundary.test.ts (6 tests) 6ms ✓ src/middleware/requireApiKey.test.ts (6 tests) 10ms ✓ src/modules/reservations/reservation.inspection.service.test.ts (5 tests) 8ms ✓ src/modules/companies/company.test.ts (10 tests) 7ms ✓ src/services/notificationService.test.ts (3 tests) 5ms ✓ src/services/financialReportService.test.ts (4 tests) 9ms ✓ src/modules/marketplace/marketplace.repo.edge.test.ts (6 tests) 6ms ✓ src/middleware/requireCompanyAuth.test.ts (6 tests) 9ms ❯ src/tests/api/employee-marketplace-notification.api.test.ts (0 test) ✓ src/services/paypalService.test.ts (4 tests) 12ms ✓ src/modules/vehicles/vehicle.service.edge.test.ts (5 tests) 6ms ✓ src/modules/subscriptions/subscription.repo.edge.test.ts (6 tests) 8ms ✓ src/services/vehicleAvailabilityService.test.ts (5 tests) 6ms stderr | src/services/notificationLocalizationService.boundary.test.ts > notificationLocalizationService formatting and fallback boundaries > throws a clear error when neither requested nor fallback templates exist [Notifications] Missing fr template for missing.template/EMAIL; falling back to en. ✓ src/services/notificationLocalizationService.boundary.test.ts (8 tests) 15ms ✓ src/modules/site/site.repo.edge.test.ts (5 tests) 5ms ✓ src/modules/marketplace/marketplace.service.edge.test.ts (5 tests) 5ms ✓ src/middleware/requireRenterAuth.test.ts (6 tests) 8ms ✓ src/services/pricingRuleService.test.ts (3 tests) 5ms ✓ src/modules/subscriptions/subscription.entitlement.test.ts (5 tests) 13ms ❯ src/tests/api/feedback-offer-boundaries.api.test.ts (0 test) ✓ src/modules/vehicles/vehicle.schemas.test.ts (7 tests) 7ms ❯ src/tests/api/subscription-team-boundaries.api.test.ts (0 test) ❯ src/tests/api/admin-billing.api.test.ts (6 tests | 5 failed) 73ms ❯ src/tests/api/admin-billing.api.test.ts > admin billing API contracts > coerces list filters and requires finance access → expected 403 to be 200 // Object.is equality ❯ src/tests/api/admin-billing.api.test.ts > admin billing API contracts > rejects oversized billing pagination before service execution → expected 403 to be 400 // Object.is equality ❯ src/tests/api/admin-billing.api.test.ts > admin billing API contracts > streams invoice PDFs with content headers from the service boundary → expected 403 to be 200 // Object.is equality ❯ src/tests/api/admin-billing.api.test.ts > admin billing API contracts > passes parsed account updates with admin identity and request ip → expected 403 to be 200 // Object.is equality ❯ src/tests/api/admin-billing.api.test.ts > admin billing API contracts > rejects malformed draft invoice payloads before invoice creation → expected 403 to be 400 // Object.is equality ✓ src/modules/auth/auth.company.repo.test.ts (1 test) 6ms ✓ src/modules/vehicles/vehicle.repo.edge.test.ts (5 tests) 7ms ✓ src/tests/api/vehicle-pricing.api.test.ts (5 tests) 68ms ✓ src/modules/notifications/notification.repo.edge.test.ts (6 tests) 10ms ✓ src/modules/offers/offer.repo.edge.test.ts (5 tests) 7ms ✓ src/modules/notifications/notification.service.test.ts (4 tests) 5ms ✓ src/modules/companies/company.repo.edge.test.ts (6 tests) 6ms ✓ src/services/amanpayService.test.ts (4 tests) 14ms ✓ src/modules/companies/company.presenter.test.ts (14 tests) 4ms ✓ src/modules/auth/auth.schemas.test.ts (3 tests) 5ms ❯ src/tests/api/admin-menu-boundaries.api.test.ts (5 tests | 5 failed) 76ms ❯ src/tests/api/admin-menu-boundaries.api.test.ts > admin menu API contracts > rejects menu item creation with blank labels before service execution → expected 403 to be 400 // Object.is equality ❯ src/tests/api/admin-menu-boundaries.api.test.ts > admin menu API contracts > passes normalized menu item creation payload with admin actor → expected 403 to be 201 // Object.is equality ❯ src/tests/api/admin-menu-boundaries.api.test.ts > admin menu API contracts > rejects invalid menu status bodies before mutation → expected 403 to be 400 // Object.is equality ❯ src/tests/api/admin-menu-boundaries.api.test.ts > admin menu API contracts > requires admin privileges for menu mutations while support can preview → expected 403 to be 200 // Object.is equality ❯ src/tests/api/admin-menu-boundaries.api.test.ts > admin menu API contracts > coerces audit-log pagination defaults and caps oversized limits → expected 403 to be 200 // Object.is equality ✓ src/modules/reservations/reservation.repo.edge.test.ts (4 tests) 4ms ✓ src/modules/complaints/complaint.service.test.ts (5 tests) 5ms ✓ src/modules/offers/offer.service.test.ts (5 tests) 4ms ✓ src/modules/auth/auth.role-specific-schemas.test.ts (5 tests) 5ms ✓ src/modules/reservations/reservation.presenter.boundary.test.ts (6 tests) 4ms ❯ src/http/errors/errorMiddleware.test.ts (10 tests | 1 failed) 10ms ❯ src/http/errors/errorMiddleware.test.ts > errorMiddleware > falls back to a 500 internal error response → expected "spy" to be called with arguments: [ { error: 'internal_error', …(2) } ] Received: 1st spy call: Array [ Object { "error": "internal_error", - "message": "boom", + "message": "Internal server error", + "requestId": undefined, "statusCode": 500, }, ] Number of calls: 1 ✓ src/modules/reservations/reservation.document.service.test.ts (3 tests) 2ms ✓ src/modules/auth/auth.presenter.test.ts (4 tests) 3ms ✓ src/modules/reservations/reservation.photo.service.test.ts (4 tests) 4ms ✓ src/modules/auth/auth.renter.service.test.ts (5 tests) 5ms ✓ src/modules/operations.schemas.test.ts (2 tests) 6ms ✓ src/services/notificationLocalizationService.test.ts (3 tests) 5ms stderr | src/services/notificationLocalizationService.test.ts > notificationLocalizationService > falls back to English when a localized template is missing [Notifications] Missing ar template for booking.confirmed/EMAIL; falling back to en. ❯ src/tests/api/payments.api.test.ts (5 tests | 2 failed) 94ms ❯ src/tests/api/payments.api.test.ts > payments API contract > accepts valid AmanPay webhooks and delegates the exact payload → expected "spy" to be called with arguments: [ { transaction_id: 'txn_1', …(1) } ] Received: 1st spy call: Array [ Object { "status": "PAID", "transaction_id": "txn_1", }, + "{\"transaction_id\":\"txn_1\",\"status\":\"PAID\"}", ] Number of calls: 1 ❯ src/tests/api/payments.api.test.ts > payments API contract > accepts verified PayPal webhooks and delegates handling → expected "spy" to be called with arguments: [ { …(2) } ] Received: 1st spy call: Array [ Object { "event_type": "PAYMENT.CAPTURE.COMPLETED", "resource": Object { "id": "capture_1", }, }, + "{\"event_type\":\"PAYMENT.CAPTURE.COMPLETED\",\"resource\":{\"id\":\"capture_1\"}}", ] Number of calls: 1 ❯ src/modules/site/site.schemas.test.ts (4 tests | 1 failed) 12ms ❯ src/modules/site/site.schemas.test.ts > site.schemas > rejects malformed availability and payment payloads at the schema layer → [ { "code": "invalid_type", "expected": "string", "received": "undefined", "path": [ "accessToken" ], "message": "Required" } ] ✓ src/services/insuranceService.test.ts (2 tests) 4ms ✓ src/tests/api/site-webhook-boundaries.api.test.ts (5 tests) 116ms ✓ src/modules/companies/company.schemas.edge.test.ts (3 tests) 8ms ✓ src/services/additionalDriverService.test.ts (3 tests) 5ms ✓ src/middleware/rateLimiter.test.ts (3 tests) 11ms ✓ src/modules/payments/payment.repo.edge.test.ts (5 tests) 7ms ✓ src/modules/reservations/reservation.schemas.edge.test.ts (3 tests) 7ms ✓ src/lib/storage.test.ts (4 tests) 4ms ❯ src/tests/api/subscriptions.api.test.ts (5 tests | 1 failed) 65ms ❯ src/tests/api/subscriptions.api.test.ts > subscriptions public API > accepts verified PayPal webhooks and delegates handling to the subscription service → expected "spy" to be called with arguments: [ { …(2) } ] Received: 1st spy call: Array [ Object { "event_type": "PAYMENT.CAPTURE.COMPLETED", "resource": Object { "id": "capture_1", }, }, + "{\"event_type\":\"PAYMENT.CAPTURE.COMPLETED\",\"resource\":{\"id\":\"capture_1\"}}", ] Number of calls: 1 ✓ src/modules/complaints/complaint.repo.edge.test.ts (4 tests) 4ms ❯ src/lib/emailTranslations.test.ts (5 tests | 1 failed) 8ms ❯ src/lib/emailTranslations.test.ts > emailTranslations > formats dates with the locale-specific formatter → expected '2 فبراير 2026' to contain '٢٠٢٦' ✓ src/middleware/requireSubscription.test.ts (4 tests) 5ms ✓ src/services/licenseValidationService.test.ts (4 tests) 6ms ✓ src/modules/reviews/review.repo.edge.test.ts (4 tests) 7ms ✓ src/modules/admin/admin.repo.edge.test.ts (3 tests) 8ms ✓ src/modules/subscriptions/subscription.schemas.edge.test.ts (4 tests) 3ms ❯ src/services/platformContentService.test.ts (2 tests | 2 failed) 14ms ❯ src/services/platformContentService.test.ts > platformContentService > returns cloned default homepage content when the file does not exist or cannot be parsed → process.chdir() is not supported in workers → process.chdir() is not supported in workers ❯ src/services/platformContentService.test.ts > platformContentService > saves only the marketplace homepage field while preserving unrelated platform content fields → process.chdir() is not supported in workers → process.chdir() is not supported in workers ✓ src/modules/auth/auth.employee.service.test.ts (2 tests) 659ms ✓ src/services/teamService.test.ts (1 test) 3ms ✓ src/middleware/requireTenant.test.ts (3 tests) 3ms ✓ src/modules/auth/auth.employee.repo.edge.test.ts (5 tests) 7ms ✓ src/tests/api/api-foundation.api.test.ts (6 tests) 79ms ✓ src/swagger/openapi.boundary.test.ts (3 tests) 4ms ✓ src/modules/customers/customer.schemas.contract.test.ts (5 tests) 5ms ❯ src/services/invoicePdfService.test.ts (2 tests | 1 failed) 11ms ❯ src/services/invoicePdfService.test.ts > invoicePdfService > builds stable legacy invoice numbers from the creation year and id suffix → expected 'INV-2026-SHORT' to be 'INV-2027-SHORT' // Object.is equality ✓ src/modules/customers/customer.repo.boundary.test.ts (3 tests) 10ms ✓ src/middleware/authHelpers.test.ts (5 tests) 4ms ✓ src/modules/admin/admin.menu.schemas.test.ts (4 tests) 5ms ✓ src/modules/admin/admin.billing.schemas.test.ts (4 tests) 5ms ✓ src/modules/marketplace/marketplace.schemas.test.ts (4 tests) 8ms ❯ src/tests/e2e/vehicle-pricing-boundaries.e2e.test.ts (1 test | 1 failed) 50ms ❯ src/tests/e2e/vehicle-pricing-boundaries.e2e.test.ts > vehicle pricing e2e boundaries > rejects anonymous and malformed pricing requests without invoking pricing services → expected 401 to be 400 // Object.is equality ✓ src/modules/reservations/reservation.additional-driver.service.test.ts (2 tests) 3ms ✓ src/tests/e2e/operations-validation-smoke.e2e.test.ts (1 test) 53ms ✓ src/tests/e2e/public-validation-smoke.e2e.test.ts (1 test) 109ms ✓ src/modules/subscriptions/subscription.policy.test.ts (4 tests) 5ms ✓ src/modules/site/site.presenter.test.ts (2 tests) 3ms ✓ src/middleware/requireRole.test.ts (3 tests) 4ms ❯ src/http/upload/upload.test.ts (4 tests | 3 failed) 7ms ❯ src/http/upload/upload.test.ts > upload assertions > accepts a single image file and narrows the route input → expected [Function] to not throw an error but 'ValidationError: Unsupported or spoof…' was thrown ❯ src/http/upload/upload.test.ts > upload assertions > rejects non-image single file uploads → expected [Function] to throw error including 'Only image uploads are supported' but got 'Unsupported or spoofed image file' ❯ src/http/upload/upload.test.ts > upload assertions > accepts multiple image files and rejects empty or mixed batches → expected [Function] to not throw an error but 'ValidationError: Unsupported or spoof…' was thrown ✓ src/modules/team/team.service.test.ts (2 tests) 3ms ✓ src/modules/team/team.schemas.edge.test.ts (3 tests) 3ms ✓ src/modules/payments/payment.schemas.edge.test.ts (2 tests) 4ms ✓ src/modules/customers/customer.presenter.test.ts (2 tests) 3ms ✓ src/modules/offers/offer.schemas.edge.test.ts (4 tests) 6ms ✓ src/tests/e2e/customer-boundaries.e2e.test.ts (1 test) 61ms ✓ src/http/respond/respond.test.ts (3 tests) 5ms ✓ src/modules/notifications/notification.schemas.edge.test.ts (3 tests) 5ms ✓ src/modules/admin/admin.service.test.ts (1 test) 3ms ✓ src/modules/complaints/complaint.schemas.edge.test.ts (5 tests) 6ms ✓ src/modules/reservations/reservation.pricing.service.test.ts (3 tests) 2ms ❯ src/tests/e2e/admin-billing-boundaries.e2e.test.ts (1 test | 1 failed) 36ms ❯ src/tests/e2e/admin-billing-boundaries.e2e.test.ts > admin billing e2e boundaries > rejects anonymous billing access and malformed invoice creation without touching services → expected 401 to be 400 // Object.is equality ✓ src/tests/e2e/subscriptions-public.e2e.test.ts (1 test) 64ms ✓ src/modules/reservations/reservation.presenter.test.ts (1 test) 1ms ✓ src/modules/vehicles/vehicle.presenter.edge.test.ts (2 tests) 2ms ✓ src/http/validate/validate.test.ts (3 tests) 7ms ❯ src/tests/e2e/admin-menu-boundaries.e2e.test.ts (0 test) ✓ src/modules/auth/auth.employee.repo.test.ts (2 tests) 2ms ✓ src/tests/e2e/api-smoke.e2e.test.ts (1 test) 58ms ✓ src/modules/admin/admin.presenter.test.ts (3 tests) 2ms ✓ src/tests/e2e/site-webhook-boundaries.e2e.test.ts (1 test) 44ms ✓ src/modules/reviews/review.schemas.edge.test.ts (4 tests) 4ms ✓ src/tests/e2e/storage-boundaries.e2e.test.ts (1 test) 33ms ✓ src/modules/marketplace/marketplace.presenter.test.ts (1 test) 2ms ✓ src/lib/isDatabaseUnavailable.test.ts (3 tests) 2ms ✓ src/modules/analytics/analytics.schemas.edge.test.ts (3 tests) 6ms ✓ src/modules/admin/admin.repo.test.ts (1 test) 3ms ✓ src/tests/e2e/payments-webhook-public.e2e.test.ts (1 test) 29ms ✓ src/tests/e2e/protected-auth-boundaries.e2e.test.ts (1 test) 35ms ✓ src/tests/e2e/operations-auth-boundaries.e2e.test.ts (1 test) 43ms ✓ src/tests/e2e/feedback-offer-boundaries.e2e.test.ts (1 test) 34ms ✓ src/tests/e2e/employee-marketplace-boundaries.e2e.test.ts (2 tests) 40ms ✓ src/tests/e2e/auth-public-disabled.e2e.test.ts (1 test) 27ms ✓ src/tests/e2e/subscription-team-boundaries.e2e.test.ts (1 test) 23ms ✓ src/tests/e2e/company-configuration-boundaries.e2e.test.ts (1 test) 17ms ⎯⎯⎯⎯⎯⎯ Failed Suites 4 ⎯⎯⎯⎯⎯⎯⎯ FAIL src/tests/api/employee-marketplace-notification.api.test.ts [ src/tests/api/employee-marketplace-notification.api.test.ts ] FAIL src/tests/api/feedback-offer-boundaries.api.test.ts [ src/tests/api/feedback-offer-boundaries.api.test.ts ] FAIL src/tests/api/subscription-team-boundaries.api.test.ts [ src/tests/api/subscription-team-boundaries.api.test.ts ] Error: [vitest] No "requireCompanyDocumentAuth" export is defined on the "../../middleware/requireCompanyAuth" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: vi.mock("../../middleware/requireCompanyAuth", async (importOriginal) => { const actual = await importOriginal() return { ...actual, // your mocked methods } }) ❯ src/modules/customers/customer.routes.ts:14:34 12| const router = Router() 13| 14| router.get('/:id/license-image', requireCompanyDocumentAuth, requireTe… | ^ 15| try { 16| const { id } = parseParams(idParamSchema, req) ❯ src/app.ts:21:32 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/45]⎯ FAIL src/tests/e2e/admin-menu-boundaries.e2e.test.ts [ src/tests/e2e/admin-menu-boundaries.e2e.test.ts ] Error: [vitest] No "requireFreshAdmin2FA" export is defined on the "../../middleware/requireAdminAuth" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: vi.mock("../../middleware/requireAdminAuth", async (importOriginal) => { const actual = await importOriginal() return { ...actual, // your mocked methods } }) ❯ src/modules/admin/admin.routes.ts:99:70 97| }) 98| 99| router.post('/auth/2fa/recovery-codes/regenerate', requireAdminAuth, r… | ^ 100| try { 101| ok(res, await service.regenerateRecoveryCodes(req.admin.id)) ❯ src/app.ts:18:32 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/45]⎯ ⎯⎯⎯⎯⎯⎯ Failed Tests 39 ⎯⎯⎯⎯⎯⎯⎯ FAIL src/lib/emailTranslations.test.ts > emailTranslations > formats dates with the locale-specific formatter AssertionError: expected '2 فبراير 2026' to contain '٢٠٢٦' - Expected + Received - ٢٠٢٦ + 2 فبراير 2026 ❯ src/lib/emailTranslations.test.ts:67:68 65| expect(formatDate(new Date('2026-02-03T00:00:00.000Z'), 'en')).toC… 66| expect(formatDate(new Date('2026-02-03T00:00:00.000Z'), 'fr')).toC… 67| expect(formatDate(new Date('2026-02-03T00:00:00.000Z'), 'ar')).toC… | ^ 68| }) 69| }) ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/45]⎯ FAIL src/services/invoicePdfService.test.ts > invoicePdfService > builds stable legacy invoice numbers from the creation year and id suffix AssertionError: expected 'INV-2026-SHORT' to be 'INV-2027-SHORT' // Object.is equality - Expected + Received - INV-2027-SHORT + INV-2026-SHORT ❯ src/services/invoicePdfService.test.ts:23:79 21| it('builds stable legacy invoice numbers from the creation year and … 22| expect(buildInvoiceNumber('invoice_abcdef', new Date('2026-06-09T1… 23| expect(buildInvoiceNumber('short', new Date('2027-01-01T00:00:00.0… | ^ 24| }) 25| ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/45]⎯ FAIL src/services/platformContentService.test.ts > platformContentService > returns cloned default homepage content when the file does not exist or cannot be parsed FAIL src/services/platformContentService.test.ts > platformContentService > saves only the marketplace homepage field while preserving unrelated platform content fields TypeError: process.chdir() is not supported in workers ❯ src/services/platformContentService.test.ts:19:13 17| tempDir = await mkdtemp(path.join(os.tmpdir(), 'rdg-platform-conte… 18| await import('fs/promises').then((fs) => fs.mkdir(path.join(tempDi… 19| process.chdir(path.join(tempDir, 'apps/api')) | ^ 20| }) 21| ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Serialized Error: { code: 'ERR_WORKER_UNSUPPORTED_OPERATION' } ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/45]⎯ FAIL src/services/platformContentService.test.ts > platformContentService > returns cloned default homepage content when the file does not exist or cannot be parsed FAIL src/services/platformContentService.test.ts > platformContentService > saves only the marketplace homepage field while preserving unrelated platform content fields TypeError: process.chdir() is not supported in workers ❯ src/services/platformContentService.test.ts:23:13 21| 22| afterEach(async () => { 23| process.chdir(originalCwd) | ^ 24| await rm(tempDir, { recursive: true, force: true }) 25| vi.resetModules() ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Serialized Error: { code: 'ERR_WORKER_UNSUPPORTED_OPERATION' } ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[6/45]⎯ FAIL src/http/errors/errorMiddleware.test.ts > errorMiddleware > falls back to a 500 internal error response AssertionError: expected "spy" to be called with arguments: [ { error: 'internal_error', …(2) } ] Received: 1st spy call: Array [ Object { "error": "internal_error", - "message": "boom", + "message": "Internal server error", + "requestId": undefined, "statusCode": 500, }, ] Number of calls: 1 ❯ src/http/errors/errorMiddleware.test.ts:95:22 93| 94| expect(res.status).toHaveBeenCalledWith(500) 95| expect(res.json).toHaveBeenCalledWith({ error: 'internal_error', m… | ^ 96| 97| spy.mockRestore() ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[7/45]⎯ FAIL src/http/upload/upload.test.ts > upload assertions > accepts a single image file and narrows the route input AssertionError: expected [Function] to not throw an error but 'ValidationError: Unsupported or spoof…' was thrown - Expected: undefined + Received: "ValidationError: Unsupported or spoofed image file" ❯ src/http/upload/upload.test.ts:21:47 19| describe('upload assertions', () => { 20| it('accepts a single image file and narrows the route input', () => { 21| expect(() => assertImageFile(file())).not.toThrow() | ^ 22| }) 23| ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[8/45]⎯ FAIL src/http/upload/upload.test.ts > upload assertions > rejects non-image single file uploads AssertionError: expected [Function] to throw error including 'Only image uploads are supported' but got 'Unsupported or spoofed image file' - Expected + Received - Only image uploads are supported + Unsupported or spoofed image file ❯ src/http/upload/upload.test.ts:30:103 28| 29| it('rejects non-image single file uploads', () => { 30| expect(() => assertImageFile(file({ mimetype: 'application/pdf', o… | ^ 31| }) 32| ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[9/45]⎯ FAIL src/http/upload/upload.test.ts > upload assertions > accepts multiple image files and rejects empty or mixed batches AssertionError: expected [Function] to not throw an error but 'ValidationError: Unsupported or spoof…' was thrown - Expected: undefined + Received: "ValidationError: Unsupported or spoofed image file" ❯ src/http/upload/upload.test.ts:34:102 32| 33| it('accepts multiple image files and rejects empty or mixed batches'… 34| expect(() => assertImageFiles([file({ originalname: 'front.png', m… | ^ 35| expect(() => assertImageFiles([], 'inspection photos')).toThrow('A… 36| expect(() => assertImageFiles([ ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[10/45]⎯ FAIL src/modules/menu/menu.service.boundary.test.ts > menu.service mutation boundaries > rejects external links that are not HTTPS before any write AssertionError: expected AppError: External links must use HTTPS. { …(3) } to match object { statusCode: 400, …(1) } (3 matching properties omitted from actual) - Expected + Received Object { - "code": "validation_error", "statusCode": 400, } ❯ src/modules/menu/menu.service.boundary.test.ts:45:5 43| 44| it('rejects external links that are not HTTPS before any write', asy… 45| await expect(createMenuItem({ | ^ 46| label: 'Docs', 47| itemType: 'EXTERNAL_LINK', ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[11/45]⎯ FAIL src/modules/menu/menu.service.boundary.test.ts > menu.service mutation boundaries > rejects duplicate routes under the same parent with a conflict error AssertionError: expected AppError: Parent menu item was not found. { …(3) } to match object { statusCode: 409, …(1) } (3 matching properties omitted from actual) - Expected + Received Object { - "code": "duplicate_menu_route", - "statusCode": 409, + "statusCode": 400, } ❯ src/modules/menu/menu.service.boundary.test.ts:58:5 56| vi.mocked(prisma.menuItem.findFirst).mockResolvedValue({ id: 'item… 57| 58| await expect(createMenuItem({ | ^ 59| label: 'Fleet', 60| itemType: 'INTERNAL_PAGE', ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[12/45]⎯ FAIL src/modules/menu/menu.service.boundary.test.ts > menu.service mutation boundaries > protects required menu items from non-super-admin disable attempts AssertionError: expected AppError: Required system items can only … { …(3) } to match object { statusCode: 403, code: 'forbidden' } (3 matching properties omitted from actual) - Expected + Received Object { - "code": "forbidden", "statusCode": 403, } ❯ src/modules/menu/menu.service.boundary.test.ts:121:5 119| vi.mocked(prisma.menuItem.findUniqueOrThrow).mockResolvedValue({ i… 120| 121| await expect(setMenuItemStatus('item_core', false, admin)).rejects… | ^ 122| 123| expect(prisma.menuItem.update).not.toHaveBeenCalled() ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[13/45]⎯ FAIL src/modules/menu/menu.service.boundary.test.ts > menu.service mutation boundaries > rejects company assignments when any company is cancelled or missing AssertionError: expected AppError: Menu items can only be assigned… { …(3) } to match object { statusCode: 400, …(1) } (3 matching properties omitted from actual) - Expected + Received Object { - "code": "validation_error", "statusCode": 400, } ❯ src/modules/menu/menu.service.boundary.test.ts:149:5 147| vi.mocked(prisma.company.findMany).mockResolvedValue([{ id: 'compa… 148| 149| await expect(assignMenuItemToCompanies('item_1', [ | ^ 150| { companyId: 'company_1' }, 151| { companyId: 'company_cancelled' }, ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[14/45]⎯ FAIL src/modules/site/site.schemas.test.ts > site.schemas > rejects malformed availability and payment payloads at the schema layer ZodError: [ { "code": "invalid_type", "expected": "string", "received": "undefined", "path": [ "accessToken" ], "message": "Required" } ] ❯ Object.get error [as error] ../../node_modules/zod/v3/types.js:39:31 ❯ ZodObject.parse ../../node_modules/zod/v3/types.js:114:22 ❯ src/modules/site/site.schemas.test.ts:53:22 51| expect(() => availabilitySchema.parse({ vehicleId: 'not-cuid', sta… 52| expect(() => paySchema.parse({ provider: 'STRIPE', successUrl: 'ht… 53| expect(paySchema.parse({ provider: 'PAYPAL', successUrl: 'https://… | ^ 54| }) 55| ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Serialized Error: { issues: [ { code: 'invalid_type', expected: 'string', received: 'undefined', path: [ 'accessToken' ], message: 'Required' } ], addIssue: 'Function', addIssues: 'Function', errors: [ { code: 'invalid_type', expected: 'string', received: 'undefined', path: [ 'accessToken' ], message: 'Required' } ], format: 'Function', isEmpty: false, flatten: 'Function', formErrors: { formErrors: [], fieldErrors: { accessToken: [ 'Required' ] } } } ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[15/45]⎯ FAIL src/modules/site/site.service.boundary.test.ts > site.service public booking/payment boundaries > calculates booking totals from base rate, free-day promo, pricing rules, insurance and additional drivers TypeError: Cannot read properties of undefined (reading 'catch') ❯ Module.createBooking src/modules/site/site.service.ts:223:45 221| } 222| if (body.licenseExpiry) { 223| await validateAndFlagLicense(customer.id).catch(() => null) | ^ 224| } 225| ❯ src/modules/site/site.service.boundary.test.ts:107:20 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[16/45]⎯ FAIL src/modules/site/site.service.boundary.test.ts > site.service public booking/payment boundaries > rejects payment initialization for already-paid reservations before provider calls AssertionError: expected AppError: Booking access token is required { …(3) } to match object { statusCode: 409, …(1) } (3 matching properties omitted from actual) - Expected + Received Object { - "code": "already_paid", - "statusCode": 409, + "statusCode": 403, } ❯ src/modules/site/site.service.boundary.test.ts:131:5 129| vi.mocked(repo.findReservationForPayment).mockResolvedValue({ paym… 130| 131| await expect(service.initPayment('atlas', 'reservation_1', { | ^ 132| provider: 'AMANPAY', 133| successUrl: 'https://example.test/success', ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[17/45]⎯ FAIL src/modules/site/site.service.boundary.test.ts > site.service public booking/payment boundaries > blocks payment when the primary or additional driver license requires review AssertionError: expected AppError: Booking access token is required { …(3) } to match object { statusCode: 409, …(1) } (3 matching properties omitted from actual) - Expected + Received Object { - "code": "license_review_required", - "statusCode": 409, + "statusCode": 403, } ❯ src/modules/site/site.service.boundary.test.ts:150:5 148| } as never) 149| 150| await expect(service.initPayment('atlas', 'reservation_1', { | ^ 151| provider: 'PAYPAL', 152| successUrl: 'https://example.test/success', ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[18/45]⎯ FAIL src/modules/site/site.test.ts > createBooking > creates a booking and returns reservation with requiresManualApproval flag Error: [vitest] No "createReservationPublicAccess" export is defined on the "./site.repo" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: vi.mock("./site.repo", async (importOriginal) => { const actual = await importOriginal() return { ...actual, // your mocked methods } }) ❯ Module.createBooking src/modules/site/site.service.ts:227:14 225| 226| const publicAccess = generatePublicAccessToken() 227| await repo.createReservationPublicAccess( | ^ 228| reservation.id, 229| publicAccess.tokenHash, ❯ src/modules/site/site.test.ts:175:20 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[19/45]⎯ FAIL src/modules/site/site.test.ts > initPayment — payment guard paths > throws AppError when reservation is already paid AssertionError: expected AppError: Booking access token is required { …(3) } to match object { error: 'already_paid' } (3 matching properties omitted from actual) - Expected + Received Object { - "error": "already_paid", + "error": "booking_token_required", } ❯ src/modules/site/site.test.ts:211:5 209| vi.mocked(validateLicense).mockReturnValue({ status: 'VALID', requ… 210| 211| await expect(initPayment(SLUG, 'r-1', payBody)).rejects.toMatchObj… | ^ 212| }) 213| ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[20/45]⎯ FAIL src/modules/site/site.test.ts > initPayment — payment guard paths > throws AppError when license review is required AssertionError: expected AppError: Booking access token is required { …(3) } to match object { error: 'license_review_required' } (3 matching properties omitted from actual) - Expected + Received Object { - "error": "license_review_required", + "error": "booking_token_required", } ❯ src/modules/site/site.test.ts:224:5 222| vi.mocked(validateLicense).mockReturnValue({ status: 'VALID', requ… 223| 224| await expect(initPayment(SLUG, 'r-1', payBody)).rejects.toMatchObj… | ^ 225| }) 226| ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[21/45]⎯ FAIL src/modules/site/site.test.ts > initPayment — payment guard paths > throws AppError when PayPal is not configured AssertionError: expected AppError: Booking access token is required { …(3) } to match object { error: 'provider_not_configured' } (3 matching properties omitted from actual) - Expected + Received Object { - "error": "provider_not_configured", + "error": "booking_token_required", } ❯ src/modules/site/site.test.ts:238:5 236| vi.mocked(paypalSvc.isConfigured).mockReturnValue(false) 237| 238| await expect(initPayment(SLUG, 'r-1', payBody)).rejects.toMatchObj… | ^ 239| }) 240| ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[22/45]⎯ FAIL src/modules/site/site.test.ts > initPayment — payment guard paths > returns checkoutUrl when PayPal is configured AppError: Booking access token is required ❯ assertPublicBookingAccess src/modules/site/site.service.ts:244:21 242| 243| async function assertPublicBookingAccess(reservationId: string, token:… 244| if (!token) throw new AppError('Booking access token is required', 4… | ^ 245| const access = await repo.findReservationPublicAccess(reservationId,… 246| if (!access) throw new AppError('Booking not found', 404, 'not_found… ❯ Module.initPayment src/modules/site/site.service.ts:260:9 ❯ src/modules/site/site.test.ts:254:20 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Serialized Error: { statusCode: 403, error: 'booking_token_required', data: undefined } ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[23/45]⎯ FAIL src/tests/api/admin-billing.api.test.ts > admin billing API contracts > coerces list filters and requires finance access AssertionError: expected 403 to be 200 // Object.is equality - Expected + Received - 200 + 403 ❯ src/tests/api/admin-billing.api.test.ts:56:24 54| .set('Authorization', 'Bearer admin-token') 55| 56| expect(res.status).toBe(200) | ^ 57| expect(adminService.getBilling).toHaveBeenCalledWith({ 58| q: 'atlas', ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[24/45]⎯ FAIL src/tests/api/admin-billing.api.test.ts > admin billing API contracts > rejects oversized billing pagination before service execution AssertionError: expected 403 to be 400 // Object.is equality - Expected + Received - 400 + 403 ❯ src/tests/api/admin-billing.api.test.ts:71:24 69| .set('Authorization', 'Bearer admin-token') 70| 71| expect(res.status).toBe(400) | ^ 72| expect(adminService.getBilling).not.toHaveBeenCalled() 73| }) ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[25/45]⎯ FAIL src/tests/api/admin-billing.api.test.ts > admin billing API contracts > streams invoice PDFs with content headers from the service boundary AssertionError: expected 403 to be 200 // Object.is equality - Expected + Received - 200 + 403 ❯ src/tests/api/admin-billing.api.test.ts:85:24 83| .set('Authorization', 'Bearer admin-token') 84| 85| expect(res.status).toBe(200) | ^ 86| expect(res.header['content-type']).toContain('application/pdf') 87| expect(res.header['content-disposition']).toContain('INV-2026-0000… ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[26/45]⎯ FAIL src/tests/api/admin-billing.api.test.ts > admin billing API contracts > passes parsed account updates with admin identity and request ip AssertionError: expected 403 to be 200 // Object.is equality - Expected + Received - 200 + 403 ❯ src/tests/api/admin-billing.api.test.ts:99:24 97| .send({ billingEmail: 'billing@example.test', invoiceTerms: 'NET… 98| 99| expect(res.status).toBe(200) | ^ 100| expect(adminService.updateBillingAccount).toHaveBeenCalledWith( 101| 'billing_account_1', ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[27/45]⎯ FAIL src/tests/api/admin-billing.api.test.ts > admin billing API contracts > rejects malformed draft invoice payloads before invoice creation AssertionError: expected 403 to be 400 // Object.is equality - Expected + Received - 400 + 403 ❯ src/tests/api/admin-billing.api.test.ts:114:24 112| .send({ invoiceType: 'MANUAL', lineItems: [] }) 113| 114| expect(res.status).toBe(400) | ^ 115| expect(adminService.createBillingInvoice).not.toHaveBeenCalled() 116| }) ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[28/45]⎯ FAIL src/tests/api/admin-menu-boundaries.api.test.ts > admin menu API contracts > rejects menu item creation with blank labels before service execution AssertionError: expected 403 to be 400 // Object.is equality - Expected + Received - 400 + 403 ❯ src/tests/api/admin-menu-boundaries.api.test.ts:51:24 49| .send({ label: ' ', itemType: 'INTERNAL_PAGE', routeOrUrl: '/f… 50| 51| expect(res.status).toBe(400) | ^ 52| expect(menuService.createMenuItem).not.toHaveBeenCalled() 53| }) ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[29/45]⎯ FAIL src/tests/api/admin-menu-boundaries.api.test.ts > admin menu API contracts > passes normalized menu item creation payload with admin actor AssertionError: expected 403 to be 201 // Object.is equality - Expected + Received - 201 + 403 ❯ src/tests/api/admin-menu-boundaries.api.test.ts:63:24 61| .send({ label: ' Fleet ', itemType: 'INTERNAL_PAGE', routeOrUrl:… 62| 63| expect(res.status).toBe(201) | ^ 64| expect(menuService.createMenuItem).toHaveBeenCalledWith( 65| expect.objectContaining({ label: 'Fleet', itemType: 'INTERNAL_PA… ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[30/45]⎯ FAIL src/tests/api/admin-menu-boundaries.api.test.ts > admin menu API contracts > rejects invalid menu status bodies before mutation AssertionError: expected 403 to be 400 // Object.is equality - Expected + Received - 400 + 403 ❯ src/tests/api/admin-menu-boundaries.api.test.ts:76:24 74| .send({ isActive: 'false' }) 75| 76| expect(res.status).toBe(400) | ^ 77| expect(menuService.setMenuItemStatus).not.toHaveBeenCalled() 78| }) ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[31/45]⎯ FAIL src/tests/api/admin-menu-boundaries.api.test.ts > admin menu API contracts > requires admin privileges for menu mutations while support can preview AssertionError: expected 403 to be 200 // Object.is equality - Expected + Received - 200 + 403 ❯ src/tests/api/admin-menu-boundaries.api.test.ts:94:31 92| .set('Authorization', 'Bearer admin-token') 93| .send({ companyId: 'company_1', role: 'MANAGER' }) 94| expect(previewRes.status).toBe(200) | ^ 95| expect(menuService.previewCompanyMenu).toHaveBeenCalledWith({ comp… 96| }) ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[32/45]⎯ FAIL src/tests/api/admin-menu-boundaries.api.test.ts > admin menu API contracts > coerces audit-log pagination defaults and caps oversized limits AssertionError: expected 403 to be 200 // Object.is equality - Expected + Received - 200 + 403 ❯ src/tests/api/admin-menu-boundaries.api.test.ts:104:31 102| .get('/api/v1/admin/menu-audit-logs') 103| .set('Authorization', 'Bearer admin-token') 104| expect(defaultRes.status).toBe(200) | ^ 105| expect(menuService.listMenuAuditLogs).toHaveBeenCalledWith({ page:… 106| ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[33/45]⎯ FAIL src/tests/api/auth-middleware.api.test.ts > auth middleware API boundaries > rejects employee-protected routes when a renter token is used AssertionError: expected { error: 'invalid_token', …(2) } to deeply equal { error: 'invalid_token', …(2) } - Expected + Received Object { "error": "invalid_token", - "message": "Invalid token type for this endpoint", + "message": "Invalid or expired session token", "statusCode": 401, } ❯ src/tests/api/auth-middleware.api.test.ts:72:22 70| 71| expect(res.status).toBe(401) 72| expect(res.body).toEqual({ error: 'invalid_token', message: 'Inval… | ^ 73| expect(prisma.employee.findUnique).not.toHaveBeenCalled() 74| }) ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[34/45]⎯ FAIL src/tests/api/auth-middleware.api.test.ts > auth middleware API boundaries > allows valid admin tokens through protected admin read routes AssertionError: expected 403 to be 200 // Object.is equality - Expected + Received - 200 + 403 ❯ src/tests/api/auth-middleware.api.test.ts:146:24 144| const res = await request(app).get('/api/v1/admin/companies').set(… 145| 146| expect(res.status).toBe(200) | ^ 147| expect(res.body).toEqual({ data: { data: [{ id: 'company_1' }], pa… 148| expect(adminService.listCompanies).toHaveBeenCalledWith({ page: 1,… ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[35/45]⎯ FAIL src/tests/api/payments.api.test.ts > payments API contract > accepts valid AmanPay webhooks and delegates the exact payload AssertionError: expected "spy" to be called with arguments: [ { transaction_id: 'txn_1', …(1) } ] Received: 1st spy call: Array [ Object { "status": "PAID", "transaction_id": "txn_1", }, + "{\"transaction_id\":\"txn_1\",\"status\":\"PAID\"}", ] Number of calls: 1 ❯ src/tests/api/payments.api.test.ts:68:42 66| expect(res.status).toBe(200) 67| expect(res.body).toEqual({ received: true }) 68| expect(service.handleAmanpayWebhook).toHaveBeenCalledWith(payload) | ^ 69| }) 70| ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[36/45]⎯ FAIL src/tests/api/payments.api.test.ts > payments API contract > accepts verified PayPal webhooks and delegates handling AssertionError: expected "spy" to be called with arguments: [ { …(2) } ] Received: 1st spy call: Array [ Object { "event_type": "PAYMENT.CAPTURE.COMPLETED", "resource": Object { "id": "capture_1", }, }, + "{\"event_type\":\"PAYMENT.CAPTURE.COMPLETED\",\"resource\":{\"id\":\"capture_1\"}}", ] Number of calls: 1 ❯ src/tests/api/payments.api.test.ts:96:41 94| expect(res.status).toBe(200) 95| expect(res.body).toEqual({ received: true }) 96| expect(service.handlePaypalWebhook).toHaveBeenCalledWith(payload) | ^ 97| }) 98| ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[37/45]⎯ FAIL src/tests/api/public-validation.api.test.ts > public validation API contracts > defaults site payment currency to MAD for valid public payment requests AssertionError: expected 400 to be 200 // Object.is equality - Expected + Received - 200 + 400 ❯ src/tests/api/public-validation.api.test.ts:111:24 109| }) 110| 111| expect(res.status).toBe(200) | ^ 112| expect(siteService.initPayment).toHaveBeenCalledWith('atlas-cars',… 113| provider: 'PAYPAL', ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[38/45]⎯ FAIL src/tests/api/subscriptions.api.test.ts > subscriptions public API > accepts verified PayPal webhooks and delegates handling to the subscription service AssertionError: expected "spy" to be called with arguments: [ { …(2) } ] Received: 1st spy call: Array [ Object { "event_type": "PAYMENT.CAPTURE.COMPLETED", "resource": Object { "id": "capture_1", }, }, + "{\"event_type\":\"PAYMENT.CAPTURE.COMPLETED\",\"resource\":{\"id\":\"capture_1\"}}", ] Number of calls: 1 ❯ src/tests/api/subscriptions.api.test.ts:103:41 101| expect(res.status).toBe(200) 102| expect(res.body).toEqual({ received: true }) 103| expect(service.handlePaypalWebhook).toHaveBeenCalledWith(payload) | ^ 104| }) 105| }) ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[39/45]⎯ FAIL src/tests/e2e/admin-billing-boundaries.e2e.test.ts > admin billing e2e boundaries > rejects anonymous billing access and malformed invoice creation without touching services AssertionError: expected 401 to be 400 // Object.is equality - Expected + Received - 400 + 401 ❯ src/tests/e2e/admin-billing-boundaries.e2e.test.ts:37:30 35| .send({ invoiceType: 'MADE_UP', lineItems: [{ quantity: 0, unitA… 36| 37| expect(malformed.status).toBe(400) | ^ 38| expect(adminService.createBillingInvoice).not.toHaveBeenCalled() 39| }) ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[40/45]⎯ FAIL src/tests/e2e/vehicle-pricing-boundaries.e2e.test.ts > vehicle pricing e2e boundaries > rejects anonymous and malformed pricing requests without invoking pricing services AssertionError: expected 401 to be 400 // Object.is equality - Expected + Received - 400 + 401 ❯ src/tests/e2e/vehicle-pricing-boundaries.e2e.test.ts:53:36 51| .send({ pricingMode: 'AUTOMATIC', baseDailyRate: -50 }) 52| 53| expect(malformedConfig.status).toBe(400) | ^ 54| expect(vehicleService.updateVehiclePricing).not.toHaveBeenCalled() 55| ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[41/45]⎯ Test Files 21 failed | 127 passed (148) Tests 39 failed | 601 passed (640) Start at 23:32:27 Duration 6.99s (transform 2.58s, setup 8ms, collect 30.38s, tests 3.22s, environment 16ms, prepare 10.35s) npm error Lifecycle script `test` failed with error: npm error code 1 npm error path /Volumes/ExternalApps/Documents/car_management_system/apps/api npm error workspace @rentaldrivego/api@1.0.0 npm error location /Volumes/ExternalApps/Documents/car_management_system/apps/api npm error command failed npm error command sh -c vitest run