Files
suaveplan/packages/networking/drive/drive-template/tests/template-roundtrip.test.ts
2026-05-27 23:47:53 +01:00

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));
});
});