diff --git a/apps/server/src/project/ProjectFaviconResolver.test.ts b/apps/server/src/project/ProjectFaviconResolver.test.ts index 75db78844a5..6929a3e8f0e 100644 --- a/apps/server/src/project/ProjectFaviconResolver.test.ts +++ b/apps/server/src/project/ProjectFaviconResolver.test.ts @@ -133,6 +133,73 @@ it.layer(TestLayer)("ProjectFaviconResolverLive", (it) => { }), ); + it.effect("resolves icon hrefs from object-literal route metadata", () => + Effect.gen(function* () { + const resolver = yield* ProjectFaviconResolver.ProjectFaviconResolver; + const cwd = yield* makeTempDir; + yield* writeTextFile( + cwd, + "src/routes/__root.tsx", + `export const Route = createRootRoute({ + head: () => ({ + links: [ + { rel: "stylesheet", href: "/app.css" }, + { rel: "icon", href: "/brand/logo.svg" }, + ], + }), +});`, + ); + yield* writeTextFile(cwd, "public/brand/logo.svg", ""); + + const resolved = yield* resolver.resolvePath(cwd); + + expect(resolved).not.toBeNull(); + expect(resolved).toContain("public/brand/logo.svg"); + }), + ); + + it.effect("resolves object-literal icon metadata when href precedes rel", () => + Effect.gen(function* () { + const resolver = yield* ProjectFaviconResolver.ProjectFaviconResolver; + const cwd = yield* makeTempDir; + yield* writeTextFile( + cwd, + "src/root.tsx", + `const links = [{ href: "/brand/logo.svg", rel: "shortcut icon" }];`, + ); + yield* writeTextFile(cwd, "public/brand/logo.svg", ""); + + const resolved = yield* resolver.resolvePath(cwd); + + expect(resolved).not.toBeNull(); + expect(resolved).toContain("public/brand/logo.svg"); + }), + ); + + // A large icon source with no icon metadata used to pin the server's event loop for + // minutes: the object pattern was unanchored, so it restarted at every offset and + // rescanned forward from each one. Anchoring keeps this proportional to file size. + it.effect("scans large icon sources without an icon in reasonable time", () => + Effect.gen(function* () { + const resolver = yield* ProjectFaviconResolver.ProjectFaviconResolver; + const cwd = yield* makeTempDir; + // Mirrors a generated single-file build: large, brace-sparse, and no icon metadata. + const filler = `
${"pokopia companion guide ".repeat(24)}
\n`; + yield* writeTextFile( + cwd, + "index.html", + `