84 lines
2.7 KiB
TypeScript
84 lines
2.7 KiB
TypeScript
/**
|
|
* DTP-01 / DTP-03 — DriveTemplate shape + canonical serialization
|
|
* deterministic across calls.
|
|
*/
|
|
|
|
import { describe, expect, it } from "@suaveplan/testing/runner";
|
|
import { canonicalSerialize } from "../src/codec/canonical.js";
|
|
import type { FileTemplate, FolderTemplate } from "../src/index.js";
|
|
import { signTemplate, verifyTemplateSignature } from "../src/index.js";
|
|
import { buildTemplate, DEFAULT_POLICY, makeKeys } from "./_helpers.js";
|
|
|
|
const FILE: FileTemplate = {
|
|
name: "photo.jpg",
|
|
fileLocId: "loc-1",
|
|
fileId: "f".repeat(64),
|
|
size: 1024,
|
|
totalChunks: 1,
|
|
chunkSize: 1024,
|
|
checksum: "blake3:abcd",
|
|
flags: DEFAULT_POLICY,
|
|
manifestKey: "manifest:f",
|
|
manifestSig: new Uint8Array(64).fill(1),
|
|
};
|
|
|
|
const ROOT: FolderTemplate = {
|
|
name: "/",
|
|
children: [{ name: "photos", children: [FILE] }],
|
|
};
|
|
|
|
describe("DTP-01 — DriveTemplate shape", () => {
|
|
it("DriveTemplate with all required fields encodes/decodes", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
const keys = makeKeys();
|
|
const tpl = signTemplate(
|
|
buildTemplate({ issuer: keys.publicHex, rootFolder: ROOT }),
|
|
keys.secret
|
|
);
|
|
expect(verifyTemplateSignature(tpl)).toBe(true);
|
|
});
|
|
|
|
it("Minimal empty-rootFolder template signs and verifies", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
const keys = makeKeys();
|
|
const tpl = signTemplate(
|
|
buildTemplate({ issuer: keys.publicHex }),
|
|
keys.secret
|
|
);
|
|
expect(verifyTemplateSignature(tpl)).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe("DTP-03 — canonicalSerialize is deterministic", () => {
|
|
it("canonicalSerialize is deterministic across calls", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
const keys = makeKeys();
|
|
const tpl = buildTemplate({ issuer: keys.publicHex, rootFolder: ROOT });
|
|
const a = canonicalSerialize(tpl);
|
|
const b = canonicalSerialize(tpl);
|
|
expect(a).toEqual(b);
|
|
});
|
|
|
|
it("Field-reorder produces identical bytes", { timeout: 5000 }, () => {
|
|
const keys = makeKeys();
|
|
const a = buildTemplate({ issuer: keys.publicHex, rootFolder: ROOT });
|
|
// Recreate with fields in a different in-memory order — the
|
|
// canonical encoder's fixed schema-driven order means the bytes
|
|
// are still identical.
|
|
const reordered = {
|
|
policy: a.policy,
|
|
schemaVersion: a.schemaVersion,
|
|
issuedAt: a.issuedAt,
|
|
issuer: a.issuer,
|
|
driveId: a.driveId,
|
|
expiresAt: a.expiresAt,
|
|
nonce: a.nonce,
|
|
rootFolder: a.rootFolder,
|
|
} as typeof a;
|
|
expect(canonicalSerialize(a)).toEqual(canonicalSerialize(reordered));
|
|
});
|
|
});
|