Initial Commit
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* DTP-02 / DTP-09 / DTP-26 — schema-version pinning + per-file
|
||||
* consistency invariants + structured error context.
|
||||
*/
|
||||
|
||||
import { describe, expect, it } from "@suaveplan/testing/runner";
|
||||
import type {
|
||||
DriveTemplate,
|
||||
FileTemplate,
|
||||
FolderTemplate,
|
||||
} from "../src/index.js";
|
||||
import {
|
||||
assertFile,
|
||||
assertFolderFileInvariants,
|
||||
type DriveTemplateError,
|
||||
DTP_CODES,
|
||||
TemplateNonceLru,
|
||||
validateTemplate,
|
||||
} from "../src/index.js";
|
||||
import { DEFAULT_POLICY, makeKeys, signed } from "./_helpers.js";
|
||||
|
||||
const baseFile: FileTemplate = {
|
||||
name: "x.bin",
|
||||
fileLocId: "loc-1",
|
||||
fileId: "f".repeat(64),
|
||||
size: 100,
|
||||
totalChunks: 1,
|
||||
chunkSize: 1024,
|
||||
checksum: "blake3:abcd",
|
||||
flags: DEFAULT_POLICY,
|
||||
manifestKey: "manifest:f",
|
||||
manifestSig: new Uint8Array(64).fill(1),
|
||||
};
|
||||
|
||||
describe("DTP-02 — schema version pinned to 1", () => {
|
||||
it("schemaVersion ≠ 1 rejected with TEMPLATE_VERSION_UNSUPPORTED", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
const keys = makeKeys();
|
||||
const tpl = signed({ issuer: keys.publicHex }, keys);
|
||||
// Cast through unknown to bypass the literal-1 type guard.
|
||||
const broken = { ...tpl, schemaVersion: 2 } as unknown as DriveTemplate;
|
||||
try {
|
||||
validateTemplate(broken, {
|
||||
clock: () => Date.now(),
|
||||
nonceLru: new TemplateNonceLru(),
|
||||
});
|
||||
throw new Error("expected VERSION_UNSUPPORTED");
|
||||
} catch (err) {
|
||||
expect((err as DriveTemplateError).code).toBe(
|
||||
DTP_CODES.TEMPLATE_VERSION_UNSUPPORTED
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("DTP-09 — per-file consistency invariants", () => {
|
||||
it("chunkSize 164 rejected", { timeout: 5000 }, () => {
|
||||
try {
|
||||
assertFile({ ...baseFile, chunkSize: 164 }, "/x.bin");
|
||||
throw new Error("expected MALFORMED");
|
||||
} catch (err) {
|
||||
expect((err as DriveTemplateError).code).toBe(
|
||||
DTP_CODES.TEMPLATE_MALFORMED
|
||||
);
|
||||
expect((err as DriveTemplateError).context).toMatchObject({
|
||||
file: "/x.bin",
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it("totalChunks insufficient for size rejected", { timeout: 5000 }, () => {
|
||||
try {
|
||||
assertFile(
|
||||
{ ...baseFile, totalChunks: 1, chunkSize: 1024, size: 4096 },
|
||||
"/x.bin"
|
||||
);
|
||||
throw new Error("expected MALFORMED");
|
||||
} catch (err) {
|
||||
expect((err as DriveTemplateError).code).toBe(
|
||||
DTP_CODES.TEMPLATE_MALFORMED
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it("valid file passes through assertFile (positive path)", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
expect(() => assertFile(baseFile, "/x.bin")).not.toThrow();
|
||||
});
|
||||
|
||||
it("empty manifestKey rejected", { timeout: 5000 }, () => {
|
||||
try {
|
||||
assertFile({ ...baseFile, manifestKey: "" }, "/x.bin");
|
||||
throw new Error("expected MALFORMED");
|
||||
} catch (err) {
|
||||
expect((err as DriveTemplateError).code).toBe(
|
||||
DTP_CODES.TEMPLATE_MALFORMED
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it("malformed checksum rejected", { timeout: 5000 }, () => {
|
||||
try {
|
||||
assertFile({ ...baseFile, checksum: "md5:abc" }, "/x.bin");
|
||||
throw new Error("expected MALFORMED");
|
||||
} catch (err) {
|
||||
expect((err as DriveTemplateError).code).toBe(
|
||||
DTP_CODES.TEMPLATE_MALFORMED
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it("empty manifestSig rejected", { timeout: 5000 }, () => {
|
||||
try {
|
||||
assertFile(
|
||||
{ ...baseFile, manifestSig: new Uint8Array(0) },
|
||||
"/x.bin"
|
||||
);
|
||||
throw new Error("expected MALFORMED");
|
||||
} catch (err) {
|
||||
expect((err as DriveTemplateError).code).toBe(
|
||||
DTP_CODES.TEMPLATE_MALFORMED
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it("nested folder: deepest file's failure surfaces with full path", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
const tree: FolderTemplate = {
|
||||
name: "/",
|
||||
children: [
|
||||
{
|
||||
name: "photos",
|
||||
children: [
|
||||
{
|
||||
name: "wedding",
|
||||
children: [{ ...baseFile, chunkSize: 164 }],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
try {
|
||||
assertFolderFileInvariants(tree);
|
||||
throw new Error("expected MALFORMED");
|
||||
} catch (err) {
|
||||
expect((err as DriveTemplateError).code).toBe(
|
||||
DTP_CODES.TEMPLATE_MALFORMED
|
||||
);
|
||||
const ctx = (err as DriveTemplateError).context as { file: string };
|
||||
expect(ctx.file).toContain("photos");
|
||||
expect(ctx.file).toContain("wedding");
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user