test: reorganize fixture files into modality-first layout (phase 6b)

Move all fixture files from flat/mixed dirs (content/, media/, documents/,
formats/, hostile/, root loose) into the modality-first hierarchy:
image/{valid,formats,edge,hostile}, video/{valid,formats,hostile},
audio/{valid,formats,hostile}, document/{valid,formats,edge,hostile},
data/valid/, security/. Update index.ts paths, fixtureDir aliases,
all literal refs in 17 e2e/qa/script files, manifest.json, and the
three generator scripts. 163 files moved, 0 dropped, 100 new tests
from expanded document scan.
This commit is contained in:
SnapOtter
2026-06-20 05:51:17 +08:00
parent 1727a7a73e
commit 941ed27912
199 changed files with 560 additions and 429 deletions
+2 -2
View File
@@ -3,7 +3,7 @@
// make-tiny-pptx.mjs
//
// Builds a minimal ECMA-376 (OOXML) presentation skeleton and writes it to
// tests/fixtures/documents/tiny.pptx using adm-zip (root devDep).
// tests/fixtures/document/formats/tiny.pptx using adm-zip (root devDep).
//
// ACCEPTANCE (2026-06-12, snapotter/snapotter:latest + libreoffice-impress):
// soffice --headless --norestore --nolockcheck --nodefault \
@@ -18,7 +18,7 @@ import { fileURLToPath } from "node:url";
import AdmZip from "adm-zip";
const __dirname = dirname(fileURLToPath(import.meta.url));
const outPath = join(__dirname, "..", "..", "tests", "fixtures", "documents", "tiny.pptx");
const outPath = join(__dirname, "..", "..", "tests", "fixtures", "document", "formats", "tiny.pptx");
const zip = new AdmZip();
+4 -4
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env node
/**
* Generates the hostile-input fixtures in tests/fixtures/hostile/.
* Generates the hostile-input fixtures in tests/fixtures/image/hostile/.
*
* Deterministic on purpose: re-running produces byte-identical files so the
* committed fixtures never churn. No dependencies (the bomb PNG is built by
@@ -14,11 +14,11 @@ import { fileURLToPath } from "node:url";
import zlib from "node:zlib";
const root = resolve(dirname(fileURLToPath(import.meta.url)), "..");
const outDir = join(root, "tests", "fixtures", "hostile");
const outDir = join(root, "tests", "fixtures", "image", "hostile");
mkdirSync(outDir, { recursive: true });
// --- 1. truncated.jpg: a real JPEG cut off at 40% ---------------------------
const realJpeg = readFileSync(join(root, "tests", "fixtures", "sample-photo.jpg"));
const realJpeg = readFileSync(join(root, "tests", "fixtures", "image", "valid", "sample-photo.jpg"));
writeFileSync(
join(outDir, "truncated.jpg"),
realJpeg.subarray(0, Math.floor(realJpeg.length * 0.4)),
@@ -38,7 +38,7 @@ for (let i = 0; i < garbage.length; i++) {
writeFileSync(join(outDir, "garbage.jpg"), garbage);
// --- 4. png-bytes.jpg: valid PNG content with a lying .jpg extension --------
const realPng = readFileSync(join(root, "tests", "fixtures", "test-200x150.png"));
const realPng = readFileSync(join(root, "tests", "fixtures", "image", "valid", "test-200x150.png"));
writeFileSync(join(outDir, "png-bytes.jpg"), realPng);
// --- 5. bomb-50000x50000.png: tiny file whose header claims 2,500 megapixels
+11 -9
View File
@@ -13,9 +13,11 @@ import { fileURLToPath } from "node:url";
const __dirname = dirname(fileURLToPath(import.meta.url));
const root = join(__dirname, "..");
const mediaDir = join(root, "tests/fixtures/media");
const docsDir = join(root, "tests/fixtures/documents");
mkdirSync(mediaDir, { recursive: true });
const videoDir = join(root, "tests/fixtures/video/formats");
const audioDir = join(root, "tests/fixtures/audio/formats");
const docsDir = join(root, "tests/fixtures/document/formats");
mkdirSync(videoDir, { recursive: true });
mkdirSync(audioDir, { recursive: true });
mkdirSync(docsDir, { recursive: true });
const ffmpeg = process.env.FFMPEG_PATH || "ffmpeg";
@@ -58,7 +60,7 @@ run([
"-b:a",
"32k",
"-shortest",
join(mediaDir, "tiny.mp4"),
join(videoDir, "tiny.mp4"),
]);
// 1s sine mp3
run([
@@ -70,7 +72,7 @@ run([
"libmp3lame",
"-b:a",
"32k",
join(mediaDir, "tiny.mp3"),
join(audioDir, "tiny.mp3"),
]);
// 1s sine wav
run([
@@ -82,7 +84,7 @@ run([
"pcm_s16le",
"-ar",
"8000",
join(mediaDir, "tiny.wav"),
join(audioDir, "tiny.wav"),
]);
// Minimal OOXML/EPUB containers via archiver (resolved from apps/api).
@@ -154,8 +156,8 @@ await writeZip(
// Encrypted PDF fixture derived from test-3page.pdf via qpdf (AES-256).
const qpdf = whichBin("QPDF_PATH", "qpdf");
if (qpdf) {
const srcPdf = join(root, "tests/fixtures/test-3page.pdf");
const encPdf = join(docsDir, "encrypted.pdf");
const srcPdf = join(root, "tests/fixtures/document/valid/test-3page.pdf");
const encPdf = join(root, "tests/fixtures/document/valid/encrypted.pdf");
const qres = spawnSync(qpdf, [srcPdf, "--encrypt", "test123", "owner123", "256", "--", encPdf], {
stdio: "inherit",
});
@@ -192,4 +194,4 @@ A paragraph with **bold** and a list:
`,
);
console.log("Fixtures written to tests/fixtures/media and tests/fixtures/documents");
console.log("Fixtures written to tests/fixtures/{video,audio}/formats and tests/fixtures/document/formats");