mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-10-30 09:16:55 +00:00
* fix(catalog): fall back to recorded video when directory is over budget hostItemDirectory() returned "" for both "not needed" and "over the 2MB host budget", so an item that needed its own hosted directory but exceeded the cap (texture-mask-text: 5.6MB of mask PNGs referenced via runtime JS template strings, invisible to the static asset scanner) silently shipped a payload with no <base href> and dead relative image references, 404ing on the docs site. It now returns a tagged result so the caller can fall back to the recorded video on over-budget, same as the existing unresolved-assets fallback. * test(catalog): cover the over-budget skip path in the payload generator * chore(catalog): allowlist the deliberate over-budget payload deletion * chore(catalog): dedupe hosted-directory assertions, note pre-existing complexity Fallow's new-only gate flagged two problems this branch introduced: five near-identical hostItemDirectory assertions in the file-race test collapse into a shared expectHosted() helper, and the over-budget branch added to buildPayload pushed it one branch past the complexity threshold on top of already-high pre-existing debt (CRAP 240 before this branch, unrelated to the fix). Suppressed with the repo's existing fallow-ignore-next-line convention rather than refactoring an unrelated 115-line function inside a bugfix PR.
69 lines
2.5 KiB
TypeScript
69 lines
2.5 KiB
TypeScript
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
import { tmpdir } from "node:os";
|
|
|
|
vi.mock("./generate-catalog-previews.js", async (importOriginal) => ({
|
|
...(await importOriginal<typeof import("./generate-catalog-previews.js")>()),
|
|
prepareProjectDir: vi.fn(),
|
|
}));
|
|
vi.mock("./catalog-payload-assets.ts", async (importOriginal) => ({
|
|
...(await importOriginal<typeof import("./catalog-payload-assets.ts")>()),
|
|
hostItemDirectory: vi.fn(),
|
|
}));
|
|
|
|
import { prepareProjectDir } from "./generate-catalog-previews.js";
|
|
import { hostItemDirectory } from "./catalog-payload-assets.ts";
|
|
import { buildPayload, payloadRoot } from "./generate-catalog-payloads.ts";
|
|
|
|
const cleanupPaths: string[] = [];
|
|
function tmpDir(): string {
|
|
const dir = mkdtempSync(join(tmpdir(), "hf-catalog-payload-"));
|
|
cleanupPaths.push(dir);
|
|
return dir;
|
|
}
|
|
|
|
afterEach(() => {
|
|
vi.clearAllMocks();
|
|
for (const path of cleanupPaths) rmSync(path, { recursive: true, force: true });
|
|
cleanupPaths.length = 0;
|
|
});
|
|
|
|
describe("buildPayload", () => {
|
|
it("skips and drops a stale payload when the item's directory is over the host budget", async () => {
|
|
const sourceDir = tmpDir();
|
|
// Declares a local asset so `needsOwnDirectory` routes through `hostItemDirectory`.
|
|
writeFileSync(
|
|
join(sourceDir, "registry-item.json"),
|
|
JSON.stringify({ files: [{ type: "hyperframes:asset" }] }),
|
|
);
|
|
const projectDir = tmpDir();
|
|
writeFileSync(join(projectDir, "index.html"), "<html></html>");
|
|
vi.mocked(prepareProjectDir).mockResolvedValue(projectDir);
|
|
vi.mocked(hostItemDirectory).mockReturnValue({ status: "over-budget" });
|
|
|
|
const item = {
|
|
name: "test-over-budget-item",
|
|
kind: "component" as const,
|
|
sourceDir,
|
|
entryFile: "index.html",
|
|
};
|
|
const outPath = join(payloadRoot, "components", `${item.name}.json`);
|
|
cleanupPaths.push(outPath);
|
|
mkdirSync(join(payloadRoot, "components"), { recursive: true });
|
|
writeFileSync(outPath, JSON.stringify({ html: "stale" }));
|
|
|
|
const logSpy = vi.spyOn(console, "log").mockImplementation(() => {});
|
|
const result = await buildPayload(item);
|
|
|
|
expect(result).toBe("skipped");
|
|
expect(existsSync(outPath)).toBe(false);
|
|
expect(
|
|
logSpy.mock.calls.some(
|
|
(call) => String(call[0]).includes("host budget") && String(call[0]).includes(item.name),
|
|
),
|
|
).toBe(true);
|
|
logSpy.mockRestore();
|
|
});
|
|
});
|