import { TeamStatistics } from '../../../src/domain/aggregates/team-statistics/team-statistics.aggregate'; import { TeamStatisticsUpdatedEvent } from '../../../src/domain/events'; describe('TeamStatistics Aggregate', () => { describe('create', () => { it('should create empty team statistics', () => { const stats = TeamStatistics.create(100n); expect(stats.userId).toBe(100n); expect(stats.directReferralCount).toBe(0); expect(stats.totalTeamCount).toBe(0); expect(stats.personalPlantingCount).toBe(0); expect(stats.teamPlantingCount).toBe(0); expect(stats.leaderboardScore).toBe(0); }); }); describe('reconstitute', () => { it('should reconstitute from persistence data', () => { const props = { id: 1n, userId: 100n, directReferralCount: 5, totalTeamCount: 100, personalPlantingCount: 10, teamPlantingCount: 90, leaderboardScore: 60, maxDirectTeamCount: 40, provinceCityDistribution: { '110000': { '110100': 50 } }, lastCalculatedAt: new Date(), createdAt: new Date(), updatedAt: new Date(), directReferrals: [ { referralId: 200n, teamCount: 40 }, { referralId: 300n, teamCount: 30 }, ], }; const stats = TeamStatistics.reconstitute(props); expect(stats.id).toBe(1n); expect(stats.userId).toBe(100n); expect(stats.directReferralCount).toBe(5); expect(stats.totalTeamCount).toBe(100); expect(stats.leaderboardScore).toBe(60); }); }); describe('addDirectReferral', () => { it('should increment direct referral count', () => { const stats = TeamStatistics.create(100n); stats.addDirectReferral(200n); expect(stats.directReferralCount).toBe(1); stats.addDirectReferral(300n); expect(stats.directReferralCount).toBe(2); }); }); describe('addPersonalPlanting', () => { it('should add personal planting count', () => { const stats = TeamStatistics.create(100n); stats.addPersonalPlanting(10, '110000', '110100'); expect(stats.personalPlantingCount).toBe(10); expect(stats.totalTeamCount).toBe(10); }); it('should emit TeamStatisticsUpdatedEvent', () => { const stats = TeamStatistics.create(100n); stats.addPersonalPlanting(10, '110000', '110100'); expect(stats.domainEvents.length).toBe(1); expect(stats.domainEvents[0]).toBeInstanceOf(TeamStatisticsUpdatedEvent); }); it('should update province/city distribution', () => { const stats = TeamStatistics.create(100n); stats.addPersonalPlanting(10, '110000', '110100'); stats.addPersonalPlanting(5, '110000', '110100'); expect(stats.provinceCityDistribution.getCityTotal('110000', '110100')).toBe(15); }); }); describe('addTeamPlanting', () => { it('should add team planting count', () => { const stats = TeamStatistics.create(100n); stats.addTeamPlanting(20, '110000', '110100', 200n); expect(stats.teamPlantingCount).toBe(20); expect(stats.totalTeamCount).toBe(20); }); it('should track direct referral team count', () => { const stats = TeamStatistics.create(100n); stats.addDirectReferral(200n); stats.addDirectReferral(300n); stats.addTeamPlanting(30, '110000', '110100', 200n); stats.addTeamPlanting(20, '110000', '110100', 300n); const directStats = stats.getDirectReferralStats(); expect(directStats.get(200n)).toBe(30); expect(directStats.get(300n)).toBe(20); }); it('should recalculate leaderboard score', () => { const stats = TeamStatistics.create(100n); stats.addDirectReferral(200n); stats.addDirectReferral(300n); stats.addTeamPlanting(50, '110000', '110100', 200n); stats.addTeamPlanting(30, '110000', '110100', 300n); // Total = 80, max direct = 50, score = 30 expect(stats.leaderboardScore).toBe(30); }); }); describe('getDirectReferralStats', () => { it('should return copy of direct referral stats', () => { const stats = TeamStatistics.create(100n); stats.addDirectReferral(200n); stats.addTeamPlanting(30, '110000', '110100', 200n); const directStats = stats.getDirectReferralStats(); directStats.set(999n, 100); // Modify copy // Original should not be affected expect(stats.getDirectReferralStats().has(999n)).toBe(false); }); }); describe('clearDomainEvents', () => { it('should clear domain events', () => { const stats = TeamStatistics.create(100n); stats.addPersonalPlanting(10, '110000', '110100'); expect(stats.domainEvents.length).toBe(1); stats.clearDomainEvents(); expect(stats.domainEvents.length).toBe(0); }); }); describe('toPersistence', () => { it('should convert to persistence format', () => { const stats = TeamStatistics.create(100n); stats.addDirectReferral(200n); stats.addTeamPlanting(30, '110000', '110100', 200n); const data = stats.toPersistence(); expect(data.userId).toBe(100n); expect(data.directReferralCount).toBe(1); expect(data.totalTeamCount).toBe(30); expect(data.teamPlantingCount).toBe(30); expect(data.directReferrals).toContainEqual({ referralId: 200n, teamCount: 30 }); }); }); });