test(auth,payments,subs): add 58 unit tests for critical auth, payment, and subscription paths

Cover auth handlers (RegisterUser, LoginUser, RefreshToken), TokenService
(token rotation, reuse attack detection), payment callback edge cases
(duplicate/concurrent callbacks, multi-provider), subscription lifecycle
transitions (expire, pastDue, renew), and throttler proxy guard.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Ho Ngoc Hai
2026-04-08 13:49:19 +07:00
parent a590a41e73
commit bac3313873
13 changed files with 1031 additions and 0 deletions

View File

@@ -0,0 +1,167 @@
import { SubscriptionEntity } from '../entities/subscription.entity';
describe('SubscriptionEntity — lifecycle edge cases', () => {
const makeSub = (status?: 'ACTIVE' | 'PAST_DUE' | 'CANCELLED' | 'EXPIRED') => {
const sub = SubscriptionEntity.createNew(
'sub-1',
'user-1',
'plan-1',
'AGENT_PRO',
new Date('2026-01-01'),
new Date('2026-02-01'),
);
sub.clearDomainEvents();
if (status === 'PAST_DUE') sub.markPastDue();
if (status === 'CANCELLED') sub.cancel();
if (status === 'EXPIRED') sub.markExpired();
return sub;
};
describe('markExpired', () => {
it('transitions ACTIVE to EXPIRED', () => {
const sub = makeSub('ACTIVE');
sub.markExpired();
expect(sub.status).toBe('EXPIRED');
});
it('transitions PAST_DUE to EXPIRED', () => {
const sub = makeSub('PAST_DUE');
sub.markExpired();
expect(sub.status).toBe('EXPIRED');
});
it('throws when marking CANCELLED as expired', () => {
const sub = makeSub('CANCELLED');
expect(() => sub.markExpired()).toThrow('Không thể đánh dấu hết hạn');
});
it('throws when already expired', () => {
const sub = makeSub('EXPIRED');
expect(() => sub.markExpired()).toThrow('Không thể đánh dấu hết hạn');
});
});
describe('markPastDue', () => {
it('transitions ACTIVE to PAST_DUE', () => {
const sub = makeSub('ACTIVE');
sub.markPastDue();
expect(sub.status).toBe('PAST_DUE');
});
it('throws when marking PAST_DUE as past due again', () => {
const sub = makeSub('PAST_DUE');
expect(() => sub.markPastDue()).toThrow('Không thể đánh dấu quá hạn');
});
it('throws when marking CANCELLED as past due', () => {
const sub = makeSub('CANCELLED');
expect(() => sub.markPastDue()).toThrow('Không thể đánh dấu quá hạn');
});
it('throws when marking EXPIRED as past due', () => {
const sub = makeSub('EXPIRED');
expect(() => sub.markPastDue()).toThrow('Không thể đánh dấu quá hạn');
});
});
describe('renewPeriod', () => {
it('renews from PAST_DUE back to ACTIVE with new dates', () => {
const sub = makeSub('PAST_DUE');
const newStart = new Date('2026-02-01');
const newEnd = new Date('2026-03-01');
sub.renewPeriod(newStart, newEnd);
expect(sub.status).toBe('ACTIVE');
expect(sub.currentPeriodStart).toEqual(newStart);
expect(sub.currentPeriodEnd).toEqual(newEnd);
});
it('renews from ACTIVE (extending period)', () => {
const sub = makeSub('ACTIVE');
const newStart = new Date('2026-03-01');
const newEnd = new Date('2026-04-01');
sub.renewPeriod(newStart, newEnd);
expect(sub.status).toBe('ACTIVE');
expect(sub.currentPeriodStart).toEqual(newStart);
expect(sub.currentPeriodEnd).toEqual(newEnd);
});
it('renews from EXPIRED back to ACTIVE', () => {
const sub = makeSub('EXPIRED');
const newStart = new Date('2026-04-01');
const newEnd = new Date('2026-05-01');
sub.renewPeriod(newStart, newEnd);
expect(sub.status).toBe('ACTIVE');
});
it('renews from CANCELLED back to ACTIVE', () => {
const sub = makeSub('CANCELLED');
const newStart = new Date('2026-04-01');
const newEnd = new Date('2026-05-01');
sub.renewPeriod(newStart, newEnd);
expect(sub.status).toBe('ACTIVE');
});
});
describe('isExpired', () => {
it('returns true when period end is in the past', () => {
const sub = SubscriptionEntity.createNew(
'sub-2',
'user-1',
'plan-1',
'FREE',
new Date('2020-01-01'),
new Date('2020-02-01'),
);
expect(sub.isExpired()).toBe(true);
});
it('returns false when period end is in the future', () => {
const sub = SubscriptionEntity.createNew(
'sub-3',
'user-1',
'plan-1',
'FREE',
new Date('2030-01-01'),
new Date('2030-02-01'),
);
expect(sub.isExpired()).toBe(false);
});
});
describe('upgrade constraints', () => {
it('throws when upgrading from PAST_DUE', () => {
const sub = makeSub('PAST_DUE');
expect(() => sub.upgrade('plan-2', 'ENTERPRISE')).toThrow();
});
it('throws when upgrading from EXPIRED', () => {
const sub = makeSub('EXPIRED');
expect(() => sub.upgrade('plan-2', 'ENTERPRISE')).toThrow();
});
});
describe('cancel constraints', () => {
it('cancels from PAST_DUE', () => {
const sub = makeSub('PAST_DUE');
sub.cancel();
expect(sub.status).toBe('CANCELLED');
expect(sub.cancelledAt).not.toBeNull();
});
it('cancels from ACTIVE', () => {
const sub = makeSub('ACTIVE');
sub.cancel();
expect(sub.status).toBe('CANCELLED');
});
});
});