Skip to content

Commit 2e89815

Browse files
committed
feat(leaderboard): add friends leaderboards (@fehmer)
1 parent 1cf316a commit 2e89815

File tree

10 files changed

+511
-59
lines changed

10 files changed

+511
-59
lines changed

backend/__tests__/__integration__/dal/leaderboards.isolated.spec.ts

Lines changed: 167 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ describe("LeaderboardsDal", () => {
3232

3333
//WHEN
3434
await LeaderboardsDal.update("time", "15", "english");
35-
const result = await LeaderboardsDal.get("time", "15", "english", 0, 50);
35+
const results = await LeaderboardsDal.get("time", "15", "english", 0, 50);
3636

3737
//THEN
38-
expect(result).toHaveLength(1);
38+
expect(results).toHaveLength(1);
3939
expect(
40-
(result as LeaderboardsDal.DBLeaderboardEntry[])[0]
40+
(results as LeaderboardsDal.DBLeaderboardEntry[])[0]
4141
).toHaveProperty("uid", applicableUser.uid);
4242
});
4343

@@ -50,7 +50,7 @@ describe("LeaderboardsDal", () => {
5050

5151
//WHEN
5252
await LeaderboardsDal.update("time", "15", "english");
53-
const result = (await LeaderboardsDal.get(
53+
const results = (await LeaderboardsDal.get(
5454
"time",
5555
"15",
5656
"english",
@@ -59,7 +59,7 @@ describe("LeaderboardsDal", () => {
5959
)) as DBLeaderboardEntry[];
6060

6161
//THEN
62-
const lb = result.map((it) => _.omit(it, ["_id"]));
62+
const lb = results.map((it) => _.omit(it, ["_id"]));
6363

6464
expect(lb).toEqual([
6565
expectedLbEntry("15", { rank: 1, user: rank1 }),
@@ -77,7 +77,7 @@ describe("LeaderboardsDal", () => {
7777

7878
//WHEN
7979
await LeaderboardsDal.update("time", "60", "english");
80-
const result = (await LeaderboardsDal.get(
80+
const results = (await LeaderboardsDal.get(
8181
"time",
8282
"60",
8383
"english",
@@ -86,7 +86,7 @@ describe("LeaderboardsDal", () => {
8686
)) as LeaderboardsDal.DBLeaderboardEntry[];
8787

8888
//THEN
89-
const lb = result.map((it) => _.omit(it, ["_id"]));
89+
const lb = results.map((it) => _.omit(it, ["_id"]));
9090

9191
expect(lb).toEqual([
9292
expectedLbEntry("60", { rank: 1, user: rank1 }),
@@ -262,7 +262,7 @@ describe("LeaderboardsDal", () => {
262262

263263
//WHEN
264264
await LeaderboardsDal.update("time", "15", "english");
265-
const result = (await LeaderboardsDal.get(
265+
const results = (await LeaderboardsDal.get(
266266
"time",
267267
"15",
268268
"english",
@@ -272,14 +272,169 @@ describe("LeaderboardsDal", () => {
272272
)) as DBLeaderboardEntry[];
273273

274274
//THEN
275-
expect(result[0]?.isPremium).toBeUndefined();
275+
expect(results[0]?.isPremium).toBeUndefined();
276+
});
277+
});
278+
279+
describe("get", () => {
280+
it("should get for page", async () => {
281+
//GIVEN
282+
const _rank1 = await createUser(lbBests(pb(90), pb(105, 90, 2)));
283+
const _rank2 = await createUser(lbBests(undefined, pb(100, 90, 1)));
284+
const rank3 = await createUser(lbBests(undefined, pb(95, 80, 2)));
285+
const rank4 = await createUser(lbBests(undefined, pb(90, 100, 1)));
286+
await LeaderboardsDal.update("time", "60", "english");
287+
288+
//WHEN
289+
290+
const results = (await LeaderboardsDal.get(
291+
"time",
292+
"60",
293+
"english",
294+
1,
295+
2,
296+
true
297+
)) as LeaderboardsDal.DBLeaderboardEntry[];
298+
299+
//THEN
300+
const lb = results.map((it) => _.omit(it, ["_id"]));
301+
302+
expect(lb).toEqual([
303+
expectedLbEntry("60", { rank: 3, user: rank3 }),
304+
expectedLbEntry("60", { rank: 4, user: rank4 }),
305+
]);
306+
});
307+
it("should get for friends only", async () => {
308+
//GIVEN
309+
const rank1 = await createUser(lbBests(pb(90), pb(100, 90, 2)));
310+
const _rank2 = await createUser(lbBests(undefined, pb(100, 90, 1)));
311+
const _rank3 = await createUser(lbBests(undefined, pb(100, 80, 2)));
312+
const rank4 = await createUser(lbBests(undefined, pb(90, 100, 1)));
313+
await LeaderboardsDal.update("time", "60", "english");
314+
315+
//WHEN
316+
317+
const results = (await LeaderboardsDal.get(
318+
"time",
319+
"60",
320+
"english",
321+
0,
322+
50,
323+
false,
324+
[rank1.uid, rank4.uid]
325+
)) as LeaderboardsDal.DBLeaderboardEntry[];
326+
327+
//THEN
328+
const lb = results.map((it) => _.omit(it, ["_id"]));
329+
330+
expect(lb).toEqual([
331+
expectedLbEntry("60", { rank: 1, user: rank1, friendsRank: 1 }),
332+
expectedLbEntry("60", { rank: 4, user: rank4, friendsRank: 2 }),
333+
]);
334+
});
335+
it("should get for friends only with page", async () => {
336+
//GIVEN
337+
const rank1 = await createUser(lbBests(pb(90), pb(105, 90, 2)));
338+
const rank2 = await createUser(lbBests(undefined, pb(100, 90, 1)));
339+
const _rank3 = await createUser(lbBests(undefined, pb(95, 80, 2)));
340+
const rank4 = await createUser(lbBests(undefined, pb(90, 100, 1)));
341+
await LeaderboardsDal.update("time", "60", "english");
342+
343+
//WHEN
344+
const results = (await LeaderboardsDal.get(
345+
"time",
346+
"60",
347+
"english",
348+
1,
349+
2,
350+
false,
351+
[rank1.uid, rank2.uid, rank4.uid]
352+
)) as LeaderboardsDal.DBLeaderboardEntry[];
353+
354+
//THEN
355+
const lb = results.map((it) => _.omit(it, ["_id"]));
356+
357+
expect(lb).toEqual([
358+
expectedLbEntry("60", { rank: 4, user: rank4, friendsRank: 3 }),
359+
]);
360+
});
361+
it("should return empty list if no friends", async () => {
362+
//GIVEN
363+
364+
//WHEN
365+
const results = (await LeaderboardsDal.get(
366+
"time",
367+
"60",
368+
"english",
369+
1,
370+
2,
371+
false,
372+
[]
373+
)) as LeaderboardsDal.DBLeaderboardEntry[];
374+
//THEN
375+
expect(results).toEqual([]);
376+
});
377+
});
378+
describe("getCount / getRank", () => {
379+
it("should get count", async () => {
380+
//GIVEN
381+
await createUser(lbBests(undefined, pb(105)));
382+
await createUser(lbBests(undefined, pb(100)));
383+
const me = await createUser(lbBests(undefined, pb(95)));
384+
await createUser(lbBests(undefined, pb(90)));
385+
await LeaderboardsDal.update("time", "60", "english");
386+
387+
//WHEN / THEN
388+
389+
expect(await LeaderboardsDal.getCount("time", "60", "english")) //
390+
.toEqual(4);
391+
expect(await LeaderboardsDal.getRank("time", "60", "english", me.uid)) //
392+
.toEqual(
393+
expect.objectContaining({
394+
wpm: 95,
395+
rank: 3,
396+
name: me.name,
397+
uid: me.uid,
398+
})
399+
);
400+
});
401+
it("should get for friends only", async () => {
402+
//GIVEN
403+
const friendOne = await createUser(lbBests(undefined, pb(105)));
404+
await createUser(lbBests(undefined, pb(100)));
405+
await createUser(lbBests(undefined, pb(95)));
406+
const friendTwo = await createUser(lbBests(undefined, pb(90)));
407+
const me = await createUser(lbBests(undefined, pb(99)));
408+
409+
console.log("me", me.uid);
410+
411+
await LeaderboardsDal.update("time", "60", "english");
412+
413+
const friends = [friendOne.uid, friendTwo.uid, me.uid];
414+
415+
//WHEN / THEN
416+
417+
expect(await LeaderboardsDal.getCount("time", "60", "english", friends)) //
418+
.toEqual(3);
419+
expect(
420+
await LeaderboardsDal.getRank("time", "60", "english", me.uid, friends)
421+
) //
422+
.toEqual(
423+
expect.objectContaining({
424+
wpm: 99,
425+
rank: 3,
426+
friendsRank: 2,
427+
name: me.name,
428+
uid: me.uid,
429+
})
430+
);
276431
});
277432
});
278433
});
279434

280435
function expectedLbEntry(
281436
time: string,
282-
{ rank, user, badgeId, isPremium }: ExpectedLbEntry
437+
{ rank, user, badgeId, isPremium, friendsRank }: ExpectedLbEntry
283438
) {
284439
// @ts-expect-error
285440
const lbBest: PersonalBest =
@@ -299,6 +454,7 @@ function expectedLbEntry(
299454
discordAvatar: user.discordAvatar,
300455
badgeId,
301456
isPremium,
457+
friendsRank,
302458
};
303459
}
304460

@@ -351,4 +507,5 @@ type ExpectedLbEntry = {
351507
user: UserDal.DBUser;
352508
badgeId?: number;
353509
isPremium?: boolean;
510+
friendsRank?: number;
354511
};

0 commit comments

Comments
 (0)