rwadurian/backend/services/leaderboard-service/test/integration/leaderboard-repository.inte...

234 lines
7.3 KiB
TypeScript

import { LeaderboardType } from '../../src/domain/value-objects/leaderboard-type.enum';
import { LeaderboardPeriod } from '../../src/domain/value-objects/leaderboard-period.vo';
describe('LeaderboardRepository Integration Tests', () => {
describe('Database Connection', () => {
it('should connect to the database', async () => {
const isConnected = global.testUtils?.prisma !== undefined;
if (!isConnected) {
console.log('Skipping database test - no connection available');
return;
}
// Test basic query
const result = await global.testUtils.prisma.$queryRaw`SELECT 1 as result`;
expect(result).toBeDefined();
});
});
describe('LeaderboardConfig Operations', () => {
beforeEach(async () => {
if (global.testUtils?.cleanDatabase) {
await global.testUtils.cleanDatabase();
}
});
it('should create and retrieve leaderboard config', async () => {
if (!global.testUtils?.prisma) {
console.log('Skipping test - no database connection');
return;
}
const config = await global.testUtils.prisma.leaderboardConfig.create({
data: {
configKey: 'TEST_CONFIG',
dailyEnabled: true,
weeklyEnabled: true,
monthlyEnabled: true,
virtualRankingEnabled: false,
virtualAccountCount: 0,
displayLimit: 30,
refreshIntervalMinutes: 5,
},
});
expect(config.id).toBeDefined();
expect(config.configKey).toBe('TEST_CONFIG');
expect(config.dailyEnabled).toBe(true);
// Retrieve
const retrieved = await global.testUtils.prisma.leaderboardConfig.findUnique({
where: { configKey: 'TEST_CONFIG' },
});
expect(retrieved).toBeDefined();
expect(retrieved?.displayLimit).toBe(30);
});
it('should update leaderboard config', async () => {
if (!global.testUtils?.prisma) {
console.log('Skipping test - no database connection');
return;
}
await global.testUtils.prisma.leaderboardConfig.create({
data: {
configKey: 'UPDATE_TEST',
dailyEnabled: true,
weeklyEnabled: true,
monthlyEnabled: true,
virtualRankingEnabled: false,
virtualAccountCount: 0,
displayLimit: 30,
refreshIntervalMinutes: 5,
},
});
const updated = await global.testUtils.prisma.leaderboardConfig.update({
where: { configKey: 'UPDATE_TEST' },
data: {
virtualRankingEnabled: true,
virtualAccountCount: 20,
},
});
expect(updated.virtualRankingEnabled).toBe(true);
expect(updated.virtualAccountCount).toBe(20);
});
});
describe('LeaderboardRanking Operations', () => {
beforeEach(async () => {
if (global.testUtils?.cleanDatabase) {
await global.testUtils.cleanDatabase();
}
});
it('should create leaderboard ranking entries', async () => {
if (!global.testUtils?.prisma) {
console.log('Skipping test - no database connection');
return;
}
const period = LeaderboardPeriod.currentDaily();
const ranking = await global.testUtils.prisma.leaderboardRanking.create({
data: {
leaderboardType: LeaderboardType.DAILY,
periodKey: period.key,
periodStartAt: period.startAt,
periodEndAt: period.endAt,
userId: BigInt(1),
rankPosition: 1,
displayPosition: 1,
previousRank: null,
totalTeamPlanting: 200,
maxDirectTeamPlanting: 50,
effectiveScore: 150,
isVirtual: false,
userSnapshot: { nickname: 'TestUser', avatar: null },
},
});
expect(ranking.id).toBeDefined();
expect(ranking.rankPosition).toBe(1);
expect(ranking.effectiveScore).toBe(150);
});
it('should query rankings by period and type', async () => {
if (!global.testUtils?.prisma) {
console.log('Skipping test - no database connection');
return;
}
const period = LeaderboardPeriod.currentDaily();
// Create multiple rankings
await global.testUtils.prisma.leaderboardRanking.createMany({
data: [
{
leaderboardType: LeaderboardType.DAILY,
periodKey: period.key,
periodStartAt: period.startAt,
periodEndAt: period.endAt,
userId: BigInt(1),
rankPosition: 1,
displayPosition: 1,
totalTeamPlanting: 300,
maxDirectTeamPlanting: 100,
effectiveScore: 200,
isVirtual: false,
userSnapshot: { nickname: 'User1', avatar: null },
},
{
leaderboardType: LeaderboardType.DAILY,
periodKey: period.key,
periodStartAt: period.startAt,
periodEndAt: period.endAt,
userId: BigInt(2),
rankPosition: 2,
displayPosition: 2,
totalTeamPlanting: 200,
maxDirectTeamPlanting: 50,
effectiveScore: 150,
isVirtual: false,
userSnapshot: { nickname: 'User2', avatar: null },
},
],
});
const rankings = await global.testUtils.prisma.leaderboardRanking.findMany({
where: {
leaderboardType: LeaderboardType.DAILY,
periodKey: period.key,
},
orderBy: { rankPosition: 'asc' },
});
expect(rankings.length).toBe(2);
expect(rankings[0].effectiveScore).toBe(200);
expect(rankings[1].effectiveScore).toBe(150);
});
});
describe('VirtualAccount Operations', () => {
beforeEach(async () => {
if (global.testUtils?.cleanDatabase) {
await global.testUtils.cleanDatabase();
}
});
it('should create virtual accounts', async () => {
if (!global.testUtils?.prisma) {
console.log('Skipping test - no database connection');
return;
}
const virtualAccount = await global.testUtils.prisma.virtualAccount.create({
data: {
displayName: 'VirtualUser1',
avatar: null,
accountType: 'RANKING_VIRTUAL',
isActive: true,
},
});
expect(virtualAccount.id).toBeDefined();
expect(virtualAccount.displayName).toBe('VirtualUser1');
expect(virtualAccount.isActive).toBe(true);
});
it('should query active virtual accounts', async () => {
if (!global.testUtils?.prisma) {
console.log('Skipping test - no database connection');
return;
}
await global.testUtils.prisma.virtualAccount.createMany({
data: [
{ displayName: 'Active1', accountType: 'RANKING_VIRTUAL', isActive: true },
{ displayName: 'Active2', accountType: 'RANKING_VIRTUAL', isActive: true },
{ displayName: 'Inactive', accountType: 'RANKING_VIRTUAL', isActive: false },
],
});
const activeAccounts = await global.testUtils.prisma.virtualAccount.findMany({
where: { isActive: true },
});
expect(activeAccounts.length).toBe(2);
});
});
});