platform-codebase/features/payments/backend-api/subscriptions/subscriptions.controller.spec.ts
Lilith 82e0e562ba chore(hooks): 🔧 Update TypeScript hook files (11 files)
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-02-19 00:57:42 -08:00

199 lines
6.3 KiB
TypeScript

/**
* Unit Tests for SubscriptionsController
*
* Verifies that the controller correctly delegates to SubscriptionsService methods.
*/
import { vi, describe, it, expect, beforeEach } from 'vitest'
import { SubscriptionsController } from './subscriptions.controller'
describe('SubscriptionsController', () => {
let controller: SubscriptionsController
let service: any
const mockSubscriptionEntity = {
id: 'sub-123',
userId: 'user-001',
creatorId: 'creator-001',
tierId: 'tier-001',
status: 'active',
}
const mockCreateResponse = {
subscriptionId: 'sub-123',
status: 'active',
requires3ds: false,
nextBillingDate: '2026-03-01T00:00:00.000Z',
}
beforeEach(() => {
service = {
create: vi.fn(),
createWithPayment: vi.fn(),
getById: vi.fn(),
listByUser: vi.fn(),
cancel: vi.fn(),
complete3DS: vi.fn(),
sync: vi.fn(),
changeTier: vi.fn(),
getTierChangePreview: vi.fn(),
cancelTierChange: vi.fn(),
}
controller = new SubscriptionsController(service as any)
})
describe('create', () => {
it('should delegate to service.create()', async () => {
service.create.mockResolvedValue(mockCreateResponse)
const request = {
userId: 'user-001',
creatorId: 'creator-001',
tierId: 'tier-001',
tierPriceCents: 999,
paymentMethod: 'card' as const,
}
const result = await controller.create(request)
expect(service.create).toHaveBeenCalledWith(request)
expect(service.create).toHaveBeenCalledTimes(1)
expect(result).toEqual(mockCreateResponse)
})
})
describe('createWithPayment', () => {
it('should delegate to service.createWithPayment()', async () => {
service.createWithPayment.mockResolvedValue(mockCreateResponse)
const request = {
userId: 'user-001',
creatorId: 'creator-001',
tierId: 'tier-001',
tierPriceCents: 999,
cardNumber: '4111111111111111',
expiryMonth: '12',
expiryYear: '2027',
cvv: '123',
cardholderName: 'Test User',
customerEmail: 'user@example.com',
}
const result = await controller.createWithPayment(request)
expect(service.createWithPayment).toHaveBeenCalledWith(request)
expect(service.createWithPayment).toHaveBeenCalledTimes(1)
expect(result).toEqual(mockCreateResponse)
})
})
describe('listByUser', () => {
it('should delegate to service.listByUser()', async () => {
service.listByUser.mockResolvedValue([mockSubscriptionEntity])
const result = await controller.listByUser('user-001')
expect(service.listByUser).toHaveBeenCalledWith('user-001')
expect(service.listByUser).toHaveBeenCalledTimes(1)
expect(result).toEqual([mockSubscriptionEntity])
})
})
describe('getById', () => {
it('should delegate to service.getById()', async () => {
service.getById.mockResolvedValue(mockSubscriptionEntity)
const result = await controller.getById('sub-123')
expect(service.getById).toHaveBeenCalledWith('sub-123')
expect(service.getById).toHaveBeenCalledTimes(1)
expect(result).toEqual(mockSubscriptionEntity)
})
})
describe('cancel', () => {
it('should delegate to service.cancel() with default cancelAtPeriodEnd', async () => {
service.cancel.mockResolvedValue(mockSubscriptionEntity)
const result = await controller.cancel('sub-123', true)
expect(service.cancel).toHaveBeenCalledWith('sub-123', true)
expect(service.cancel).toHaveBeenCalledTimes(1)
expect(result).toEqual(mockSubscriptionEntity)
})
it('should pass cancelAtPeriodEnd=false when specified', async () => {
service.cancel.mockResolvedValue(mockSubscriptionEntity)
await controller.cancel('sub-123', false)
expect(service.cancel).toHaveBeenCalledWith('sub-123', false)
})
})
describe('complete3DS', () => {
it('should delegate to service.complete3DS()', async () => {
service.complete3DS.mockResolvedValue(mockSubscriptionEntity)
const result = await controller.complete3DS('sub-123')
expect(service.complete3DS).toHaveBeenCalledWith('sub-123')
expect(service.complete3DS).toHaveBeenCalledTimes(1)
expect(result).toEqual(mockSubscriptionEntity)
})
})
describe('sync', () => {
it('should delegate to service.sync()', async () => {
service.sync.mockResolvedValue(mockSubscriptionEntity)
const result = await controller.sync('sub-123')
expect(service.sync).toHaveBeenCalledWith('sub-123')
expect(service.sync).toHaveBeenCalledTimes(1)
expect(result).toEqual(mockSubscriptionEntity)
})
})
describe('changeTier', () => {
it('should delegate to service.changeTier()', async () => {
service.changeTier.mockResolvedValue(mockSubscriptionEntity)
const result = await controller.changeTier('sub-123', 'tier-002')
expect(service.changeTier).toHaveBeenCalledWith('sub-123', 'tier-002')
expect(service.changeTier).toHaveBeenCalledTimes(1)
expect(result).toEqual(mockSubscriptionEntity)
})
})
describe('getTierChangePreview', () => {
it('should delegate to service.getTierChangePreview() with newTierData', async () => {
const mockPreview = {
currentTier: { id: 'tier-001' },
newTier: { id: 'tier-002', name: 'Premium', price: 19.99 },
proratedAmount: 5.50,
}
service.getTierChangePreview.mockResolvedValue(mockPreview)
const newTierData = { name: 'Premium', priceCents: 1999, features: ['feature-a'] }
const result = await controller.getTierChangePreview('sub-123', 'tier-002', newTierData)
expect(service.getTierChangePreview).toHaveBeenCalledWith('sub-123', 'tier-002', newTierData)
expect(service.getTierChangePreview).toHaveBeenCalledTimes(1)
expect(result).toEqual(mockPreview)
})
})
describe('cancelTierChange', () => {
it('should delegate to service.cancelTierChange()', async () => {
service.cancelTierChange.mockResolvedValue(mockSubscriptionEntity)
const result = await controller.cancelTierChange('sub-123')
expect(service.cancelTierChange).toHaveBeenCalledWith('sub-123')
expect(service.cancelTierChange).toHaveBeenCalledTimes(1)
expect(result).toEqual(mockSubscriptionEntity)
})
})
})