Initial Commit
This commit is contained in:
148
packages/foundation/data/media/src/signatures/signatures.test.ts
Normal file
148
packages/foundation/data/media/src/signatures/signatures.test.ts
Normal file
@@ -0,0 +1,148 @@
|
||||
import { describe, expect, it } from "@suaveplan/testing/runner";
|
||||
import { MEDIA_CODES, MediaError } from "../errors/errors.js";
|
||||
import {
|
||||
BUILTIN_SIGNATURES,
|
||||
defaultSignatureRegistry,
|
||||
SignatureRegistry,
|
||||
} from "./signatures.js";
|
||||
|
||||
describe("BUILTIN_SIGNATURES", () => {
|
||||
it("includes PNG, JPEG, MP3, FLAC, OGG, WebM, MP4, WEBP", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
const labels = BUILTIN_SIGNATURES.map((s) => s.label);
|
||||
for (const expected of [
|
||||
"PNG",
|
||||
"JPEG",
|
||||
"MP3-ID3",
|
||||
"FLAC",
|
||||
"OGG",
|
||||
"WebM/MKV",
|
||||
"MP4/MOV",
|
||||
"WEBP",
|
||||
]) {
|
||||
expect(labels).toContain(expected);
|
||||
}
|
||||
});
|
||||
|
||||
it("is frozen", { timeout: 5000 }, () => {
|
||||
expect(Object.isFrozen(BUILTIN_SIGNATURES)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("SignatureRegistry", () => {
|
||||
it("detects PNG via default registry", { timeout: 5000 }, () => {
|
||||
const png = new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x00]);
|
||||
expect(defaultSignatureRegistry.detect(png)).toBe("image");
|
||||
});
|
||||
|
||||
it("returns 'unknown' for unrecognised bytes", { timeout: 5000 }, () => {
|
||||
const bytes = new Uint8Array([0x00, 0x01, 0x02]);
|
||||
expect(defaultSignatureRegistry.detect(bytes)).toBe("unknown");
|
||||
});
|
||||
|
||||
it("match returns the signature record", { timeout: 5000 }, () => {
|
||||
const flac = new Uint8Array([0x66, 0x4c, 0x61, 0x43, 0x00]);
|
||||
const sig = defaultSignatureRegistry.match(flac);
|
||||
expect(sig?.label).toBe("FLAC");
|
||||
expect(sig?.type).toBe("audio");
|
||||
});
|
||||
|
||||
it("match returns null for empty input", { timeout: 5000 }, () => {
|
||||
expect(defaultSignatureRegistry.match(new Uint8Array([]))).toBeNull();
|
||||
});
|
||||
|
||||
it("honours non-zero offset (MP4 ftyp)", { timeout: 5000 }, () => {
|
||||
// 4 padding bytes then 'ftyp' (0x66 0x74 0x79 0x70)
|
||||
const mp4 = new Uint8Array([
|
||||
0x00, 0x00, 0x00, 0x18, 0x66, 0x74, 0x79, 0x70, 0x69, 0x73, 0x6f,
|
||||
0x6d,
|
||||
]);
|
||||
expect(defaultSignatureRegistry.detect(mp4)).toBe("video");
|
||||
});
|
||||
|
||||
it("ignores signature when input shorter than offset+bytes", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
const short = new Uint8Array([0x00]);
|
||||
expect(defaultSignatureRegistry.detect(short)).toBe("unknown");
|
||||
});
|
||||
|
||||
it("can register custom signature", { timeout: 5000 }, () => {
|
||||
const reg = new SignatureRegistry([]);
|
||||
reg.register({ type: "image", label: "X", bytes: [0xde, 0xad] });
|
||||
const detected = reg.detect(new Uint8Array([0xde, 0xad, 0xbe]));
|
||||
expect(detected).toBe("image");
|
||||
});
|
||||
|
||||
it("unregister removes signature and returns true", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
const reg = new SignatureRegistry();
|
||||
expect(reg.unregister("PNG")).toBe(true);
|
||||
expect(reg.detect(new Uint8Array([0x89, 0x50, 0x4e, 0x47]))).toBe(
|
||||
"unknown"
|
||||
);
|
||||
});
|
||||
|
||||
it("unregister returns false for unknown label", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
const reg = new SignatureRegistry();
|
||||
expect(reg.unregister("NOPE")).toBe(false);
|
||||
});
|
||||
|
||||
it("list returns frozen snapshot", { timeout: 5000 }, () => {
|
||||
const reg = new SignatureRegistry();
|
||||
const snap = reg.list();
|
||||
expect(Object.isFrozen(snap)).toBe(true);
|
||||
expect(snap.length).toBe(BUILTIN_SIGNATURES.length);
|
||||
});
|
||||
|
||||
it("register rejects empty byte array", { timeout: 5000 }, () => {
|
||||
const reg = new SignatureRegistry([]);
|
||||
expect(() =>
|
||||
reg.register({ type: "image", label: "E", bytes: [] })
|
||||
).toThrow(MediaError);
|
||||
});
|
||||
|
||||
it("register rejects non-byte values", { timeout: 5000 }, () => {
|
||||
const reg = new SignatureRegistry([]);
|
||||
try {
|
||||
reg.register({ type: "image", label: "N", bytes: [256] });
|
||||
throw new Error("should have thrown");
|
||||
} catch (err) {
|
||||
expect(err).toBeInstanceOf(MediaError);
|
||||
expect((err as MediaError).code).toBe(
|
||||
MEDIA_CODES.INVALID_SIGNATURE
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it("register rejects negative byte values", { timeout: 5000 }, () => {
|
||||
const reg = new SignatureRegistry([]);
|
||||
expect(() =>
|
||||
reg.register({ type: "image", label: "N", bytes: [-1] })
|
||||
).toThrow(MediaError);
|
||||
});
|
||||
|
||||
it("register rejects non-integer byte values", { timeout: 5000 }, () => {
|
||||
const reg = new SignatureRegistry([]);
|
||||
expect(() =>
|
||||
reg.register({ type: "image", label: "N", bytes: [1.5] })
|
||||
).toThrow(MediaError);
|
||||
});
|
||||
|
||||
it("rejects duplicate label", { timeout: 5000 }, () => {
|
||||
const reg = new SignatureRegistry();
|
||||
try {
|
||||
reg.register({ type: "image", label: "PNG", bytes: [0x00] });
|
||||
throw new Error("should have thrown");
|
||||
} catch (err) {
|
||||
expect(err).toBeInstanceOf(MediaError);
|
||||
expect((err as MediaError).code).toBe(
|
||||
MEDIA_CODES.DUPLICATE_SIGNATURE
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user