From 5dc4c43e921707cf5150859856c972d6e759a29d Mon Sep 17 00:00:00 2001 From: zkldi <20380519+zkldi@users.noreply.github.com> Date: Fri, 21 Jan 2022 14:53:24 +0000 Subject: [PATCH 1/8] Support setting a BPI target for IIDX Fixes #634 --- .../_game/_playtype/settings/router.test.ts | 27 +++++++++++++++++++ .../games/_game/_playtype/settings/router.ts | 10 +++---- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts index 19c14ed5b..49e994f48 100644 --- a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts +++ b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts @@ -136,6 +136,33 @@ t.test("PATCH /api/v1/users/:userID/games/:game/:playtype/settings", (t) => { t.end(); }); + t.test("Should reject a arbitrary things on game specific settings.", async (t) => { + await db["api-tokens"].insert({ + userID: 1, + identifier: "api_token", + permissions: { + customise_profile: true, + }, + token: "api_token", + fromAPIClient: null, + }); + + const res = await mockApi + .patch("/api/v1/users/1/games/iidx/SP/settings") + .set("Authorization", "Bearer api_token") + .send({ + preferredScoreAlg: "ktRating", + gameSpecific: { + display2DXTra: true, + arbitraryValue: {}, + }, + }); + + t.equal(res.statusCode, 400); + + t.end(); + }); + t.test("Requires the user to be authed as the requested user.", async (t) => { await db["api-tokens"].insert({ userID: 2, diff --git a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.ts b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.ts index ed865c379..e78e707fe 100644 --- a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.ts +++ b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.ts @@ -55,12 +55,10 @@ router.patch( display2DXTra: "boolean", }; } - const err = p( - req.body, - { gameSpecific: p.optional(schema) }, - {}, - { allowExcessKeys: true } - ); + // A limitation in prudence means that validating top-level properties like this isn't + // possible. + // A prudence v1.0. should fix this! + const err = p({ __: req.body.gameSpecific }, { __: p.optional(schema) }, {}); if (err) { return res.status(400).json({ From fbdf9489dcd90d8b19e989f78ca51f922e500cb7 Mon Sep 17 00:00:00 2001 From: zkldi <20380519+zkldi@users.noreply.github.com> Date: Fri, 21 Jan 2022 14:59:57 +0000 Subject: [PATCH 2/8] Bind bpiTarget between 0 and 100 --- .../v1/users/_userID/games/_game/_playtype/settings/router.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.ts b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.ts index e78e707fe..9eeddb29c 100644 --- a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.ts +++ b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.ts @@ -53,6 +53,7 @@ router.patch( if (game === "iidx") { schema = { display2DXTra: "boolean", + bpiTarget: p.isBoundedInteger(0, 100), }; } // A limitation in prudence means that validating top-level properties like this isn't From 90935d58f82cd51d77c510f44d35979f5e6858a0 Mon Sep 17 00:00:00 2001 From: zkldi <20380519+zkldi@users.noreply.github.com> Date: Fri, 21 Jan 2022 15:01:17 +0000 Subject: [PATCH 3/8] Add a regression test for bpi stuff --- .../users/_userID/games/_game/_playtype/settings/router.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts index 49e994f48..6a1a1a4ce 100644 --- a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts +++ b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts @@ -102,6 +102,7 @@ t.test("PATCH /api/v1/users/:userID/games/:game/:playtype/settings", (t) => { preferredScoreAlg: "ktLampRating", gameSpecific: { display2DXTra: true, + bpiTarget: 50, }, }); @@ -119,6 +120,7 @@ t.test("PATCH /api/v1/users/:userID/games/:game/:playtype/settings", (t) => { stats: [], gameSpecific: { display2DXTra: true, + bpiTarget: 50, }, }, }, From a76b2eb873874f5ca8e24fbf6bd06fe422778061 Mon Sep 17 00:00:00 2001 From: zkldi <20380519+zkldi@users.noreply.github.com> Date: Fri, 21 Jan 2022 15:10:23 +0000 Subject: [PATCH 4/8] Add even more regression tests while we're here --- server/package.json | 2 +- server/pnpm-lock.yaml | 8 +- .../_game/_playtype/settings/router.test.ts | 108 ++++++++++++++++++ .../games/_game/_playtype/settings/router.ts | 10 +- 4 files changed, 117 insertions(+), 11 deletions(-) diff --git a/server/package.json b/server/package.json index f1a3e0386..fbdfee609 100644 --- a/server/package.json +++ b/server/package.json @@ -82,7 +82,7 @@ "rimraf": "3.0.2", "safe-json-stringify": "1.2.0", "seq-logging": "^1.1.1", - "tachi-common": "0.5.4", + "tachi-common": "0.5.5", "ts-node": "10.0.0", "tsconfig-paths": "3.10.1", "typescript": "4.3.4", diff --git a/server/pnpm-lock.yaml b/server/pnpm-lock.yaml index a9a1c0ce4..ab20ddb7b 100644 --- a/server/pnpm-lock.yaml +++ b/server/pnpm-lock.yaml @@ -63,7 +63,7 @@ specifiers: safe-json-stringify: 1.2.0 seq-logging: ^1.1.1 supertest: 6.1.3 - tachi-common: 0.5.4 + tachi-common: 0.5.5 tap: 15.0.9 ts-node: 10.0.0 tsconfig-paths: 3.10.1 @@ -107,7 +107,7 @@ dependencies: rimraf: 3.0.2 safe-json-stringify: 1.2.0 seq-logging: 1.1.1 - tachi-common: 0.5.4 + tachi-common: 0.5.5 ts-node: 10.0.0_83f53b0a0c5616d3fa00ed4e30b9ce1b tsconfig-paths: 3.10.1 typescript: 4.3.4 @@ -5386,8 +5386,8 @@ packages: strip-ansi: 6.0.0 dev: true - /tachi-common/0.5.4: - resolution: {integrity: sha512-6QDpdvyGB2JOzPcW+7Hm/jXCKXXrIB6KgTKmvVq86771Iyali/oA2iigSb+oeVUQb8zNX2IM/s9hRD9F+80xTw==} + /tachi-common/0.5.5: + resolution: {integrity: sha512-LFKK+3xhlDQJ07yUij2/H+0cPiHXoXKdFQyR8X1ZNSjsluZoWncR9Rkqwhxlt/WeFBaGyLjkYkpdMkRYZMLVUg==} dependencies: monk: 7.3.4 transitivePeerDependencies: diff --git a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts index 6a1a1a4ce..778f29193 100644 --- a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts +++ b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts @@ -138,6 +138,114 @@ t.test("PATCH /api/v1/users/:userID/games/:game/:playtype/settings", (t) => { t.end(); }); + t.test("Should update an IIDX player's bpiTarget settings.", async (t) => { + t.beforeEach(async () => { + await db["api-tokens"].insert({ + userID: 1, + identifier: "api_token", + permissions: { + customise_profile: true, + }, + token: "api_token", + fromAPIClient: null, + }); + }); + + const f = async (target: number) => { + const res = await mockApi + .patch("/api/v1/users/1/games/iidx/SP/settings") + .set("Authorization", "Bearer api_token") + .send({ + gameSpecific: { + bpiTarget: target, + }, + }); + + t.equal(res.statusCode, 200); + + t.strictSame( + res.body.body, + { + userID: 1, + game: "iidx", + playtype: "SP", + preferences: { + preferredScoreAlg: null, + preferredSessionAlg: null, + preferredProfileAlg: null, + scoreBucket: null, + stats: [], + gameSpecific: { + bpiTarget: target, + }, + }, + }, + "Should only update the mutated properties." + ); + + const data = await db["game-settings"].findOne({ + userID: 1, + game: "iidx", + playtype: "SP", + }); + + t.equal(data?.preferences.gameSpecific.bpiTarget, target); + }; + + for (const target of [0, 10, 15, 100]) { + t.test(`Should be able to update the BPI target to ${target}`, async (t) => { + await f(target); + + t.end(); + }); + } + + t.test("Should reject float BPI targets.", async (t) => { + const res = await mockApi + .patch("/api/v1/users/1/games/iidx/SP/settings") + .set("Authorization", "Bearer api_token") + .send({ + gameSpecific: { + bpiTarget: 10.5, + }, + }); + + t.equal(res.statusCode, 400); + }); + + t.test("Should reject negative BPI targets", async (t) => { + const res = await mockApi + .patch("/api/v1/users/1/games/iidx/SP/settings") + .set("Authorization", "Bearer api_token") + .send({ + gameSpecific: { + bpiTarget: -10, + }, + }); + + t.equal(res.statusCode, 400); + + t.end(); + }); + + t.test("Should reject >= 100 BPI targets", async (t) => { + const res = await mockApi + .patch("/api/v1/users/1/games/iidx/SP/settings") + .set("Authorization", "Bearer api_token") + .send({ + gameSpecific: { + bpiTarget: 101, + }, + }); + + t.equal(res.statusCode, 400); + + t.end(); + }); + + t.end(); + }); + t.test("Should reject a arbitrary things on game specific settings.", async (t) => { await db["api-tokens"].insert({ userID: 1, diff --git a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.ts b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.ts index 9eeddb29c..dd07f3463 100644 --- a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.ts +++ b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.ts @@ -52,14 +52,12 @@ router.patch( if (game === "iidx") { schema = { - display2DXTra: "boolean", - bpiTarget: p.isBoundedInteger(0, 100), + display2DXTra: p.optional("boolean"), + bpiTarget: p.optional(p.isBoundedInteger(0, 100)), }; } - // A limitation in prudence means that validating top-level properties like this isn't - // possible. - // A prudence v1.0. should fix this! - const err = p({ __: req.body.gameSpecific }, { __: p.optional(schema) }, {}); + + const err = p(req.body.gameSpecific, schema); if (err) { return res.status(400).json({ From 26ffdecf74030f796eeb50e4b55271633ee74059 Mon Sep 17 00:00:00 2001 From: zkldi <20380519+zkldi@users.noreply.github.com> Date: Fri, 21 Jan 2022 15:12:06 +0000 Subject: [PATCH 5/8] fix a small mistake in the tests --- .../users/_userID/games/_game/_playtype/settings/router.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts index 778f29193..95d80204b 100644 --- a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts +++ b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts @@ -176,6 +176,7 @@ t.test("PATCH /api/v1/users/:userID/games/:game/:playtype/settings", (t) => { scoreBucket: null, stats: [], gameSpecific: { + display2DXTra: false, bpiTarget: target, }, }, From e45038d2c83c078a63cc860acadb6526be092718 Mon Sep 17 00:00:00 2001 From: zkldi <20380519+zkldi@users.noreply.github.com> Date: Fri, 21 Jan 2022 15:28:31 +0000 Subject: [PATCH 6/8] Fix hanging and broken tests. --- server/src/lib/showcase/get-stats.test.ts | 1 + .../users/_userID/games/_game/_playtype/settings/router.test.ts | 2 ++ 2 files changed, 3 insertions(+) diff --git a/server/src/lib/showcase/get-stats.test.ts b/server/src/lib/showcase/get-stats.test.ts index 8d8004696..9ed0a3ab5 100644 --- a/server/src/lib/showcase/get-stats.test.ts +++ b/server/src/lib/showcase/get-stats.test.ts @@ -42,6 +42,7 @@ t.test("#EvalulateUsersStatsShowcase", (t) => { ], gameSpecific: { display2DXTra: false, + bpiTarget: 0, }, }, }); diff --git a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts index 95d80204b..873495cef 100644 --- a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts +++ b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts @@ -212,6 +212,8 @@ t.test("PATCH /api/v1/users/:userID/games/:game/:playtype/settings", (t) => { }); t.equal(res.statusCode, 400); + + t.end(); }); t.test("Should reject negative BPI targets", async (t) => { From 94d18e88a45586f525e9a7b38eeb402c2a97d540 Mon Sep 17 00:00:00 2001 From: zkldi <20380519+zkldi@users.noreply.github.com> Date: Sat, 22 Jan 2022 12:11:58 +0000 Subject: [PATCH 7/8] Weird test left in queue. TAP bug? --- .../lib/score-mutation/update-score.test.ts | 4 - .../_game/_playtype/settings/router.test.ts | 77 +++++++++---------- 2 files changed, 37 insertions(+), 44 deletions(-) diff --git a/server/src/lib/score-mutation/update-score.test.ts b/server/src/lib/score-mutation/update-score.test.ts index d304186f6..d3d71aaf0 100644 --- a/server/src/lib/score-mutation/update-score.test.ts +++ b/server/src/lib/score-mutation/update-score.test.ts @@ -68,8 +68,6 @@ t.test("#UpdateScore", (t) => { const newScoreID = CreateScoreID(score.userID, score, score.chartID); - rootLogger.crit(newScoreID); - await db.imports.insert(mockImportDocument); await db.sessions.insert(mockSessionDocument); @@ -87,8 +85,6 @@ t.test("#UpdateScore", (t) => { scoreID: newScoreID, }); - rootLogger.crit("foo", await db.scores.find({})); - t.hasStrict( dbNewScore?.scoreData, score.scoreData, diff --git a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts index 873495cef..ab07df375 100644 --- a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts +++ b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts @@ -1,6 +1,7 @@ /* eslint-disable no-await-in-loop */ import db from "external/mongo/db"; import t from "tap"; +import { CloseAllConnections } from "test-utils/close-connections"; import mockApi from "test-utils/mock-api"; import ResetDBState from "test-utils/resets"; @@ -138,7 +139,7 @@ t.test("PATCH /api/v1/users/:userID/games/:game/:playtype/settings", (t) => { t.end(); }); - t.test("Should update an IIDX player's bpiTarget settings.", async (t) => { + t.test("Should update an IIDX player's bpiTarget settings.", (t) => { t.beforeEach(async () => { await db["api-tokens"].insert({ userID: 1, @@ -151,51 +152,47 @@ t.test("PATCH /api/v1/users/:userID/games/:game/:playtype/settings", (t) => { }); }); - const f = async (target: number) => { - const res = await mockApi - .patch("/api/v1/users/1/games/iidx/SP/settings") - .set("Authorization", "Bearer api_token") - .send({ - gameSpecific: { - bpiTarget: target, + for (const target of [0, 10, 15, 100]) { + t.test(`Should be able to update the BPI target to ${target}`, async (t) => { + const res = await mockApi + .patch("/api/v1/users/1/games/iidx/SP/settings") + .set("Authorization", "Bearer api_token") + .send({ + gameSpecific: { + bpiTarget: target, + }, + }); + + t.equal(res.statusCode, 200); + + t.strictSame( + res.body.body, + { + userID: 1, + game: "iidx", + playtype: "SP", + preferences: { + preferredScoreAlg: null, + preferredSessionAlg: null, + preferredProfileAlg: null, + scoreBucket: null, + stats: [], + gameSpecific: { + display2DXTra: false, + bpiTarget: target, + }, + }, }, - }); + "Should only update the mutated properties." + ); - t.equal(res.statusCode, 200); - - t.strictSame( - res.body.body, - { + const data = await db["game-settings"].findOne({ userID: 1, game: "iidx", playtype: "SP", - preferences: { - preferredScoreAlg: null, - preferredSessionAlg: null, - preferredProfileAlg: null, - scoreBucket: null, - stats: [], - gameSpecific: { - display2DXTra: false, - bpiTarget: target, - }, - }, - }, - "Should only update the mutated properties." - ); + }); - const data = await db["game-settings"].findOne({ - userID: 1, - game: "iidx", - playtype: "SP", - }); - - t.equal(data?.preferences.gameSpecific.bpiTarget, target); - }; - - for (const target of [0, 10, 15, 100]) { - t.test(`Should be able to update the BPI target to ${target}`, async (t) => { - await f(target); + t.equal(data?.preferences.gameSpecific.bpiTarget, target); t.end(); }); From 367f8a69301b3dcb69bc2e6c66546e4bac48bae0 Mon Sep 17 00:00:00 2001 From: zkldi <20380519+zkldi@users.noreply.github.com> Date: Sat, 22 Jan 2022 12:35:23 +0000 Subject: [PATCH 8/8] whoops --- server/src/lib/game-settings/create-game-settings.ts | 1 + .../users/_userID/games/_game/_playtype/showcase/router.test.ts | 2 ++ 2 files changed, 3 insertions(+) diff --git a/server/src/lib/game-settings/create-game-settings.ts b/server/src/lib/game-settings/create-game-settings.ts index 1d9d61e66..d21e533ce 100644 --- a/server/src/lib/game-settings/create-game-settings.ts +++ b/server/src/lib/game-settings/create-game-settings.ts @@ -30,6 +30,7 @@ export async function CreateGameSettings(userID: integer, game: Game, playtype: if (game === "iidx") { gameSpecific = { display2DXTra: false, + bpiTarget: 0, }; } diff --git a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/showcase/router.test.ts b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/showcase/router.test.ts index 2f4de811c..4d1283e11 100644 --- a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/showcase/router.test.ts +++ b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/showcase/router.test.ts @@ -37,6 +37,7 @@ const SetFolders = async () => { ], gameSpecific: { display2DXTra: false, + bpiTarget: 0, }, }, }); @@ -94,6 +95,7 @@ t.test("GET /api/v1/users/:userID/games/:game/:playtype/showcase", (t) => { ], gameSpecific: { display2DXTra: false, + bpiTarget: 0, }, }, });