rwadurian/backend/services/leaderboard-service/test/domain/services/ranking-merger.service.spec.ts

165 lines
5.4 KiB
TypeScript

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