diff --git a/server/src/lib/score-import/import-types/api/arc-ddr/converter.test.ts b/server/src/lib/score-import/import-types/api/arc-ddr/converter.test.ts deleted file mode 100644 index 3c3bd794d..000000000 --- a/server/src/lib/score-import/import-types/api/arc-ddr/converter.test.ts +++ /dev/null @@ -1,108 +0,0 @@ -import t from "tap"; -import { CloseAllConnections } from "test-utils/close-connections"; -import ResetDBState from "test-utils/resets"; -import { GetKTDataJSON } from "test-utils/test-data"; -import CreateLogCtx from "lib/logger/logger"; -import { ConvertAPIArcDDR, ResolveARCDDRLamp } from "./converter"; -import { ARCDDRScore } from "./types"; -import deepmerge from "deepmerge"; - -const logger = CreateLogCtx(__filename); - -const arcScore = GetKTDataJSON("./api-arc/ddr-score.json") as ARCDDRScore; -const putySong = GetKTDataJSON("./tachi/ddr-puty-song.json") as ARCDDRScore; -const putyChart = GetKTDataJSON("./tachi/ddr-puty-chart.json") as ARCDDRScore; - -t.test("#ConvertAPIArcDDR", (t) => { - t.beforeEach(ResetDBState); - - t.test("Should convert a valid score", async (t) => { - const res = await ConvertAPIArcDDR(arcScore, {}, "api/arc-ddr", logger); - - t.hasStrict(res, { - song: putySong, - chart: putyChart, - dryScore: { - comment: null, - game: "ddr", - importType: "api/arc-ddr", - timeAchieved: 1591822550346, - service: "ARC DDR Ace", - scoreData: { - grade: "AAA", - percent: 99.976, - score: 999760, - judgements: { - marvelous: 236, - perfect: 24, - great: 0, - good: 0, - boo: 0, - miss: 0, - ok: 17, - ng: 0, - }, - hitMeta: { - fast: 10, - slow: 14, - maxCombo: 260, - }, - lamp: "PERFECT FULL COMBO", - }, - scoreMeta: {}, - }, - }); - - t.end(); - }); - - t.test("Should throw on an invalid score", (t) => { - t.rejects( - () => - ConvertAPIArcDDR( - deepmerge(arcScore, { ex_score: "foo" }), - {}, - "api/arc-ddr", - logger - ), - { - message: /Invalid ARC Score:/iu, - } - ); - - t.end(); - }); - - t.test("Should throw on no chart", (t) => { - t.rejects( - () => - ConvertAPIArcDDR( - deepmerge(arcScore, { chart_id: "foo" }), - {}, - "api/arc-ddr", - logger - ), - { - message: /Could not find chart/iu, - } - ); - - t.end(); - }); - - t.end(); -}); - -t.test("#ResolveARCDDRLamp", (t) => { - t.equal(ResolveARCDDRLamp("FAIL"), "FAILED"); - t.equal(ResolveARCDDRLamp("CLEAR"), "CLEAR"); - t.equal(ResolveARCDDRLamp("CLEAR_3LIFE"), "LIFE4"); - t.equal(ResolveARCDDRLamp("GOOD_FC"), "FULL COMBO"); - t.equal(ResolveARCDDRLamp("GREAT_FC"), "GREAT FULL COMBO"); - t.equal(ResolveARCDDRLamp("PERFECT_FC"), "PERFECT FULL COMBO"); - t.equal(ResolveARCDDRLamp("MARVELOUS_FC"), "MARVELOUS FULL COMBO"); - - t.end(); -}); - -t.teardown(CloseAllConnections); diff --git a/server/src/lib/score-import/import-types/api/arc-ddr/converter.ts b/server/src/lib/score-import/import-types/api/arc-ddr/converter.ts deleted file mode 100644 index 31a23d78a..000000000 --- a/server/src/lib/score-import/import-types/api/arc-ddr/converter.ts +++ /dev/null @@ -1,137 +0,0 @@ -import { EmptyObject } from "utils/types"; -import { ConverterFunction } from "../../common/types"; -import p, { PrudenceSchema } from "prudence"; -import { - InvalidScoreFailure, - KTDataNotFoundFailure, -} from "../../../framework/common/converter-failures"; -import { FormatPrError } from "utils/prudence"; -import { ARCDDRScore } from "./types"; -import { FindChartOnARCID } from "utils/queries/charts"; -import { FindSongOnIDGuaranteed } from "utils/queries/songs"; -import { DryScore } from "../../../framework/common/types"; -import { - GenericGetGradeAndPercent, - ParseDateFromString, -} from "../../../framework/common/score-utils"; -import { Lamps } from "tachi-common"; - -// There's a bunch of other useless fields but we don't care -const PR_ArcDDRScore: PrudenceSchema = { - chart_id: "string", - lamp: p.isIn( - "MARVELOUS_FC", - "PERFECT_FC", - "GREAT_FC", - "GOOD_FC", - "CLEAR_3LIFE", - "CLEAR", - "FAIL" - ), - score: p.isBoundedInteger(0, 1_000_000), - ex_score: p.isPositiveInteger, - max_combo: p.isPositiveInteger, - judgments: { - marvelous: p.isPositiveInteger, - perfect: p.isPositiveInteger, - great: p.isPositiveInteger, - good: p.isPositiveInteger, - boo: p.isPositiveInteger, - miss: p.isPositiveInteger, - ok: p.isPositiveInteger, - ng: p.isPositiveInteger, - }, - fast: p.isPositiveInteger, - slow: p.isPositiveInteger, - timestamp: "string", -}; - -export const ConvertAPIArcDDR: ConverterFunction = async ( - data, - context, - importType, - logger -) => { - const err = p(data, PR_ArcDDRScore, {}, { throwOnNonObject: false, allowExcessKeys: true }); - - if (err) { - throw new InvalidScoreFailure(FormatPrError(err, "Invalid ARC Score: ")); - } - - // confirmed by Prudence above. - const score = data as ARCDDRScore; - - const chart = await FindChartOnARCID("ddr", score.chart_id); - - if (!chart) { - throw new KTDataNotFoundFailure( - `Could not find chart with chart_id ${score.chart_id}.`, - importType, - data, - context - ); - } - - const song = await FindSongOnIDGuaranteed("ddr", chart.songID, logger); - - const { grade, percent } = GenericGetGradeAndPercent("ddr", score.score, chart); - - const timeAchieved = ParseDateFromString(score.timestamp); - - const lamp = ResolveARCDDRLamp(score.lamp); - - const dryScore: DryScore<"ddr:SP" | "ddr:DP"> = { - comment: null, - game: "ddr", - importType, - timeAchieved, - service: "ARC DDR Ace", - scoreData: { - grade, - percent, - score: score.score, - judgements: { - marvelous: score.judgments.marvelous, - perfect: score.judgments.perfect, - great: score.judgments.great, - good: score.judgments.good, - boo: score.judgments.boo, - miss: score.judgments.miss, - ok: score.judgments.ok, - ng: score.judgments.ng, - }, - hitMeta: { - fast: score.fast, - slow: score.slow, - maxCombo: score.max_combo, - }, - lamp, - }, - scoreMeta: {}, - }; - - return { song, chart, dryScore }; -}; - -export function ResolveARCDDRLamp(lamp: ARCDDRScore["lamp"]): Lamps["ddr:SP" | "ddr:DP"] { - switch (lamp) { - case "FAIL": - return "FAILED"; - case "CLEAR": - return "CLEAR"; - case "CLEAR_3LIFE": - return "LIFE4"; - case "GOOD_FC": - return "FULL COMBO"; - case "GREAT_FC": - return "GREAT FULL COMBO"; - case "PERFECT_FC": - return "PERFECT FULL COMBO"; - case "MARVELOUS_FC": - return "MARVELOUS FULL COMBO"; - } - - // failsafe - /* istanbul ignore next */ - throw new InvalidScoreFailure(`Invalid lamp ${lamp} - Could not resolve.`); -} diff --git a/server/src/lib/score-import/import-types/api/arc-ddr/parser.test.ts b/server/src/lib/score-import/import-types/api/arc-ddr/parser.test.ts deleted file mode 100644 index 49665ac20..000000000 --- a/server/src/lib/score-import/import-types/api/arc-ddr/parser.test.ts +++ /dev/null @@ -1,71 +0,0 @@ -import t from "tap"; -import { CloseAllConnections } from "test-utils/close-connections"; -import { agta } from "test-utils/misc"; -import { MockJSONFetch } from "test-utils/mock-fetch"; -import ResetDBState from "test-utils/resets"; -import CreateLogCtx from "lib/logger/logger"; -import { ParseArcDDR } from "./parser"; -import db from "external/mongo/db"; - -const logger = CreateLogCtx(__filename); - -t.test("#ParseArcDDR", (t) => { - t.beforeEach(ResetDBState); - - const mockArcAPI = MockJSONFetch({ - "https://arc.example.com/api/v1/ddr/16/player_bests?profile_id=profile": { - _links: { - _next: "https://arc.example.com/api/v1/ddr/16/player_bests?profile_id=profile&page=2", - }, - _items: [1, 2, 3], - }, - "https://arc.example.com/api/v1/ddr/16/player_bests?profile_id=profile&page=2": { - _links: { - _next: null, - }, - _items: [4, 5, 6], - }, - }); - - t.test("Should iterate over the API.", async (t) => { - await db["arc-saved-profiles"].insert({ - userID: 1, - accountID: "profile", - forImportType: "api/arc-ddr", - }); - - const res = await ParseArcDDR(1, logger, mockArcAPI); - - t.equal(res.game, "ddr"); - t.strictSame(res.context, {}); - t.equal(res.classHandler, null); - - const iter = await agta(res.iterable); - - t.strictSame(iter, [1, 2, 3, 4, 5, 6]); - - t.end(); - }); - - t.test("Should throw a fatal error if no saved profile exists for this user.", async (t) => { - t.rejects(() => ParseArcDDR(1, logger, mockArcAPI), { - message: /No authentication was stored for api\/arc-ddr/iu, - }); - - await db["arc-saved-profiles"].insert({ - userID: 1, - accountID: "profile", - forImportType: "api/arc-sdvx", - }); - - t.rejects(() => ParseArcDDR(1, logger, mockArcAPI), { - message: /No authentication was stored for api\/arc-ddr/iu, - }); - - t.end(); - }); - - t.end(); -}); - -t.teardown(CloseAllConnections); diff --git a/server/src/lib/score-import/import-types/api/arc-ddr/parser.ts b/server/src/lib/score-import/import-types/api/arc-ddr/parser.ts deleted file mode 100644 index 067fec233..000000000 --- a/server/src/lib/score-import/import-types/api/arc-ddr/parser.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { KtLogger } from "lib/logger/logger"; -import nodeFetch from "utils/fetch"; -import { TraverseKaiAPI } from "../../common/api-kai/traverse-api"; -import { ParserFunctionReturns } from "../../common/types"; -import { EmptyObject } from "utils/types"; -import { ServerConfig } from "lib/setup/config"; -import { integer } from "tachi-common"; -import { GetArcAuthGuaranteed } from "utils/queries/auth"; - -export async function ParseArcDDR( - userID: integer, - logger: KtLogger, - fetch = nodeFetch -): Promise> { - const authDoc = await GetArcAuthGuaranteed(userID, "api/arc-ddr", logger); - - return { - iterable: TraverseKaiAPI( - ServerConfig.ARC_API_URL, - // DDR Ace. - `/api/v1/ddr/16/player_bests?profile_id=${authDoc.accountID}`, - ServerConfig.ARC_AUTH_TOKEN, - logger, - null, - fetch - ), - context: {}, - classHandler: null, - game: "ddr", - }; -} diff --git a/server/src/lib/score-import/import-types/api/arc-ddr/types.ts b/server/src/lib/score-import/import-types/api/arc-ddr/types.ts deleted file mode 100644 index b34476c03..000000000 --- a/server/src/lib/score-import/import-types/api/arc-ddr/types.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { integer } from "tachi-common"; - -export interface ARCDDRScore { - chart_id: string; - lamp: "MARVELOUS_FC" | "PERFECT_FC" | "GREAT_FC" | "GOOD_FC" | "CLEAR_3LIFE" | "CLEAR" | "FAIL"; - score: integer; - ex_score: integer; - max_combo: integer; - judgments: { - marvelous: integer; - perfect: integer; - great: integer; - good: integer; - boo: integer; - miss: integer; - ok: integer; - ng: integer; - }; - fast: integer; - slow: integer; - timestamp: string; -}