mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
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:
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user