97 lines
3.5 KiB
TypeScript
97 lines
3.5 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
vi.mock('../../lib/prisma', () => ({
|
|
prisma: {
|
|
vehicle: {
|
|
findMany: vi.fn(),
|
|
count: vi.fn(),
|
|
findFirst: vi.fn(),
|
|
create: vi.fn(),
|
|
update: vi.fn(),
|
|
updateMany: vi.fn(),
|
|
},
|
|
reservation: { findMany: vi.fn() },
|
|
vehicleCalendarBlock: { findMany: vi.fn(), create: vi.fn(), deleteMany: vi.fn() },
|
|
maintenanceLog: { findMany: vi.fn(), create: vi.fn() },
|
|
vehiclePricingConfiguration: { findUnique: vi.fn(), create: vi.fn(), update: vi.fn() },
|
|
vehiclePricingRule: { findFirst: vi.fn(), create: vi.fn(), update: vi.fn(), deleteMany: vi.fn() },
|
|
vehiclePriceHistory: { create: vi.fn() },
|
|
},
|
|
}))
|
|
|
|
import { prisma } from '../../lib/prisma'
|
|
import * as repo from './vehicle.repo'
|
|
|
|
describe('vehicle.repo edge queries', () => {
|
|
beforeEach(() => vi.clearAllMocks())
|
|
|
|
it('soft deletes by taking the vehicle out of service and unpublishing it inside the tenant boundary', async () => {
|
|
await repo.softDelete('vehicle_1', 'company_1')
|
|
|
|
expect(prisma.vehicle.updateMany).toHaveBeenCalledWith({
|
|
where: { id: 'vehicle_1', companyId: 'company_1' },
|
|
data: { status: 'OUT_OF_SERVICE', isPublished: false },
|
|
})
|
|
})
|
|
|
|
it('publishes and unpublishes inside the tenant boundary', async () => {
|
|
await repo.setPublished('vehicle_1', 'company_1', true)
|
|
expect(prisma.vehicle.updateMany).toHaveBeenCalledWith({
|
|
where: { id: 'vehicle_1', companyId: 'company_1' },
|
|
data: { isPublished: true },
|
|
})
|
|
})
|
|
|
|
it('finds reservation conflicts by overlap and active statuses only', async () => {
|
|
const start = new Date('2026-09-01T00:00:00.000Z')
|
|
const end = new Date('2026-09-07T00:00:00.000Z')
|
|
|
|
await repo.findReservationConflicts('vehicle_1', 'company_1', start, end)
|
|
|
|
expect(prisma.reservation.findMany).toHaveBeenCalledWith({
|
|
where: {
|
|
vehicleId: 'vehicle_1',
|
|
companyId: 'company_1',
|
|
status: { in: ['CONFIRMED', 'ACTIVE'] },
|
|
startDate: { lt: end },
|
|
endDate: { gt: start },
|
|
},
|
|
select: { id: true, startDate: true, endDate: true, status: true },
|
|
})
|
|
})
|
|
|
|
it('loads calendar reservations and blocks in chronological order for the requested range', async () => {
|
|
const rangeStart = new Date('2026-10-01T00:00:00.000Z')
|
|
const rangeEnd = new Date('2026-10-31T23:59:59.000Z')
|
|
|
|
await repo.findCalendarEvents('vehicle_1', 'company_1', rangeStart, rangeEnd)
|
|
|
|
expect(prisma.reservation.findMany).toHaveBeenCalledWith(expect.objectContaining({
|
|
where: expect.objectContaining({
|
|
vehicleId: 'vehicle_1',
|
|
companyId: 'company_1',
|
|
status: { in: ['DRAFT', 'CONFIRMED', 'ACTIVE'] },
|
|
startDate: { lt: rangeEnd },
|
|
endDate: { gt: rangeStart },
|
|
}),
|
|
orderBy: { startDate: 'asc' },
|
|
}))
|
|
expect(prisma.vehicleCalendarBlock.findMany).toHaveBeenCalledWith({
|
|
where: { vehicleId: 'vehicle_1', startDate: { lt: rangeEnd }, endDate: { gt: rangeStart } },
|
|
orderBy: { startDate: 'asc' },
|
|
})
|
|
})
|
|
|
|
it('loads pricing configuration with deterministic rule and history ordering', async () => {
|
|
await repo.findPricingConfiguration('vehicle_1')
|
|
|
|
expect(prisma.vehiclePricingConfiguration.findUnique).toHaveBeenCalledWith({
|
|
where: { vehicleId: 'vehicle_1' },
|
|
include: {
|
|
rules: { orderBy: [{ sortOrder: 'asc' }, { startDate: 'asc' }, { createdAt: 'asc' }] },
|
|
history: { orderBy: { createdAt: 'desc' }, take: 20 },
|
|
},
|
|
})
|
|
})
|
|
})
|