166 lines
5.4 KiB
TypeScript
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 });
|
|
});
|
|
});
|
|
});
|