diff --git a/common/src/lib/schemas.ts b/common/src/lib/schemas.ts index 0dac73b76..99b99d009 100644 --- a/common/src/lib/schemas.ts +++ b/common/src/lib/schemas.ts @@ -633,6 +633,8 @@ const PRE_SCHEMAS = { game: p.isIn(games), playtype: isValidPlaytype, quests: ["string"], + name: "string", + desc: "string", }), quests: prSchemaFnWrap({ game: p.isIn(games), diff --git a/docs/docs/tachi-server/implementation-details/goals-quests.md b/docs/docs/tachi-server/implementation-details/goals-quests.md index 0eeb81b0a..038d7eaca 100644 --- a/docs/docs/tachi-server/implementation-details/goals-quests.md +++ b/docs/docs/tachi-server/implementation-details/goals-quests.md @@ -117,4 +117,4 @@ an empty array as a result of this process. Questline are ordered lists of quests. Their purpose is to group quests together visually. -Users *can not* "subscribe" to quest sets, but they can use sets as a utility for subscribing to all the related quests. +Users *can not* "subscribe" to questlines, but they can use questlines as a utility for subscribing to all the related quests. diff --git a/server/src/lib/score-import/framework/goals/goals.test.ts b/server/src/lib/score-import/framework/goals/goals.test.ts index baa1c44ca..2e79ffae9 100644 --- a/server/src/lib/score-import/framework/goals/goals.test.ts +++ b/server/src/lib/score-import/framework/goals/goals.test.ts @@ -77,7 +77,7 @@ t.test("#UpdateGoalsForUser", (t) => { }, new: { progress: 1479, - progressHuman: "1479", + progressHuman: "1,479", outOf: 1, outOfHuman: "1", achieved: true, @@ -91,7 +91,7 @@ t.test("#UpdateGoalsForUser", (t) => { r, { progress: 1479, - progressHuman: "1479", + progressHuman: "1,479", outOf: 1, outOfHuman: "1", achieved: true, diff --git a/server/src/lib/score-import/framework/quests/quests.test.ts b/server/src/lib/score-import/framework/quests/quests.test.ts index cbff4e1a0..66e8e1db7 100644 --- a/server/src/lib/score-import/framework/quests/quests.test.ts +++ b/server/src/lib/score-import/framework/quests/quests.test.ts @@ -31,7 +31,6 @@ t.test("#UpdateUsersQuests", (t) => { timeAchieved: null, lastInteraction: null, userID: 1, - wasAssignedStandalone: false, }) ); @@ -165,7 +164,6 @@ t.test("#UpdateUsersQuests", (t) => { timeAchieved: null, lastInteraction: null, userID: 1, - wasAssignedStandalone: false, }); const res = await UpdateUsersQuests( @@ -276,7 +274,6 @@ t.test("#UpdateUsersQuests", (t) => { timeAchieved: null, lastInteraction: null, userID: 1, - wasAssignedStandalone: false, }, { achieved: false, @@ -289,7 +286,6 @@ t.test("#UpdateUsersQuests", (t) => { timeAchieved: null, lastInteraction: null, userID: 1, - wasAssignedStandalone: false, }, { achieved: false, @@ -302,7 +298,6 @@ t.test("#UpdateUsersQuests", (t) => { timeAchieved: null, lastInteraction: null, userID: 1, - wasAssignedStandalone: false, }, { achieved: false, @@ -314,7 +309,6 @@ t.test("#UpdateUsersQuests", (t) => { timeAchieved: null, lastInteraction: null, userID: 1, - wasAssignedStandalone: false, }, ]); diff --git a/server/src/server/router/api/v1/games/_game/_playtype/targets/goals/router.test.ts b/server/src/server/router/api/v1/games/_game/_playtype/targets/goals/router.test.ts index eba969926..beda02ae7 100644 --- a/server/src/server/router/api/v1/games/_game/_playtype/targets/goals/router.test.ts +++ b/server/src/server/router/api/v1/games/_game/_playtype/targets/goals/router.test.ts @@ -96,52 +96,3 @@ t.test("GET /api/v1/games/:game/:playtype/targets/goals/:goalID", (t) => { t.end(); }); - -t.test("GET /api/v1/games/:game/:playtype/targets/goals/:goalID/evaluate-for", (t) => { - t.beforeEach(ResetDBState); - t.beforeEach(LoadLazySampleData); - - t.test("Should evaluate a goal upon a user that exists.", async (t) => { - const res = await mockApi.get( - "/api/v1/games/iidx/SP/targets/goals/eg_goal_1/evaluate-for?userID=1" - ); - - t.equal(res.statusCode, 200, "Should return a status code of 200."); - - t.strictSame( - res.body.body, - { - achieved: false, - outOf: 5, - outOfHuman: "HARD CLEAR", - progress: null, - progressHuman: "NO DATA", - }, - "Should evaluate the goal for the user." - ); - - t.end(); - }); - - t.test("Should return 404 if the user doesn't exist.", async (t) => { - const res = await mockApi.get( - "/api/v1/games/iidx/SP/targets/goals/eg_goal_1/evaluate-for?userID=unknown" - ); - - t.equal(res.statusCode, 404); - - t.end(); - }); - - t.test("Should return 400 if the user exists but hasn't played this game.", async (t) => { - const res = await mockApi.get( - "/api/v1/games/iidx/SP/targets/goals/eg_goal_1/evaluate-for?userID=2" - ); - - t.equal(res.statusCode, 400); - - t.end(); - }); - - t.end(); -}); diff --git a/server/src/server/router/api/v1/games/_game/_playtype/targets/goals/router.ts b/server/src/server/router/api/v1/games/_game/_playtype/targets/goals/router.ts index 73269aa5b..96c87bb07 100644 --- a/server/src/server/router/api/v1/games/_game/_playtype/targets/goals/router.ts +++ b/server/src/server/router/api/v1/games/_game/_playtype/targets/goals/router.ts @@ -2,15 +2,13 @@ import { Router } from "express"; import db from "external/mongo/db"; import CreateLogCtx from "lib/logger/logger"; import { CreateGoalTitle, ValidateGoalChartsAndCriteria } from "lib/targets/goal-utils"; -import { EvaluateGoalForUser, GetQuestsThatContainGoal } from "lib/targets/goals"; +import { GetQuestsThatContainGoal } from "lib/targets/goals"; import p from "prudence"; import prValidate from "server/middleware/prudence-validate"; -import { FormatGame } from "tachi-common"; import { GetMostSubscribedGoals } from "utils/db"; import { AssignToReqTachiData, GetGPT, GetTachiData } from "utils/req-tachi-data"; -import { GetUsersWithIDs, ResolveUser } from "utils/user"; +import { GetUsersWithIDs } from "utils/user"; import type { RequestHandler } from "express"; -import type { EvaluatedGoalReturn } from "lib/targets/goals"; import type { GoalDocument } from "tachi-common"; const logger = CreateLogCtx(__filename); @@ -181,87 +179,4 @@ router.get("/:goalID", ResolveGoalID, async (req, res) => { }); }); -/** - * Evaluates a goal upon a user, even if they aren't subscribed to it. - * - * @param userID - The userID to evaluate this goal against. Must be a player of this GPT. - * - * @name GET /api/v1/games/:game/:playtype/targets/goals/:goalID/evaluate-for - */ -router.get( - "/:goalID/evaluate-for", - ResolveGoalID, - prValidate({ - userID: "string", - }), - async (req, res) => { - const { game, playtype } = GetGPT(req); - - const userID = req.query.userID as string; - - const user = await ResolveUser(userID); - - if (!user) { - return res.status(404).json({ - success: false, - description: `The user ${userID} does not exist.`, - }); - } - - const hasPlayed = await db["game-stats"].findOne({ - game, - playtype, - userID: user.id, - }); - - if (!hasPlayed) { - return res.status(400).json({ - success: false, - description: `The user ${user.username} hasn't played ${FormatGame( - game, - playtype - )}.`, - }); - } - - const goal = GetTachiData(req, "goalDoc"); - const goalID = goal.goalID; - - const goalSub = await db["goal-subs"].findOne({ - userID: user.id, - goalID, - }); - - let goalResults: EvaluatedGoalReturn; - - // shortcut evaluation by using the user goal - - if (goalSub) { - goalResults = { - achieved: goalSub.achieved, - outOf: goalSub.outOf, - outOfHuman: goalSub.outOfHuman, - progress: goalSub.progress, - progressHuman: goalSub.progressHuman, - }; - } else { - const results = await EvaluateGoalForUser(goal, user.id, logger); - - if (!results) { - throw new Error( - `Failed to evaluate goal ${goal.name} (${goal.goalID}) for user ${user.id}. More information above.` - ); - } - - goalResults = results; - } - - return res.status(200).json({ - success: true, - description: `Evaluated ${goal.name} for ${user.username}.`, - body: goalResults, - }); - } -); - export default router; diff --git a/server/src/server/router/api/v1/games/_game/_playtype/targets/questlines/router.test.ts b/server/src/server/router/api/v1/games/_game/_playtype/targets/questlines/router.test.ts index a2a1410be..1bf87cec9 100644 --- a/server/src/server/router/api/v1/games/_game/_playtype/targets/questlines/router.test.ts +++ b/server/src/server/router/api/v1/games/_game/_playtype/targets/questlines/router.test.ts @@ -7,7 +7,7 @@ import { TestingIIDXSPQuest } from "test-utils/test-data"; import type { QuestDocument, QuestlineDocument } from "tachi-common"; const TestingIIDXSPQuestline: QuestlineDocument = { - name: "Testing Quest Set", + name: "Testing Questline", desc: "foo", game: "iidx", quests: [TestingIIDXSPQuest.questID, "other_quest"], @@ -22,7 +22,7 @@ t.test("GET /api/v1/games/:game/:playtype/targets/questlines", (t) => { return dm(TestingIIDXSPQuestline, merge) as QuestlineDocument; } - t.test("Should search the loaded quest sets for this game.", async (t) => { + t.test("Should return all questlines for this game.", async (t) => { await db.questlines.insert([ mkSet({ name: "Testing Set", questlineID: "name" }), mkSet({ name: "Testing Other Set", questlineID: "similar_name" }), @@ -35,22 +35,18 @@ t.test("GET /api/v1/games/:game/:playtype/targets/questlines", (t) => { mkSet({ playtype: "DP", questlineID: "matching name but different playtype" }), ]); - const res = await mockApi.get("/api/v1/games/iidx/SP/targets/questlines?search=Testing"); - - t.hasStrict( - (res.body.body as Array).sort((a, b) => - a.name.localeCompare(b.name) - ), - [{ questlineID: "similar_name" }, { questlineID: "name" }] - ); - - t.end(); - }); - - t.test("Should mandate a search field.", async (t) => { const res = await mockApi.get("/api/v1/games/iidx/SP/targets/questlines"); - t.equal(res.statusCode, 400); + t.hasStrict( + (res.body.body.questlines as Array).sort((a, b) => + a.name.localeCompare(b.name) + ), + [ + { questlineID: "radically_different_name" }, + { questlineID: "similar_name" }, + { questlineID: "name" }, + ] + ); t.end(); }); @@ -68,7 +64,7 @@ t.test("GET /api/v1/games/:game/:playtype/targets/questlines/:questlineID", (t) ]); }); - t.test("Should return the quest set and its quests.", async (t) => { + t.test("Should return the questline and its quests.", async (t) => { const res = await mockApi.get("/api/v1/games/iidx/SP/targets/questlines/quest_set"); t.equal(res.statusCode, 200, "Should return 200."); @@ -87,7 +83,7 @@ t.test("GET /api/v1/games/:game/:playtype/targets/questlines/:questlineID", (t) t.end(); }); - t.test("Should return 404 if the quest set doesn't exist.", async (t) => { + t.test("Should return 404 if the questline doesn't exist.", async (t) => { const res = await mockApi.get("/api/v1/games/iidx/SP/targets/questlines/foobar"); t.equal(res.statusCode, 404); diff --git a/server/src/server/router/api/v1/games/_game/_playtype/targets/questlines/router.ts b/server/src/server/router/api/v1/games/_game/_playtype/targets/questlines/router.ts index af5f39026..e6088f502 100644 --- a/server/src/server/router/api/v1/games/_game/_playtype/targets/questlines/router.ts +++ b/server/src/server/router/api/v1/games/_game/_playtype/targets/questlines/router.ts @@ -45,7 +45,7 @@ router.get("/", async (req, res) => { return res.status(200).json({ success: true, - description: `Returned ${questlines.length} quest sets.`, + description: `Returned ${questlines.length} questlines.`, body: { questlines, standalone, standaloneGoals }, }); }); @@ -64,7 +64,7 @@ router.get("/:questlineID", ResolveQuestlineID, async (req, res) => { return res.status(200).json({ success: true, - description: `Retrieved quest set '${questline.name}'.`, + description: `Retrieved questline '${questline.name}'.`, body: { quests, questline, diff --git a/server/src/server/router/api/v1/games/_game/_playtype/targets/quests/router.test.ts b/server/src/server/router/api/v1/games/_game/_playtype/targets/quests/router.test.ts index 5e0624774..6795c44ee 100644 --- a/server/src/server/router/api/v1/games/_game/_playtype/targets/quests/router.test.ts +++ b/server/src/server/router/api/v1/games/_game/_playtype/targets/quests/router.test.ts @@ -9,7 +9,6 @@ import { IIDXSPQuestGoalSubs, TestingIIDXSPQuest, TestingIIDXSPQuestSub, - TestingIIDXSPScorePB, } from "test-utils/test-data"; import type { QuestDocument, QuestlineDocument, QuestSubscriptionDocument } from "tachi-common"; @@ -38,7 +37,9 @@ t.test("GET /api/v1/games/:game/:playtype/targets/quests", (t) => { t.equal(res.statusCode, 200); t.hasStrict( - (res.body.body as Array).sort((a, b) => a.name.localeCompare(b.name)), + (res.body.body.quests as Array).sort((a, b) => + a.name.localeCompare(b.name) + ), [{ questID: "similar_name" }, { questID: "name" }] ); @@ -65,29 +66,6 @@ const LoadLazySampleData = async () => { ] as Array); }; -t.test("GET /api/v1/games/:game/:playtype/targets/quests/popular", (t) => { - t.beforeEach(ResetDBState); - t.beforeEach(LoadLazySampleData); - - t.test("Should return the most subscribed quests for this GPT.", async (t) => { - const res = await mockApi.get("/api/v1/games/iidx/SP/targets/quests/popular"); - - t.equal(res.statusCode, 200); - - t.hasStrict( - (res.body.body as Array).sort((a, b) => a.name.localeCompare(b.name)), - [ - { questID: TestingIIDXSPQuest.questID, __subscriptions: 2 }, - { questID: "other_quest", __subscriptions: 1 }, - ] - ); - - t.end(); - }); - - t.end(); -}); - t.test("GET /api/v1/games/:game/:playtype/targets/quests/:questID", (t) => { t.beforeEach(ResetDBState); t.beforeEach(async () => { @@ -143,121 +121,3 @@ t.test("GET /api/v1/games/:game/:playtype/targets/quests/:questID", (t) => { t.end(); }); - -t.test("GET /api/v1/games/:game/:playtype/targets/quests/:questID/evaluate-for", (t) => { - t.beforeEach(ResetDBState); - t.beforeEach(LoadLazySampleData); - - t.test("Should evaluate a quest for a user.", async (t) => { - // remove all quest subs -- the user isn't properly - // subscribed to this quest due to test mocking. - // this will force a live calc. - await db["quest-subs"].remove({}); - - await db["personal-bests"].insert(TestingIIDXSPScorePB); - - const res = await mockApi.get( - `/api/v1/games/iidx/SP/targets/quests/${TestingIIDXSPQuest.questID}/evaluate-for?userID=1` - ); - - t.equal(res.statusCode, 200); - - t.hasStrict(res.body.body, { - goals: [ - { - goalID: "eg_goal_1", - }, - { - goalID: "eg_goal_2", - }, - { - goalID: "eg_goal_3", - }, - { - goalID: "eg_goal_4", - }, - ], - goalResults: [ - { - achieved: true, - progress: 6, - outOf: 5, - progressHuman: "EX HARD CLEAR (BP: 2)", - outOfHuman: "HARD CLEAR", - goalID: "eg_goal_1", - }, - { - achieved: true, - progress: 6, - outOf: 2, - progressHuman: "EX HARD CLEAR (BP: 2)", - outOfHuman: "ASSIST CLEAR", - goalID: "eg_goal_2", - }, - { - achieved: true, - progress: 1479, - outOf: 300, - outOfHuman: "300", - progressHuman: "1479", - goalID: "eg_goal_3", - }, - { - achieved: true, - progress: 1479, - outOf: 1100, - outOfHuman: "1100", - progressHuman: "1479", - goalID: "eg_goal_4", - }, - ], - achieved: true, - progress: 4, - outOf: 4, - }); - - t.end(); - }); - - t.test("Should return 404 if the requested quest doesn't exist.", async (t) => { - const res = await mockApi.get( - "/api/v1/games/iidx/SP/targets/quests/fake_quest/evaluate-for?userID=1" - ); - - t.equal(res.statusCode, 404); - - t.end(); - }); - - t.test("Should return 404 if the quest exists but for a different GPT.", async (t) => { - const res = await mockApi.get( - `/api/v1/games/iidx/DP/targets/quests/${TestingIIDXSPQuest.questID}/evaluate-for?userID=1` - ); - - t.equal(res.statusCode, 404); - - t.end(); - }); - - t.test("Should return 404 if the requested user doesn't exist.", async (t) => { - const res = await mockApi.get( - `/api/v1/games/iidx/SP/targets/quests/${TestingIIDXSPQuest.questID}/evaluate-for?userID=3` - ); - - t.equal(res.statusCode, 404); - - t.end(); - }); - - t.test("Should return 400 if the requested user hasn't played this gpt.", async (t) => { - const res = await mockApi.get( - `/api/v1/games/iidx/SP/targets/quests/${TestingIIDXSPQuest.questID}/evaluate-for?userID=2` - ); - - t.equal(res.statusCode, 400); - - t.end(); - }); - - t.end(); -}); diff --git a/server/src/server/router/api/v1/games/_game/_playtype/targets/quests/router.ts b/server/src/server/router/api/v1/games/_game/_playtype/targets/quests/router.ts index 932681c98..b8c0235d1 100644 --- a/server/src/server/router/api/v1/games/_game/_playtype/targets/quests/router.ts +++ b/server/src/server/router/api/v1/games/_game/_playtype/targets/quests/router.ts @@ -1,13 +1,10 @@ import { Router } from "express"; import db from "external/mongo/db"; import { SearchCollection } from "lib/search/search"; -import { EvaluateQuestProgress, GetGoalsInQuest, GetGoalsInQuests } from "lib/targets/quests"; -import prValidate from "server/middleware/prudence-validate"; -import { FormatGame } from "tachi-common"; -import { GetMostSubscribedQuests } from "utils/db"; +import { GetGoalsInQuest, GetGoalsInQuests } from "lib/targets/quests"; import { IsString } from "utils/misc"; import { AssignToReqTachiData, GetGPT, GetTachiData } from "utils/req-tachi-data"; -import { GetUsersWithIDs, ResolveUser } from "utils/user"; +import { GetUsersWithIDs } from "utils/user"; import type { RequestHandler } from "express"; const router: Router = Router({ mergeParams: true }); @@ -61,24 +58,6 @@ router.get("/", async (req, res) => { }); }); -/** - * Find the most subscribed-to quests for this GPT. - * - * @name GET /api/v1/games/:game/:playtype/targets/quests/popular - */ -router.get("/popular", async (req, res) => { - const { game, playtype } = GetGPT(req); - - const quests = await GetMostSubscribedQuests({ game, playtype }); - const goals = await GetGoalsInQuests(quests); - - return res.status(200).json({ - success: true, - description: `Returned ${quests.length} popular quests.`, - body: { quests, goals }, - }); -}); - /** * Retrieve information about this quest and who is subscribed to it. * @@ -112,57 +91,4 @@ router.get("/:questID", ResolveQuestID, async (req, res) => { }); }); -/** - * Evaluates a quest upon a user, even if they aren't subscribed to it. - * - * @param userID - The userID to evaluate this goal against. Must be a player of this GPT. - * - * @name GET /api/v1/games/:game/:playtype/targets/quests/:questID/evaluate-for - */ -router.get( - "/:questID/evaluate-for", - ResolveQuestID, - prValidate({ userID: "string" }), - async (req, res) => { - const { game, playtype } = GetGPT(req); - - const userID = req.query.userID as string; - - const user = await ResolveUser(userID); - - if (!user) { - return res.status(404).json({ - success: false, - description: `The user ${userID} does not exist.`, - }); - } - - const hasPlayed = await db["game-stats"].findOne({ - game, - playtype, - userID: user.id, - }); - - if (!hasPlayed) { - return res.status(400).json({ - success: false, - description: `The user ${user.username} hasn't played ${FormatGame( - game, - playtype - )}.`, - }); - } - - const quest = GetTachiData(req, "questDoc"); - - const questProgress = await EvaluateQuestProgress(user.id, quest); - - return res.status(200).json({ - success: true, - description: `Evaluated ${quest.name} for ${user.username}.`, - body: questProgress, - }); - } -); - export default router; diff --git a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/targets/goals/router.test.ts b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/targets/goals/router.test.ts index 3bc88540c..859d9da7a 100644 --- a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/targets/goals/router.test.ts +++ b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/targets/goals/router.test.ts @@ -55,6 +55,8 @@ t.test("GET /api/v1/users/:userID/games/:game/:playtype/targets/goals", (t) => { t.strictSame(res.body.body, { goals: [HC511Goal], goalSubs: [HC511UserGoal], + quests: [], + questSubs: [], }); t.end(); diff --git a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/targets/quests/router.test.ts b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/targets/quests/router.test.ts index 7f5b6878c..d6765efcb 100644 --- a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/targets/quests/router.test.ts +++ b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/targets/quests/router.test.ts @@ -4,6 +4,7 @@ import { CreateFakeAuthCookie } from "test-utils/fake-auth"; import mockApi from "test-utils/mock-api"; import ResetDBState from "test-utils/resets"; import { + HC511Goal, IIDXSPQuestGoals, IIDXSPQuestGoalSubs, TestingIIDXSPQuest, @@ -17,15 +18,21 @@ t.test("GET /api/v1/users/:userID/games/:game/:playtype/targets/quests", (t) => t.test("Should return all quest subscriptions.", async (t) => { await db.quests.insert(TestingIIDXSPQuest); await db["quest-subs"].insert(TestingIIDXSPQuestSub); + await db.goals.insert(IIDXSPQuestGoals); const res = await mockApi.get("/api/v1/users/1/games/iidx/SP/targets/quests"); delete TestingIIDXSPQuest._id; delete TestingIIDXSPQuestSub._id; + for (const goal of IIDXSPQuestGoals) { + delete goal._id; + } + t.strictSame(res.body.body, { quests: [TestingIIDXSPQuest], questSubs: [TestingIIDXSPQuestSub], + goals: IIDXSPQuestGoals, }); t.end(); diff --git a/server/src/test-utils/snapshots/snapshot-data.json b/server/src/test-utils/snapshots/snapshot-data.json index b4c999ae7..db2a24f85 100644 --- a/server/src/test-utils/snapshots/snapshot-data.json +++ b/server/src/test-utils/snapshots/snapshot-data.json @@ -7,7 +7,7 @@ "Invalid Goal: single with countNum": "[criteria.countNum] Invalid countNum for mode 'single'. Must not have one! (Received 123)", "Invalid Goal: nonsense mode": "[criteria.mode] Expected any of single, absolute, proportion. (Received nonsense)", "Invalid Goal: abs with countNum but charts.type == single": "Invalid countNum for goal with criteria.mode of 'absolute'. Expected a whole number less than the total amount of charts available and greater than 1. (Got 1, while total charts was 1.)", - "Invalid Goal: nonsense charts.type": "[charts.type] Expected any of single, multi, folder, any. (Received nonsense)", + "Invalid Goal: nonsense charts.type": "[charts.type] Expected any of single, multi, folder. (Received nonsense)", "Invalid Goal: charts.data when type == any": "[charts.data] Invalid charts.data for type 'any'. Must not have any data! (Received foo)", "Invalid Goal: charts.data array when type == single": "[charts.data] Expected a string in charts.data due to charts.type being 'single'.", "Invalid Goal: charts.data array of identical chartIDs": "Expected charts.data to match 2 charts. Instead, it only matched 1. Are all of these chartIDs valid?", diff --git a/server/src/test-utils/test-data.ts b/server/src/test-utils/test-data.ts index 2faf805eb..14f5d88a9 100644 --- a/server/src/test-utils/test-data.ts +++ b/server/src/test-utils/test-data.ts @@ -666,7 +666,6 @@ export const TestingIIDXSPQuestSub: QuestSubscriptionDocument = { progress: 4, timeAchieved: null, wasInstantlyAchieved: false, - wasAssignedStandalone: false, }; let KTDATA_CACHE: