From 1ded3899b0307e3d37ae14ae41985b1e3f9f7f48 Mon Sep 17 00:00:00 2001 From: Sander Declerck Date: Tue, 21 Oct 2025 14:56:46 +0200 Subject: [PATCH] Commit new tests --- packages/safe-chain/src/api/npmApi.spec.js | 211 +++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 packages/safe-chain/src/api/npmApi.spec.js diff --git a/packages/safe-chain/src/api/npmApi.spec.js b/packages/safe-chain/src/api/npmApi.spec.js new file mode 100644 index 0000000..0c7585d --- /dev/null +++ b/packages/safe-chain/src/api/npmApi.spec.js @@ -0,0 +1,211 @@ +import { describe, it, mock } from "node:test"; +import assert from "node:assert"; + +describe("resolvePackageVersion", async () => { + const mockNpmFetchJson = mock.fn(); + + mock.module("npm-registry-fetch", { + namedExports: { + json: mockNpmFetchJson, + }, + }); + + const { resolvePackageVersion } = await import("./npmApi.js"); + + it("should return the version if it is already a fixed version", async () => { + const result = await resolvePackageVersion("express", "4.17.1"); + + assert.strictEqual(result, "4.17.1"); + }); + + it("should use 'latest' as default version range when not provided", async () => { + mockNpmFetchJson.mock.mockImplementationOnce(() => ({ + "dist-tags": { + latest: "4.18.2", + }, + versions: { + "4.18.2": {}, + }, + })); + + const result = await resolvePackageVersion("express"); + + assert.strictEqual(result, "4.18.2"); + }); + + it("should resolve dist-tag versions", async () => { + mockNpmFetchJson.mock.mockImplementationOnce(() => ({ + "dist-tags": { + latest: "4.18.2", + next: "5.0.0-beta.1", + }, + versions: { + "4.18.2": {}, + "5.0.0-beta.1": {}, + }, + })); + + const result = await resolvePackageVersion("express", "next"); + + assert.strictEqual(result, "5.0.0-beta.1"); + }); + + it("should resolve version ranges using semver", async () => { + mockNpmFetchJson.mock.mockImplementationOnce(() => ({ + "dist-tags": { + latest: "4.18.2", + }, + versions: { + "4.16.0": {}, + "4.17.0": {}, + "4.17.1": {}, + "4.18.0": {}, + "4.18.2": {}, + }, + })); + + const result = await resolvePackageVersion("express", "^4.17.0"); + + assert.strictEqual(result, "4.18.2"); + }); + + it("should resolve tilde ranges correctly", async () => { + mockNpmFetchJson.mock.mockImplementationOnce(() => ({ + "dist-tags": { + latest: "4.18.2", + }, + versions: { + "4.17.0": {}, + "4.17.1": {}, + "4.17.3": {}, + "4.18.0": {}, + }, + })); + + const result = await resolvePackageVersion("express", "~4.17.0"); + + assert.strictEqual(result, "4.17.3"); + }); + + it("should return null if package info cannot be fetched", async () => { + mockNpmFetchJson.mock.mockImplementationOnce(() => { + throw new Error("Package not found"); + }); + + const result = await resolvePackageVersion("non-existent-package", "latest"); + + assert.strictEqual(result, null); + }); + + it("should return null if no versions match the range", async () => { + mockNpmFetchJson.mock.mockImplementationOnce(() => ({ + "dist-tags": { + latest: "1.0.0", + }, + versions: { + "1.0.0": {}, + "1.1.0": {}, + }, + })); + + const result = await resolvePackageVersion("express", "^5.0.0"); + + assert.strictEqual(result, null); + }); + + it("should return null if dist-tag does not exist", async () => { + mockNpmFetchJson.mock.mockImplementationOnce(() => ({ + "dist-tags": { + latest: "4.18.2", + }, + versions: { + "4.18.2": {}, + }, + })); + + const result = await resolvePackageVersion("express", "nonexistent-tag"); + + assert.strictEqual(result, null); + }); + + it("should return null if package info has no versions property (retracted package)", async () => { + mockNpmFetchJson.mock.mockImplementationOnce(() => ({ + _id: "zenn", + name: "zenn", + time: { + modified: "2021-04-20T16:20:56.084Z", + created: "2017-07-10T19:48:07.891Z", + unpublished: { + time: "2021-04-20T16:20:56.084Z", + versions: [ + "0.9.0", + "0.9.1", + "0.9.2", + "0.9.3", + "0.9.4", + "0.9.5", + "0.9.6", + "0.9.8", + "0.9.9", + "0.9.10", + "0.9.11", + "0.9.12", + "0.9.13", + "0.9.14", + ], + }, + }, + })); + + const result = await resolvePackageVersion("zenn", "^0.9.0"); + + assert.strictEqual(result, null); + }); + + it("should return dist-tag version even if versions property is missing", async () => { + mockNpmFetchJson.mock.mockImplementationOnce(() => ({ + "dist-tags": { + latest: "4.18.2", + }, + })); + + const result = await resolvePackageVersion("express", "latest"); + + assert.strictEqual(result, "4.18.2"); + }); + + it("should handle scoped packages", async () => { + mockNpmFetchJson.mock.mockImplementationOnce(() => ({ + "dist-tags": { + latest: "1.2.3", + }, + versions: { + "1.2.3": {}, + }, + })); + + const result = await resolvePackageVersion("@scope/package", "latest"); + + assert.strictEqual(result, "1.2.3"); + }); + + it("should handle complex version ranges", async () => { + mockNpmFetchJson.mock.mockImplementationOnce(() => ({ + "dist-tags": { + latest: "2.5.0", + }, + versions: { + "1.0.0": {}, + "2.0.0": {}, + "2.3.0": {}, + "2.4.0": {}, + "2.5.0": {}, + "3.0.0": {}, + }, + })); + + const result = await resolvePackageVersion("express", ">=2.0.0 <3.0.0"); + + assert.strictEqual(result, "2.5.0"); + }); +});