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,41 @@
import { ThrottlerBehindProxyGuard } from '../guards/throttler-behind-proxy.guard';
describe('ThrottlerBehindProxyGuard', () => {
let guard: ThrottlerBehindProxyGuard;
beforeEach(() => {
// Create instance without DI — we only test the overridden getTracker method
guard = Object.create(ThrottlerBehindProxyGuard.prototype);
});
it('extracts first IP from X-Forwarded-For header', async () => {
const req = { headers: { 'x-forwarded-for': '203.0.113.1, 70.41.3.18, 150.172.238.178' }, ip: '127.0.0.1' };
// Access the protected method via bracket notation
const ip = await (guard as any).getTracker(req);
expect(ip).toBe('203.0.113.1');
});
it('trims whitespace from forwarded IP', async () => {
const req = { headers: { 'x-forwarded-for': ' 10.0.0.1 , 192.168.1.1' }, ip: '127.0.0.1' };
const ip = await (guard as any).getTracker(req);
expect(ip).toBe('10.0.0.1');
});
it('falls back to req.ip when no X-Forwarded-For header', async () => {
const req = { headers: {}, ip: '192.168.1.100' };
const ip = await (guard as any).getTracker(req);
expect(ip).toBe('192.168.1.100');
});
it('returns 127.0.0.1 when no IP available', async () => {
const req = { headers: {}, ip: undefined };
const ip = await (guard as any).getTracker(req);
expect(ip).toBe('127.0.0.1');
});
it('handles array-typed x-forwarded-for by falling back to req.ip', async () => {
const req = { headers: { 'x-forwarded-for': ['203.0.113.1', '10.0.0.1'] }, ip: '172.16.0.1' };
const ip = await (guard as any).getTracker(req);
expect(ip).toBe('172.16.0.1');
});
});