import { RankingMergerService } from '../../../src/domain/services/ranking-merger.service'; import { LeaderboardRanking } from '../../../src/domain/aggregates/leaderboard-ranking/leaderboard-ranking.aggregate'; import { LeaderboardType, LeaderboardPeriod, UserSnapshot } from '../../../src/domain/value-objects'; describe('RankingMergerService', () => { let service: RankingMergerService; let mockPeriod: LeaderboardPeriod; beforeEach(() => { service = new RankingMergerService(); mockPeriod = LeaderboardPeriod.currentDaily(); }); const createRealRanking = (userId: bigint, rankPosition: number) => { return LeaderboardRanking.createRealRanking({ leaderboardType: LeaderboardType.DAILY, period: mockPeriod, userId, rankPosition, displayPosition: rankPosition, previousRank: null, totalTeamPlanting: 100, maxDirectTeamPlanting: 50, userSnapshot: UserSnapshot.create({ userId, nickname: `用户${userId}`, }), }); }; const createVirtualRanking = (virtualAccountId: bigint, displayPosition: number) => { return LeaderboardRanking.createVirtualRanking({ leaderboardType: LeaderboardType.DAILY, period: mockPeriod, virtualAccountId, displayPosition, generatedScore: 500, displayName: `虚拟用户${virtualAccountId}`, avatar: null, }); }; describe('mergeRankings', () => { it('没有虚拟排名时应该保持原始排名', () => { const realRankings = [ createRealRanking(1n, 1), createRealRanking(2n, 2), createRealRanking(3n, 3), ]; const merged = service.mergeRankings([], realRankings, 30); expect(merged.length).toBe(3); expect(merged[0].displayPosition.value).toBe(1); expect(merged[1].displayPosition.value).toBe(2); expect(merged[2].displayPosition.value).toBe(3); }); it('有虚拟排名时应该正确调整真实用户排名', () => { const virtualRankings = [ createVirtualRanking(100n, 1), createVirtualRanking(101n, 2), ]; const realRankings = [ createRealRanking(1n, 1), createRealRanking(2n, 2), ]; const merged = service.mergeRankings(virtualRankings, realRankings, 30); expect(merged.length).toBe(4); expect(merged[0].isVirtual).toBe(true); expect(merged[0].displayPosition.value).toBe(1); expect(merged[1].isVirtual).toBe(true); expect(merged[1].displayPosition.value).toBe(2); expect(merged[2].isVirtual).toBe(false); expect(merged[2].displayPosition.value).toBe(3); // 原来第1名变成第3名 expect(merged[3].isVirtual).toBe(false); expect(merged[3].displayPosition.value).toBe(4); // 原来第2名变成第4名 }); it('应该遵守显示数量限制', () => { const virtualRankings = [ createVirtualRanking(100n, 1), createVirtualRanking(101n, 2), ]; const realRankings = [ createRealRanking(1n, 1), createRealRanking(2n, 2), createRealRanking(3n, 3), ]; const merged = service.mergeRankings(virtualRankings, realRankings, 3); expect(merged.length).toBe(3); expect(merged[0].isVirtual).toBe(true); expect(merged[1].isVirtual).toBe(true); expect(merged[2].isVirtual).toBe(false); }); }); describe('getRealRankingsOnly', () => { it('应该只返回真实用户排名', () => { const virtualRanking = createVirtualRanking(100n, 1); const realRanking = createRealRanking(1n, 2); const rankings = [virtualRanking, realRanking]; const realOnly = service.getRealRankingsOnly(rankings, 10); expect(realOnly.length).toBe(1); expect(realOnly[0].isVirtual).toBe(false); }); }); describe('getVirtualRankingsOnly', () => { it('应该只返回虚拟排名', () => { const virtualRanking = createVirtualRanking(100n, 1); const realRanking = createRealRanking(1n, 2); const rankings = [virtualRanking, realRanking]; const virtualOnly = service.getVirtualRankingsOnly(rankings); expect(virtualOnly.length).toBe(1); expect(virtualOnly[0].isVirtual).toBe(true); }); }); describe('calculateRealRankPosition', () => { it('应该正确计算真实排名位置', () => { const virtualRanking = createVirtualRanking(100n, 1); const realRanking1 = createRealRanking(1n, 2); const realRanking2 = createRealRanking(2n, 3); const rankings = [virtualRanking, realRanking1, realRanking2]; expect(service.calculateRealRankPosition(rankings, 1n)).toBe(1); expect(service.calculateRealRankPosition(rankings, 2n)).toBe(2); }); it('用户不在排名中应该返回null', () => { const rankings = [createRealRanking(1n, 1)]; expect(service.calculateRealRankPosition(rankings, 999n)).toBeNull(); }); }); describe('validateRankingContinuity', () => { it('连续排名应该验证通过', () => { const rankings = [ createRealRanking(1n, 1), createRealRanking(2n, 2), createRealRanking(3n, 3), ]; expect(service.validateRankingContinuity(rankings)).toBe(true); }); it('空数组应该验证通过', () => { expect(service.validateRankingContinuity([])).toBe(true); }); }); });