rwadurian/backend/services/referral-service/test/domain/aggregates/team-statistics.aggregate.s...

166 lines
5.4 KiB
TypeScript

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 });
});
});
});