Files
carmanagement/apps/api/src/tests/integration/operations.test.ts
T
2026-06-10 00:40:19 -04:00

120 lines
4.4 KiB
TypeScript

import request from 'supertest'
import { createApp } from '../../app'
import { prisma } from '../../lib/prisma'
import {
authHeader,
createCompanyNotification,
createCompanyWithEmployee,
createRenter,
createRenterNotification,
createVehicle,
signEmployeeToken,
signRenterToken,
} from '../helpers/fixtures'
const app = createApp()
describe('Operations API integration', () => {
let companyId: string
let employeeId: string
let token: string
beforeAll(async () => {
const { company, employee } = await createCompanyWithEmployee({ role: 'OWNER' })
companyId = company.id
employeeId = employee.id
token = signEmployeeToken(employee.id, company.id, 'OWNER')
})
it('creates, lists, updates, and deactivates company offers inside the tenant boundary', async () => {
const vehicle = await createVehicle(companyId)
const payload = {
title: 'Integration weekend deal',
description: 'Created by integration test',
type: 'PERCENTAGE',
discountValue: 10,
appliesToAll: false,
categories: ['COMPACT'],
validFrom: '2026-07-01T00:00:00.000Z',
validUntil: '2026-08-01T00:00:00.000Z',
isActive: true,
isPublic: true,
vehicleIds: [vehicle.id],
}
const created = await request(app)
.post('/api/v1/offers')
.set(authHeader(token))
.send(payload)
expect(created.status).toBe(201)
expect(created.body.data.title).toBe(payload.title)
const offerId = created.body.data.id
const listed = await request(app).get('/api/v1/offers?active=true').set(authHeader(token))
expect(listed.status).toBe(200)
expect(listed.body.data.some((offer: any) => offer.id === offerId)).toBe(true)
const updated = await request(app)
.patch(`/api/v1/offers/${offerId}`)
.set(authHeader(token))
.send({ title: 'Updated integration weekend deal' })
expect(updated.status).toBe(200)
expect(updated.body.data.title).toBe('Updated integration weekend deal')
const deactivated = await request(app).post(`/api/v1/offers/${offerId}/deactivate`).set(authHeader(token))
expect(deactivated.status).toBe(200)
expect(deactivated.body.data).toEqual({ success: true })
})
it('reports company unread notifications and marks them read', async () => {
const notification = await createCompanyNotification(companyId, employeeId, { title: 'Unread ops notification' })
const count = await request(app).get('/api/v1/notifications/unread-count').set(authHeader(token))
expect(count.status).toBe(200)
expect(count.body.data.unread).toBeGreaterThanOrEqual(1)
const marked = await request(app).post(`/api/v1/notifications/company/${notification.id}/read`).set(authHeader(token))
expect(marked.status).toBe(200)
expect(marked.body.data).toEqual({ success: true })
const stored = await prisma.notification.findUniqueOrThrow({ where: { id: notification.id } })
expect(stored.readAt).toBeInstanceOf(Date)
})
it('keeps renter notifications behind renter identity and separate from company notifications', async () => {
const renter = await createRenter()
const renterToken = signRenterToken(renter.id)
const notification = await createRenterNotification(renter.id, { title: 'Renter-only notification' })
const listed = await request(app).get('/api/v1/notifications/renter').set(authHeader(renterToken))
expect(listed.status).toBe(200)
expect(listed.body.data.some((item: any) => item.id === notification.id)).toBe(true)
const marked = await request(app).post(`/api/v1/notifications/renter/${notification.id}/read`).set(authHeader(renterToken))
expect(marked.status).toBe(200)
expect(marked.body.data).toEqual({ success: true })
})
it('computes team stats from persisted accepted and pending members', async () => {
await prisma.employee.create({
data: {
companyId,
clerkUserId: `pending-${Date.now()}`,
firstName: 'Pending',
lastName: 'Member',
email: `pending-${Date.now()}@example.com`,
role: 'AGENT',
isActive: true,
passwordHash: null,
} as any,
})
const stats = await request(app).get('/api/v1/team/stats').set(authHeader(token))
expect(stats.status).toBe(200)
expect(stats.body.data.total).toBeGreaterThanOrEqual(2)
expect(stats.body.data.active).toBeGreaterThanOrEqual(1)
expect(stats.body.data.pending).toBeGreaterThanOrEqual(1)
})
})