diff --git a/test/create-integrity-metadata.js b/test/create-integrity-metadata.js new file mode 100644 index 0000000..bd2691e --- /dev/null +++ b/test/create-integrity-metadata.js @@ -0,0 +1,23 @@ +import assert from "node:assert"; +import { test } from "node:test"; +import { createIntegrityMetadata, IntegrityMetadata } from "../dist/index.js"; + +test("instantiate a new IntegrityMetadata", async function () { + const res = new Response("Hello, world!"); + const data = await res.arrayBuffer(); + const integrityMetadata = await createIntegrityMetadata("sha256", data); + + assert(integrityMetadata instanceof IntegrityMetadata); +}); + +test("instantiate with the specified hash algorithm and ArrayBuffer", async function () { + const res = new Response("Hello, world!"); + const data = await res.arrayBuffer(); + const integrityMetadata = await createIntegrityMetadata("sha256", data); + + assert.deepEqual(integrityMetadata, { + alg: "sha256", + val: "MV9b23bQeMQ7isAGTkoBZGErH853yGk0W/yUx1iU7dM=", + opt: [], + }); +}); diff --git a/test/get-prioritized-hash-algorithm.js b/test/get-prioritized-hash-algorithm.js new file mode 100644 index 0000000..a09e2d7 --- /dev/null +++ b/test/get-prioritized-hash-algorithm.js @@ -0,0 +1,34 @@ +import assert from "node:assert/strict"; +import { test } from "node:test"; +import { getPrioritizedHashAlgorithm } from "../dist/index.js"; + +test("return the most collision-resistant hash algorithm", function () { + assert.strictEqual(getPrioritizedHashAlgorithm("sha256", "sha512"), "sha512"); +}); + +test("if the priority is equal, return the empty string", function () { + assert.strictEqual(getPrioritizedHashAlgorithm("sha256", "sha256"), ""); +}); + +test("if both hash algorithms are not supported, return the empty string", function () { + assert.strictEqual(getPrioritizedHashAlgorithm("md5", "sha1"), ""); +}); + +test.todo( + "if one of the hash algorithms is unsupported, return the supported hash algorithm", + function () { + assert.strictEqual(getPrioritizedHashAlgorithm("md5", "sha256"), "sha256"); + }, +); + +test("if both strings are empty, return the empty string", function () { + assert.strictEqual(getPrioritizedHashAlgorithm("", ""), ""); +}); + +test, + todo( + "if either is an empty string, it return the supported hash algorithm", + function () { + assert.strictEqual(getPrioritizedHashAlgorithm("sha256", ""), "sha256"); + }, + ); diff --git a/test/index.js b/test/index.js deleted file mode 100644 index 278b302..0000000 --- a/test/index.js +++ /dev/null @@ -1,39 +0,0 @@ -import assert from "node:assert/strict"; -import { test } from "node:test"; -import { - createIntegrityMetadata, - createIntegrityMetadataSet, - IntegrityMetadataSet, -} from "../dist/index.js"; - -test("createIntegrityMetadata()", async function () { - const res = new Response("Hello, world!"); - const data = await res.arrayBuffer(); - const integrityMetadata = await createIntegrityMetadata("sha256", data); - - assert.strictEqual( - integrityMetadata.toString(), - "sha256-MV9b23bQeMQ7isAGTkoBZGErH853yGk0W/yUx1iU7dM=", - ); -}); - -test("createIntegrityMetadataSet()", async function () { - const res = new Response("Hello, world!"); - const data = await res.arrayBuffer(); - const sri = await createIntegrityMetadataSet(["sha384", "sha512"], data); - - assert.strictEqual( - sri.toString(), - "sha384-VbxVaw0v4Pzlgrpf4Huq//A1ZTY4x6wNVJTCpkwL6hzFczHHwSpFzbyn9MNKCJ7r sha512-wVJ82JPBJHc9gRkRlwyP5uhX1t9dySJr2KFgYUwM2WOk3eorlLt9NgIe+dhl1c6ilKgt1JoLsmn1H256V/eUIQ==", - ); -}); - -test("IntegrityMetadataSet.strongest", async function () { - const { strongest } = new IntegrityMetadataSet(` -sha256-MV9b23bQeMQ7isAGTkoBZGErH853yGk0W/yUx1iU7dM= -sha384-VbxVaw0v4Pzlgrpf4Huq//A1ZTY4x6wNVJTCpkwL6hzFczHHwSpFzbyn9MNKCJ7r -sha512-wVJ82JPBJHc9gRkRlwyP5uhX1t9dySJr2KFgYUwM2WOk3eorlLt9NgIe+dhl1c6ilKgt1JoLsmn1H256V/eUIQ== -`); - - assert.strictEqual(strongest.alg, "sha512"); -}); diff --git a/test/integrity-metadata/constructor.js b/test/integrity-metadata/constructor.js new file mode 100644 index 0000000..89d7dd8 --- /dev/null +++ b/test/integrity-metadata/constructor.js @@ -0,0 +1,112 @@ +import assert from "node:assert"; +import { test } from "node:test"; +import { IntegrityMetadata } from "../../dist/index.js"; + +test("supports SHA-256", function () { + const integrityMetadata = new IntegrityMetadata( + "sha256-MV9b23bQeMQ7isAGTkoBZGErH853yGk0W/yUx1iU7dM=", + ); + + assert.deepEqual(integrityMetadata, { + alg: "sha256", + val: "MV9b23bQeMQ7isAGTkoBZGErH853yGk0W/yUx1iU7dM=", + opt: [], + }); +}); + +test("supports SHA-384", function () { + const integrityMetadata = new IntegrityMetadata( + "sha384-VbxVaw0v4Pzlgrpf4Huq//A1ZTY4x6wNVJTCpkwL6hzFczHHwSpFzbyn9MNKCJ7r", + ); + + assert.deepEqual(integrityMetadata, { + alg: "sha384", + val: "VbxVaw0v4Pzlgrpf4Huq//A1ZTY4x6wNVJTCpkwL6hzFczHHwSpFzbyn9MNKCJ7r", + opt: [], + }); +}); + +test("supports SHA-512", function () { + const integrityMetadata = new IntegrityMetadata( + "sha512-wVJ82JPBJHc9gRkRlwyP5uhX1t9dySJr2KFgYUwM2WOk3eorlLt9NgIe+dhl1c6ilKgt1JoLsmn1H256V/eUIQ==", + ); + + assert.deepEqual(integrityMetadata, { + alg: "sha512", + val: "wVJ82JPBJHc9gRkRlwyP5uhX1t9dySJr2KFgYUwM2WOk3eorlLt9NgIe+dhl1c6ilKgt1JoLsmn1H256V/eUIQ==", + opt: [], + }); +}); + +test.todo("accepts options", function () { + const integrityMetadata = new IntegrityMetadata( + "sha256-MV9b23bQeMQ7isAGTkoBZGErH853yGk0W/yUx1iU7dM=?foo?bar", + ); + + assert.deepEqual(integrityMetadata, { + alg: "sha256", + val: "MV9b23bQeMQ7isAGTkoBZGErH853yGk0W/yUx1iU7dM=", + opt: ["foo", "bar"], + }); +}); + +test.todo("accepts an IntegrityMetadata like object as input", function () { + const integrityMetadata = new IntegrityMetadata({ + alg: "sha256", + val: "MV9b23bQeMQ7isAGTkoBZGErH853yGk0W/yUx1iU7dM=", + }); + + assert.deepEqual( + integrityMetadata, + new IntegrityMetadata( + "sha256-MV9b23bQeMQ7isAGTkoBZGErH853yGk0W/yUx1iU7dM=", + ), + ); +}); + +test.todo("trims leading and trailing whitespace", function () { + const integrityMetadata = new IntegrityMetadata( + "\t sha256-MV9b23bQeMQ7isAGTkoBZGErH853yGk0W/yUx1iU7dM=\u0020\u00a0\u1680\u180e\u2000\u2001\u2002\u3000", + ); + + assert.deepEqual( + integrityMetadata, + new IntegrityMetadata( + "sha256-MV9b23bQeMQ7isAGTkoBZGErH853yGk0W/yUx1iU7dM=", + ), + ); +}); + +test("discards unsupported hash algorithm", function () { + const integrityMetadata = new IntegrityMetadata( + "sha1-lDpwLQbzRZmu4fjajvn3KWAx1pk=", + ); + + assert.deepEqual(integrityMetadata, new IntegrityMetadata()); +}); + +test("discards null input", function () { + const integrityMetadata = new IntegrityMetadata(null); + + assert.deepEqual(integrityMetadata, new IntegrityMetadata()); +}); + +test("discards empty string input", function () { + const integrityMetadata = new IntegrityMetadata(""); + + assert.deepEqual(integrityMetadata, new IntegrityMetadata()); +}); + +test("discards invalid value", function () { + const integrityMetadata = new IntegrityMetadata("md5\0/..invalid-value"); + + assert.deepEqual(integrityMetadata, new IntegrityMetadata()); +}); + +test("discards invalid values in a list of multiple inputs", function () { + const integrityMetadata = new IntegrityMetadata( + "sha1-lDpwLQbzRZmu4fjajvn3KWAx1pk= md5\0/..invalid-value", + ); + + assert.deepEqual(integrityMetadata, new IntegrityMetadata()); +}); diff --git a/test/integrity-metadata/match.js b/test/integrity-metadata/match.js new file mode 100644 index 0000000..de6ceb5 --- /dev/null +++ b/test/integrity-metadata/match.js @@ -0,0 +1,82 @@ +import assert from "node:assert/strict"; +import { test } from "node:test"; +import { IntegrityMetadata } from "../../dist/index.js"; + +test("if the hash values match, return true", function () { + const integrityMetadata = new IntegrityMetadata( + "sha256-MV9b23bQeMQ7isAGTkoBZGErH853yGk0W/yUx1iU7dM=", + ); + + assert.strictEqual( + integrityMetadata.match({ + alg: "sha256", + val: "MV9b23bQeMQ7isAGTkoBZGErH853yGk0W/yUx1iU7dM=", + }), + true, + ); +}); + +test("if the hash algorithms are different, return false", function () { + const integrityMetadata = new IntegrityMetadata( + "sha256-MV9b23bQeMQ7isAGTkoBZGErH853yGk0W/yUx1iU7dM=", + ); + + assert.strictEqual( + integrityMetadata.match({ + alg: "sha512", + val: "MJ7MSJwS1utMxA9QyQLytNDtd+5RGnx6m808qG1M2G+YndNbxf9JlnDaNCVbRbDP2DDoH2Bdz33FVC6TrpzXbw==", + }), + false, + ); +}); + +test("if the hash values are different, return false", function () { + const integrityMetadata = new IntegrityMetadata( + "sha256-MV9b23bQeMQ7isAGTkoBZGErH853yGk0W/yUx1iU7dM=", + ); + + assert.strictEqual( + integrityMetadata.match({ + alg: "sha256", + val: "uU0nuZNNPgilLlLX2n2r+sSE7+N6U4DukIj3rOLvzek=", + }), + false, + ); +}); + +test.todo("if the hash algorithm is unsupported, return false", function () { + const integrityMetadata = new IntegrityMetadata( + "sha1-lDpwLQbzRZmu4fjajvn3KWAx1pk=", + ); + + assert.strictEqual( + integrityMetadata.match( + new IntegrityMetadata("sha1-lDpwLQbzRZmu4fjajvn3KWAx1pk="), + ), + false, + ); +}); + +test.todo("if null, return false", function () { + const integrityMetadata = new IntegrityMetadata(null); + + assert.strictEqual( + integrityMetadata.match(new IntegrityMetadata(null)), + false, + ); +}); + +test.todo("if empty, return false", function () { + const integrityMetadata = new IntegrityMetadata(""); + + assert.strictEqual(integrityMetadata.match(new IntegrityMetadata("")), false); +}); + +test.todo("if invalid value, return false", function () { + const integrityMetadata = new IntegrityMetadata("md5\0/..invalid-value"); + + assert.strictEqual( + integrityMetadata.match(new IntegrityMetadata("md5\0/..invalid-value")), + false, + ); +}); diff --git a/test/integrity-metadata/stringify.js b/test/integrity-metadata/stringify.js new file mode 100644 index 0000000..26d5ca4 --- /dev/null +++ b/test/integrity-metadata/stringify.js @@ -0,0 +1,15 @@ +import assert from "node:assert/strict"; +import { test } from "node:test"; +import { IntegrityMetadata } from "../../dist/index.js"; + +test("IntegrityMetadata like object can be serialized", function () { + const integrityMetadataLike = { + alg: "sha256", + val: "MV9b23bQeMQ7isAGTkoBZGErH853yGk0W/yUx1iU7dM=", + }; + + assert.strictEqual( + IntegrityMetadata.stringify(integrityMetadataLike), + "sha256-MV9b23bQeMQ7isAGTkoBZGErH853yGk0W/yUx1iU7dM=", + ); +}); diff --git a/test/integrity-metadata/to-json.js b/test/integrity-metadata/to-json.js new file mode 100644 index 0000000..bfa166d --- /dev/null +++ b/test/integrity-metadata/to-json.js @@ -0,0 +1,14 @@ +import assert from "node:assert/strict"; +import { test } from "node:test"; +import { IntegrityMetadata } from "../../dist/index.js"; + +test("toJSON() can be used", function () { + const integrityMetadata = new IntegrityMetadata( + "sha256-MV9b23bQeMQ7isAGTkoBZGErH853yGk0W/yUx1iU7dM=", + ); + + assert.strictEqual( + integrityMetadata.toJSON(), + "sha256-MV9b23bQeMQ7isAGTkoBZGErH853yGk0W/yUx1iU7dM=", + ); +}); diff --git a/test/integrity-metadata/to-string.js b/test/integrity-metadata/to-string.js new file mode 100644 index 0000000..68bbaf8 --- /dev/null +++ b/test/integrity-metadata/to-string.js @@ -0,0 +1,14 @@ +import assert from "node:assert/strict"; +import { test } from "node:test"; +import { IntegrityMetadata } from "../../dist/index.js"; + +test("toString() can be used", function () { + const integrityMetadata = new IntegrityMetadata( + "sha256-MV9b23bQeMQ7isAGTkoBZGErH853yGk0W/yUx1iU7dM=", + ); + + assert.strictEqual( + integrityMetadata.toString(), + "sha256-MV9b23bQeMQ7isAGTkoBZGErH853yGk0W/yUx1iU7dM=", + ); +});