import { Test, TestingModule } from '@nestjs/testing'; import { ReferralRelationshipRepository } from '../../../src/infrastructure/repositories/referral-relationship.repository'; import { PrismaService } from '../../../src/infrastructure/database/prisma.service'; import { MockPrismaService } from '../mocks/prisma.mock'; import { ReferralRelationship } from '../../../src/domain'; describe('ReferralRelationshipRepository (Integration)', () => { let repository: ReferralRelationshipRepository; let mockPrisma: MockPrismaService; beforeEach(async () => { mockPrisma = new MockPrismaService(); const module: TestingModule = await Test.createTestingModule({ providers: [ ReferralRelationshipRepository, { provide: PrismaService, useValue: mockPrisma, }, ], }).compile(); repository = module.get(ReferralRelationshipRepository); }); afterEach(() => { mockPrisma.$cleanup(); }); describe('save', () => { it('should save a new referral relationship without referrer', async () => { const relationship = ReferralRelationship.create(100n, 'D2512120001', null, null); const saved = await repository.save(relationship); expect(saved).toBeDefined(); expect(saved.userId).toBe(100n); expect(saved.accountSequence).toBe('D2512120001'); expect(saved.referralCode).toBeDefined(); expect(saved.usedReferralCode).toBeNull(); expect(saved.referralChain).toEqual([]); }); it('should save referral relationship with referrer', async () => { // First create the referrer const referrer = ReferralRelationship.create(50n, 'D2512110001', null, null); const savedReferrer = await repository.save(referrer); // Then create with referrer, passing the referrer's referral code const relationship = ReferralRelationship.create(100n, 'D2512120001', 50n, savedReferrer.referralCode, []); const saved = await repository.save(relationship); expect(saved.userId).toBe(100n); expect(saved.accountSequence).toBe('D2512120001'); expect(saved.referrerId).toBe(50n); expect(saved.usedReferralCode).toBe(savedReferrer.referralCode); expect(saved.referralChain).toContain(50n); }); it('should update existing referral relationship', async () => { const relationship = ReferralRelationship.create(100n, 'D2512120001', null, null); await repository.save(relationship); // Save again should update const updated = await repository.save(relationship); expect(updated.userId).toBe(100n); expect(updated.accountSequence).toBe('D2512120001'); }); }); describe('findByUserId', () => { it('should find relationship by user ID', async () => { const relationship = ReferralRelationship.create(100n, 'D2512120001', null, null); await repository.save(relationship); const found = await repository.findByUserId(100n); expect(found).toBeDefined(); expect(found!.userId).toBe(100n); expect(found!.accountSequence).toBe('D2512120001'); }); it('should return null for non-existent user', async () => { const found = await repository.findByUserId(999n); expect(found).toBeNull(); }); }); describe('findByReferralCode', () => { it('should find relationship by referral code', async () => { const relationship = ReferralRelationship.create(100n, 'D2512120001', null, null); const saved = await repository.save(relationship); const found = await repository.findByReferralCode(saved.referralCode); expect(found).toBeDefined(); expect(found!.userId).toBe(100n); expect(found!.accountSequence).toBe('D2512120001'); }); it('should return null for non-existent code', async () => { const found = await repository.findByReferralCode('NONEXISTENT'); expect(found).toBeNull(); }); }); describe('findDirectReferrals', () => { it('should find all direct referrals', async () => { // Create referrer const referrer = ReferralRelationship.create(50n, 'D2512110001', null, null); const savedReferrer = await repository.save(referrer); // Create direct referrals with referrer's code const ref1 = ReferralRelationship.create(100n, 'D2512120001', 50n, savedReferrer.referralCode, []); const ref2 = ReferralRelationship.create(101n, 'D2512120002', 50n, savedReferrer.referralCode, []); await repository.save(ref1); await repository.save(ref2); const directReferrals = await repository.findDirectReferrals(50n); expect(directReferrals.length).toBe(2); expect(directReferrals.map((r) => r.userId)).toContain(100n); expect(directReferrals.map((r) => r.userId)).toContain(101n); }); it('should return empty array for user with no referrals', async () => { const referrer = ReferralRelationship.create(50n, 'D2512110001', null, null); await repository.save(referrer); const directReferrals = await repository.findDirectReferrals(50n); expect(directReferrals.length).toBe(0); }); }); describe('existsByReferralCode', () => { it('should return true for existing code', async () => { const relationship = ReferralRelationship.create(100n, 'D2512120001', null, null); const saved = await repository.save(relationship); const exists = await repository.existsByReferralCode(saved.referralCode); expect(exists).toBe(true); }); it('should return false for non-existent code', async () => { const exists = await repository.existsByReferralCode('NONEXISTENT'); expect(exists).toBe(false); }); }); describe('existsByUserId', () => { it('should return true for existing user', async () => { const relationship = ReferralRelationship.create(100n, 'D2512120001', null, null); await repository.save(relationship); const exists = await repository.existsByUserId(100n); expect(exists).toBe(true); }); it('should return false for non-existent user', async () => { const exists = await repository.existsByUserId(999n); expect(exists).toBe(false); }); }); describe('getReferralChain', () => { it('should return referral chain', async () => { const parentChain = [200n, 300n]; const relationship = ReferralRelationship.create(100n, 'D2512120001', 50n, 'RWAREF12345', parentChain); await repository.save(relationship); const chain = await repository.getReferralChain(100n); expect(chain).toContain(50n); }); it('should return empty array for non-existent user', async () => { const chain = await repository.getReferralChain(999n); expect(chain).toEqual([]); }); }); });