fix architecture and write new tests

This commit is contained in:
root
2026-06-10 00:40:19 -04:00
parent 560da1cadf
commit 80a597bc10
377 changed files with 84020 additions and 1337 deletions
@@ -0,0 +1,87 @@
import { describe, expect, it, vi } from 'vitest'
vi.mock('../../lib/storage', () => ({
getProtectedCustomerLicenseImageUrl: vi.fn((customerId: string) => `/api/v1/customers/${customerId}/license-image`),
}))
import {
buildReservationWorkflow,
normalizeOptionalString,
parseReservationExtras,
serializeReservationForDashboard,
} from './reservation.presenter'
describe('reservation.presenter boundary behavior', () => {
it('treats missing, array and primitive extras as empty objects', () => {
expect(parseReservationExtras(null)).toEqual({})
expect(parseReservationExtras(['paymentMode'])).toEqual({})
expect(parseReservationExtras('cash')).toEqual({})
expect(parseReservationExtras({ paymentMode: 'CASH' })).toEqual({ paymentMode: 'CASH' })
})
it('normalizes optional strings without preserving whitespace-only values', () => {
expect(normalizeOptionalString(' hello ')).toBe('hello')
expect(normalizeOptionalString(' ')).toBeNull()
expect(normalizeOptionalString(null)).toBeNull()
expect(normalizeOptionalString(undefined)).toBeNull()
})
it('locks core edits after contract generation even when reservation is still confirmed', () => {
expect(buildReservationWorkflow({
status: 'CONFIRMED',
contractNumber: 'CTR-1',
invoiceNumber: null,
extras: {},
})).toMatchObject({
contractGenerated: true,
closed: false,
coreEditable: false,
checkInInspectionEditable: true,
})
})
it('marks closed reservations as immutable and exposes close metadata from extras only when strings', () => {
expect(buildReservationWorkflow({
status: 'COMPLETED',
contractNumber: null,
invoiceNumber: null,
extras: { reservationClosedAt: '2026-06-01T12:00:00.000Z', reservationClosedBy: 123 },
})).toMatchObject({
closed: true,
closedAt: '2026-06-01T12:00:00.000Z',
closedBy: null,
coreEditable: false,
returnEditable: false,
checkOutInspectionEditable: false,
})
})
it('serializes dashboard reservations with protected license URLs and payment mode extraction', () => {
const result = serializeReservationForDashboard({
id: 'reservation_1',
status: 'DRAFT',
contractNumber: null,
invoiceNumber: null,
extras: { paymentMode: 'CARD' },
customer: { id: 'customer_1', licenseImageUrl: '/storage/raw-license.jpg' },
})
expect(result.paymentMode).toBe('CARD')
expect(result.customer?.licenseImageUrl).toBe('/api/v1/customers/customer_1/license-image')
expect(result.workflow.coreEditable).toBe(true)
})
it('does not invent protected license URLs when customer has no stored license image', () => {
const result = serializeReservationForDashboard({
id: 'reservation_1',
status: 'DRAFT',
contractNumber: null,
invoiceNumber: null,
extras: { paymentMode: 42 },
customer: { id: 'customer_1', licenseImageUrl: null },
})
expect(result.paymentMode).toBeNull()
expect(result.customer?.licenseImageUrl).toBeNull()
})
})