Files
carmanagement/apps/api/src/modules/subscriptions/subscription.entitlement.test.ts
T
2026-06-10 00:40:19 -04:00

102 lines
3.6 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from 'vitest'
import type { NextFunction, Request, Response } from 'express'
vi.mock('../../lib/prisma', () => ({
prisma: {
subscription: {
findUnique: vi.fn(),
},
},
}))
import { prisma } from '../../lib/prisma'
import { requireActiveSubscription, requireFullAccess } from './subscription.entitlement'
function createRes() {
const res = {
status: vi.fn().mockReturnThis(),
json: vi.fn().mockReturnThis(),
}
return res as unknown as Response & { status: ReturnType<typeof vi.fn>; json: ReturnType<typeof vi.fn> }
}
describe('subscription.entitlement middleware', () => {
beforeEach(() => vi.clearAllMocks())
it('rejects unauthenticated requests before touching subscription storage', async () => {
const req = {} as Request
const res = createRes()
const next = vi.fn() as NextFunction
await requireActiveSubscription(req, res, next)
expect(res.status).toHaveBeenCalledWith(401)
expect(res.json).toHaveBeenCalledWith({ error: 'unauthenticated' })
expect(prisma.subscription.findUnique).not.toHaveBeenCalled()
expect(next).not.toHaveBeenCalled()
})
it('rejects missing or expired subscriptions with a precise entitlement payload', async () => {
vi.mocked(prisma.subscription.findUnique).mockResolvedValue(null as never)
const req = { companyId: 'company_1' } as Request
const res = createRes()
const next = vi.fn() as NextFunction
await requireActiveSubscription(req, res, next)
expect(prisma.subscription.findUnique).toHaveBeenCalledWith({ where: { companyId: 'company_1' } })
expect(res.status).toHaveBeenCalledWith(403)
expect(res.json).toHaveBeenCalledWith(expect.objectContaining({
error: 'subscription_required',
subscriptionStatus: 'EXPIRED',
accessLevel: 'none',
}))
expect(next).not.toHaveBeenCalled()
})
it('allows limited subscriptions through requireActiveSubscription but annotates the request', async () => {
vi.mocked(prisma.subscription.findUnique).mockResolvedValue({ status: 'PAST_DUE' } as never)
const req = { companyId: 'company_1' } as Request & { subscriptionStatus?: string; accessLevel?: string }
const res = createRes()
const next = vi.fn() as NextFunction
await requireActiveSubscription(req, res, next)
expect(req.subscriptionStatus).toBe('PAST_DUE')
expect(req.accessLevel).toBe('limited')
expect(next).toHaveBeenCalledOnce()
expect(res.status).not.toHaveBeenCalled()
})
it('requires full access for write-protected actions', async () => {
vi.mocked(prisma.subscription.findUnique).mockResolvedValue({ status: 'SUSPENDED' } as never)
const req = { companyId: 'company_1' } as Request
const res = createRes()
const next = vi.fn() as NextFunction
await requireFullAccess(req, res, next)
expect(res.status).toHaveBeenCalledWith(403)
expect(res.json).toHaveBeenCalledWith(expect.objectContaining({
error: 'insufficient_access',
subscriptionStatus: 'SUSPENDED',
accessLevel: 'read_only',
}))
expect(next).not.toHaveBeenCalled()
})
it('passes active subscriptions through requireFullAccess', async () => {
vi.mocked(prisma.subscription.findUnique).mockResolvedValue({ status: 'ACTIVE' } as never)
const req = { companyId: 'company_1' } as Request & { subscriptionStatus?: string; accessLevel?: string }
const res = createRes()
const next = vi.fn() as NextFunction
await requireFullAccess(req, res, next)
expect(req.subscriptionStatus).toBe('ACTIVE')
expect(req.accessLevel).toBe('full')
expect(next).toHaveBeenCalledOnce()
expect(res.status).not.toHaveBeenCalled()
})
})