Files
carmanagement/apps/api/src/tests/helpers/fixtures.ts
T
2026-05-24 23:58:54 -04:00

245 lines
6.2 KiB
TypeScript

import bcrypt from 'bcryptjs'
import jwt from 'jsonwebtoken'
import { prisma } from '../../lib/prisma'
const JWT_SECRET = process.env.JWT_SECRET ?? 'test-secret'
let counter = 0
function uid() {
return `${Date.now()}-${++counter}-${Math.random().toString(36).slice(2, 7)}`
}
export async function createCompanyWithEmployee(overrides: {
role?: 'OWNER' | 'MANAGER' | 'AGENT'
companyStatus?: 'ACTIVE' | 'TRIALING' | 'PAST_DUE' | 'SUSPENDED' | 'PENDING'
} = {}) {
const slug = `test-${uid()}`
const company = await prisma.company.create({
data: {
name: `Test Company ${slug}`,
slug,
email: `company-${slug}@test.com`,
status: (overrides.companyStatus ?? 'ACTIVE') as any,
subscription: {
create: { status: 'TRIALING', plan: 'STARTER' },
},
},
})
const employee = await prisma.employee.create({
data: {
companyId: company.id,
clerkUserId: `clerk_${uid()}`,
firstName: 'Test',
lastName: 'User',
email: `employee-${uid()}@test.com`,
role: overrides.role ?? 'OWNER',
},
})
return { company, employee }
}
export async function createVehicle(companyId: string, overrides: Record<string, unknown> = {}) {
return prisma.vehicle.create({
data: {
companyId,
make: 'Toyota',
model: 'Corolla',
year: 2022,
color: 'White',
licensePlate: `PL-${uid()}`,
dailyRate: 500,
status: 'AVAILABLE',
isPublished: true,
pickupLocations: ['Casablanca'],
allowDifferentDropoff: false,
dropoffLocations: [],
...overrides,
} as any,
})
}
export async function createCustomer(companyId: string, overrides: Record<string, unknown> = {}) {
return prisma.customer.create({
data: {
companyId,
firstName: 'Jane',
lastName: 'Doe',
email: `customer-${uid()}@test.com`,
...overrides,
},
})
}
export async function createRenter(overrides: {
firstName?: string
lastName?: string
email?: string
password?: string
isActive?: boolean
} = {}) {
return prisma.renter.create({
data: {
firstName: overrides.firstName ?? 'Renter',
lastName: overrides.lastName ?? 'User',
email: overrides.email ?? `renter-${uid()}@test.com`,
passwordHash: await bcrypt.hash(overrides.password ?? 'RenterPass123!', 10),
isActive: overrides.isActive ?? true,
},
})
}
export async function createAdminUser(overrides: {
email?: string
firstName?: string
lastName?: string
password?: string
role?: 'SUPER_ADMIN' | 'ADMIN' | 'SUPPORT' | 'FINANCE' | 'VIEWER'
isActive?: boolean
totpEnabled?: boolean
totpSecret?: string | null
} = {}) {
return prisma.adminUser.create({
data: {
email: overrides.email ?? `admin-${uid()}@test.com`,
firstName: overrides.firstName ?? 'Admin',
lastName: overrides.lastName ?? 'User',
passwordHash: await bcrypt.hash(overrides.password ?? 'AdminPass123!', 10),
role: (overrides.role ?? 'ADMIN') as any,
isActive: overrides.isActive ?? true,
totpEnabled: overrides.totpEnabled ?? false,
totpSecret: overrides.totpSecret ?? null,
},
})
}
export async function createReservation(
companyId: string,
vehicleId: string,
customerId: string,
overrides: Record<string, unknown> = {},
) {
return prisma.reservation.create({
data: {
companyId,
vehicleId,
customerId,
startDate: new Date(Date.now() + 24 * 60 * 60 * 1000),
endDate: new Date(Date.now() + 4 * 24 * 60 * 60 * 1000),
dailyRate: 500,
totalDays: 3,
totalAmount: 1500,
depositAmount: 300,
status: 'CONFIRMED',
paymentStatus: 'UNPAID',
paidAmount: 0,
...overrides,
} as any,
})
}
export async function createRentalPayment(
companyId: string,
reservationId: string,
overrides: Record<string, unknown> = {},
) {
return prisma.rentalPayment.create({
data: {
companyId,
reservationId,
amount: 500,
currency: 'MAD',
status: 'SUCCEEDED',
type: 'CHARGE',
paymentProvider: 'AMANPAY',
amanpayTransactionId: `aman-${uid()}`,
paidAt: new Date(),
...overrides,
} as any,
})
}
export async function createSubscriptionInvoice(
companyId: string,
subscriptionId: string,
overrides: Record<string, unknown> = {},
) {
return prisma.subscriptionInvoice.create({
data: {
companyId,
subscriptionId,
amount: 29900,
currency: 'MAD',
status: 'PENDING',
paymentProvider: 'AMANPAY',
amanpayTransactionId: `sub-${uid()}`,
...overrides,
} as any,
})
}
export async function createCompanyNotification(
companyId: string,
employeeId?: string,
overrides: Record<string, unknown> = {},
) {
return prisma.notification.create({
data: {
companyId,
employeeId,
type: 'PAYMENT_RECEIVED',
title: 'Payment received',
body: 'A payment was recorded.',
channel: 'IN_APP',
status: 'PENDING',
...overrides,
} as any,
})
}
export async function createRenterNotification(
renterId: string,
overrides: Record<string, unknown> = {},
) {
return prisma.notification.create({
data: {
renterId,
type: 'BOOKING_CONFIRMED',
title: 'Booking confirmed',
body: 'Your booking is confirmed.',
channel: 'IN_APP',
status: 'PENDING',
...overrides,
} as any,
})
}
export function signEmployeeToken(employeeId: string, companyId: string, role: string = 'OWNER') {
return jwt.sign(
{ sub: employeeId, companyId, role, type: 'employee' },
JWT_SECRET,
{ expiresIn: '1h' },
)
}
export function signAdminToken(adminId: string) {
return jwt.sign(
{ sub: adminId, type: 'admin' },
JWT_SECRET,
{ expiresIn: '1h' },
)
}
export function signRenterToken(renterId: string) {
return jwt.sign(
{ sub: renterId, type: 'renter' },
JWT_SECRET,
{ expiresIn: '1h' },
)
}
export function authHeader(token: string) {
return { Authorization: `Bearer ${token}` }
}