evOo-local/apps/desktop/src/renderer-assets.test.ts
cynarAI 6c7eed7580 Initial clean evOo-local from f00577b
Fresh history cut from cynarAI/evoo antigravity-handoff/project-timeline
(Voice First + project timeline). Brand docs/titles as evOo; keep @rakazo/*
packages as tech debt. Excludes node_modules, caches, secrets, voice blobs.
2026-09-20 17:15:16 +02:00

76 lines
2.9 KiB
TypeScript

import path from "node:path";
import { describe, expect, it } from "vitest";
import {
bundledRendererCandidates,
contentType,
forwardedRendererRequestInit,
immutableRendererAsset,
isRendererAssetMiss,
} from "./renderer-assets.js";
const root = path.resolve("/tmp/rakazo-renderer");
const origin = "https://app.example.com";
describe("bundled desktop renderer", () => {
it("serves static assets and falls back to index.html for app routes", () => {
expect(bundledRendererCandidates(root, `${origin}/assets/app-123.js`, origin, false)).toEqual([
path.join(root, "assets/app-123.js"),
]);
expect(bundledRendererCandidates(root, `${origin}/app/bot-1`, origin, true)).toEqual([
path.join(root, "app/bot-1"),
path.join(root, "index.html"),
]);
expect(bundledRendererCandidates(root, `${origin}/app/bot.name`, origin, true)).toEqual([
path.join(root, "app/bot.name"),
path.join(root, "index.html"),
]);
});
it("leaves APIs, screen proxying, and other origins on the network", () => {
for (const pathname of ["/api/auth/session", "/rpc/bots", "/novnc/socket"]) {
expect(bundledRendererCandidates(root, `${origin}${pathname}`, origin, false)).toBeNull();
}
expect(
bundledRendererCandidates(root, "https://example.net/assets/app-123.js", origin, false),
).toBeNull();
});
it("does not resolve traversal outside the renderer root", () => {
expect(
bundledRendererCandidates(root, `${origin}/%2e%2e%2fsecret.txt`, origin, false),
).toBeNull();
expect(bundledRendererCandidates(root, `${origin}/bad%00name.js`, origin, false)).toBeNull();
});
it("assigns cache and content metadata", () => {
expect(contentType("index.html")).toBe("text/html; charset=utf-8");
expect(contentType("app.woff2")).toBe("font/woff2");
expect(immutableRendererAsset(path.join(root, "assets/app-123.js"))).toBe(true);
expect(immutableRendererAsset(path.join(root, "index.html"))).toBe(false);
});
it("treats filesystem path misses as renderer fallbacks", () => {
for (const code of ["ENOENT", "EISDIR", "ENOTDIR"]) {
expect(isRendererAssetMiss(Object.assign(new Error(code), { code }))).toBe(true);
}
expect(isRendererAssetMiss(Object.assign(new Error("denied"), { code: "EACCES" }))).toBe(false);
expect(isRendererAssetMiss(null)).toBe(false);
});
it("forwards cookies for both app and cross-origin requests", () => {
const appOptions = forwardedRendererRequestInit(new Request(`${origin}/rpc/bots`), origin);
const oauthOptions = forwardedRendererRequestInit(
new Request("https://oauth.example.com/authorize"),
origin,
);
expect(appOptions.credentials).toBe("include");
expect(new Headers(appOptions.headers).get("origin")).toBe(origin);
expect(oauthOptions).toMatchObject({
bypassCustomProtocolHandlers: true,
credentials: "include",
});
expect(oauthOptions.headers).toBeUndefined();
});
});