Files
carmanagement/apps/api/src/modules/offers/offer.service.test.ts
T
2026-06-10 00:40:19 -04:00

73 lines
3.1 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from 'vitest'
vi.mock('./offer.repo', () => ({
findMany: vi.fn(),
findByIdOrThrow: vi.fn(),
create: vi.fn(),
findFirst: vi.fn(),
update: vi.fn(),
deleteMany: vi.fn(),
setActive: vi.fn(),
getStats: vi.fn(),
}))
import { NotFoundError } from '../../http/errors'
import * as repo from './offer.repo'
import { createOffer, deleteOffer, getOffer, getOfferStats, listOffers, setOfferActive, updateOffer } from './offer.service'
describe('offer.service', () => {
beforeEach(() => vi.clearAllMocks())
it('keeps listing filters tenant-scoped and delegates them unchanged to the repository', async () => {
vi.mocked(repo.findMany).mockResolvedValue([{ id: 'offer_1' }] as never)
const result = await listOffers('company_1', { active: 'true', public: 'false' })
expect(repo.findMany).toHaveBeenCalledWith('company_1', { active: 'true', public: 'false' })
expect(result).toEqual([{ id: 'offer_1' }])
})
it('creates offers with separate offer data and vehicle assignment ids', async () => {
vi.mocked(repo.create).mockResolvedValue({ id: 'offer_1' } as never)
const payload = { title: 'Weekend deal', type: 'PERCENTAGE', discountValue: 15 }
await createOffer('company_1', payload, ['vehicle_1', 'vehicle_2'])
expect(repo.create).toHaveBeenCalledWith('company_1', payload, ['vehicle_1', 'vehicle_2'])
})
it('throws NotFoundError before updating an offer outside the tenant boundary', async () => {
vi.mocked(repo.findFirst).mockResolvedValue(null as never)
await expect(updateOffer('offer_1', 'company_1', { title: 'Nope' })).rejects.toBeInstanceOf(NotFoundError)
expect(repo.update).not.toHaveBeenCalled()
})
it('updates an existing offer and preserves explicit vehicle assignment updates', async () => {
vi.mocked(repo.findFirst).mockResolvedValue({ id: 'offer_1' } as never)
vi.mocked(repo.update).mockResolvedValue({ id: 'offer_1', title: 'Summer' } as never)
const result = await updateOffer('offer_1', 'company_1', { title: 'Summer' }, [])
expect(repo.update).toHaveBeenCalledWith('offer_1', { title: 'Summer' }, [])
expect(result).toEqual({ id: 'offer_1', title: 'Summer' })
})
it('activates, deactivates, deletes, and reads stats through tenant-scoped repository methods', async () => {
vi.mocked(repo.setActive).mockResolvedValue({ id: 'offer_1', isActive: true } as never)
vi.mocked(repo.deleteMany).mockResolvedValue({ count: 1 } as never)
vi.mocked(repo.getStats).mockResolvedValue({ redemptions: 3 } as never)
vi.mocked(repo.findByIdOrThrow).mockResolvedValue({ id: 'offer_1' } as never)
await getOffer('offer_1', 'company_1')
await setOfferActive('offer_1', 'company_1', true)
await deleteOffer('offer_1', 'company_1')
await getOfferStats('offer_1', 'company_1')
expect(repo.findByIdOrThrow).toHaveBeenCalledWith('offer_1', 'company_1')
expect(repo.setActive).toHaveBeenCalledWith('offer_1', 'company_1', true)
expect(repo.deleteMany).toHaveBeenCalledWith('offer_1', 'company_1')
expect(repo.getStats).toHaveBeenCalledWith('offer_1', 'company_1')
})
})