diff --git a/tests/unit/platforms/modrinth/modrinth-uploader.spec.ts b/tests/unit/platforms/modrinth/modrinth-uploader.spec.ts new file mode 100644 index 0000000..f0b8156 --- /dev/null +++ b/tests/unit/platforms/modrinth/modrinth-uploader.spec.ts @@ -0,0 +1,132 @@ +import { resolve } from "node:path"; +import { readFileSync } from "node:fs"; +import mockFs from "mock-fs"; +import { createFakeFetch } from "../../../utils/fetch-utils"; +import { SecureString } from "@/utils/security/secure-string"; +import { PlatformType } from "@/platforms/platform-type"; +import { FileInfo } from "@/utils/io/file-info"; +import { HttpResponse } from "@/utils/net/http-response"; +import { FormData } from "@/utils/net/form-data"; +import { VersionType } from "@/utils/versioning/version-type"; +import { parseDependency } from "@/dependencies/dependency"; +import { JavaVersion } from "@/utils/java/java-version"; +import { ModrinthUnfeatureMode } from "@/platforms/modrinth/modrinth-unfeature-mode"; +import { ModrinthVersionInit } from "@/platforms/modrinth/modrinth-version"; +import { MODRINTH_API_URL } from "@/platforms/modrinth/modrinth-api-client"; +import { ModrinthUploader } from "@/platforms/modrinth/modrinth-uploader"; + +const DB = Object.freeze({ + loaders: Object.freeze(JSON.parse( + readFileSync(resolve(__dirname, "../../../content/modrinth/loader.json"), "utf8") + )), + + gameVersions: Object.freeze(JSON.parse( + readFileSync(resolve(__dirname, "../../../content/modrinth/game_version.json"), "utf8") + )), +}); + +const MODRINTH_FETCH = createFakeFetch({ + baseUrl: MODRINTH_API_URL, + requiredHeaders: ["Authorization"], + + GET: { + "^\\/tag\\/loader": () => DB.loaders, + + "^\\/tag\\/game_version": () => DB.gameVersions, + + "^\\/project\\/foo$": () => ({ + id: "AAAAAAAA", + slug: "foo", + project_type: "mod", + }), + + "^\\/project\\/AAAAAAAA\\/version\\?featured=true": () => HttpResponse.json([]), + + "^\\/project\\/fabric-api\\/check$": () => ({ + id: "P7dR8mSH", + }), + }, + + POST: { + "^\\/version$": (_, { body }) => { + const formData = body as FormData; + const data = JSON.parse(formData.get("data") as string) as ModrinthVersionInit; + + expect(data.changelog).toBe("Changelog"); + expect(data.featured).toBe(true); + expect(data.name).toBe("Version v1.0.0"); + expect(data.project_id).toBe("AAAAAAAA"); + expect(data.version_number).toBe("1.0.0"); + expect(data.version_type).toBe(VersionType.ALPHA); + expect(data["primary_file"]).toBe("_0"); + expect(data["file_parts"]).toEqual(["_0"]); + expect(data.loaders).toEqual(["fabric"]); + expect(data.game_versions).toEqual(["1.18.2"]); + expect(data.dependencies).toContainEqual({ project_id: "P7dR8mSH", dependency_type: "required" }); + + expect(formData.get("_0")).toHaveProperty("name", "file.txt"); + + return { + id: "BBBBBBBB", + ...data, + files: [{ + filename: "file.txt", + url: "https://cdn.modrinth.com/data/AAAAAAAA/versions/BBBBBBBB/file.txt", + hashes: { sha1: "sha1" }, + }], + }; + }, + }, +}); + +beforeEach(() => { + mockFs({ + "file.txt": "", + }); +}); + +afterEach(() => { + mockFs.restore(); +}); + +describe("ModrinthUploader", () => { + describe("platform", () => { + test("returns `PlatformType.MODRINTH`", () => { + const uploader = new ModrinthUploader(); + + expect(uploader.platform).toBe(PlatformType.MODRINTH); + }); + }); + + describe("upload", () => { + test("fulfills the specified upload request", async () => { + const uploader = new ModrinthUploader({ fetch: MODRINTH_FETCH }); + + const report = await uploader.upload({ + token: SecureString.from("token"), + id: "foo", + name: "Version v1.0.0", + version: "1.0.0", + versionType: VersionType.ALPHA, + changelog: "Changelog", + files: [FileInfo.of("file.txt")], + dependencies: [parseDependency("fabric-api@0.75.0(required)")], + gameVersions: ["1.18.2"], + loaders: ["fabric", "unknown"], + java: [JavaVersion.of(17)], + unfeatureMode: ModrinthUnfeatureMode.ANY, + }); + + expect(report).toEqual({ + id: "AAAAAAAA", + version: "BBBBBBBB", + url: "https://modrinth.com/mod/foo/version/1.0.0", + files: [{ + id: "sha1", + name: "file.txt", + url: "https://cdn.modrinth.com/data/AAAAAAAA/versions/BBBBBBBB/file.txt", + }], + }); + }); + }); +});