199 lines
6.3 KiB
TypeScript
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)
|
|
})
|
|
})
|
|
})
|