Files
rednote-tool-studio/tests/validation.test.ts
T
2026-09-17 21:54:33 +08:00

43 lines
1.9 KiB
TypeScript

import assert from "node:assert/strict";
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import test from "node:test";
import { validateArtifact } from "../lib/validation";
async function fixture(files: Record<string, string>) {
const root = await fs.mkdtemp(path.join(os.tmpdir(), "rednote-validator-"));
for (const [name, content] of Object.entries(files)) {
const target = path.join(root, name);
await fs.mkdir(path.dirname(target), { recursive: true });
await fs.writeFile(target, content);
}
return root;
}
test("accepts a minimal offline artifact", async (t) => {
const root = await fixture({
"index.html": '<!doctype html><html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"><link rel="stylesheet" href="./assets/style.css"></head><body><script src="./assets/main.js"></script></body></html>',
"assets/main.js": 'document.body.addEventListener("click", function () {});',
"assets/style.css": "body { color: #333; }",
});
t.after(() => fs.rm(root, { recursive: true, force: true }));
const report = await validateArtifact(root);
assert.equal(report.status, "passed");
assert.match(report.auditOutput, /PASS/);
});
test("reports forbidden APIs, inline handlers and missing resources", async (t) => {
const root = await fixture({
"index.html": '<!doctype html><html><body><img src="./missing.png"><button onclick="go()">go</button><script src="./main.js"></script></body></html>',
"main.js": 'fetch("/api");',
});
t.after(() => fs.rm(root, { recursive: true, force: true }));
const report = await validateArtifact(root);
const codes = report.issues.map((issue) => issue.code);
assert.equal(report.status, "failed");
assert.ok(codes.includes("NETWORK_FETCH"));
assert.ok(codes.includes("INLINE_EVENT"));
assert.ok(codes.includes("MISSING_RESOURCE"));
});