diff --git a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/sessions/router.test.ts b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/sessions/router.test.ts index a4e9eb2bb..a75047185 100644 --- a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/sessions/router.test.ts +++ b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/sessions/router.test.ts @@ -107,6 +107,48 @@ t.test("GET /api/v1/users/:userID/games/:game/:playtype/sessions/best", (t) => { t.end(); }); + t.test( + "Should return a user's best 100 sessions according to the provided rating alg.", + async (t) => { + const sessions: SessionDocument[] = []; + + for (let i = 0; i < 200; i++) { + sessions.push({ + sessionID: i.toString(), + game: "iidx", + playtype: "SP", + userID: 1, + calculatedData: { + ktLampRating: 200 - i, + BPI: i, + }, + } as SessionDocument); + } + + await db.sessions.remove({}); + await db.sessions.insert(sessions); + + const res = await mockApi.get( + "/api/v1/users/test_zkldi/games/iidx/SP/sessions/best?alg=BPI" + ); + + t.hasStrict(res.body, { + success: true, + description: "Retrieved 100 sessions.", + }); + + t.strictSame( + res.body.body.map((e: SessionDocument) => e.sessionID), + sessions + .slice(100) + .reverse() + .map((e) => e.sessionID) + ); + + t.end(); + } + ); + t.end(); }); diff --git a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/sessions/router.ts b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/sessions/router.ts index e1bc8b446..d42048c32 100644 --- a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/sessions/router.ts +++ b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/sessions/router.ts @@ -3,6 +3,7 @@ import db from "external/mongo/db"; import { SYMBOL_TachiData } from "lib/constants/tachi"; import { SearchSessions } from "lib/search/search"; import { GetGamePTConfig } from "tachi-common"; +import { CheckStrSessionAlg, SessionRatingAlgs } from "utils/string-checks"; const router: Router = Router({ mergeParams: true }); @@ -37,7 +38,6 @@ router.get("/", async (req, res) => { * for that game. * * @param alg - An override to specify a different algorithm for that game. - * UNIMPLEMENTED!!! * @name GET /api/v1/users/:userID/games/:game/:playtype/sessions/best */ router.get("/best", async (req, res) => { @@ -46,6 +46,22 @@ router.get("/best", async (req, res) => { const playtype = req[SYMBOL_TachiData]!.playtype!; const gptConfig = GetGamePTConfig(game, playtype); + let alg = gptConfig.defaultSessionRatingAlg; + if (typeof req.query.alg === "string") { + const userAlg = CheckStrSessionAlg(game, playtype, req.query.alg); + + if (userAlg === null) { + return res.status(400).json({ + success: false, + description: `Invalid algorithm '${ + req.query.alg + }' provided. Expected any of ${gptConfig.sessionRatingAlgs.join(", ")}.`, + }); + } + + alg = userAlg; + } + const sessions = await db.sessions.find( { userID: user.id, @@ -55,7 +71,7 @@ router.get("/best", async (req, res) => { { limit: 100, sort: { - [`calculatedData.${gptConfig.defaultSessionRatingAlg}`]: -1, + [`calculatedData.${alg}`]: -1, }, } );