import { createMemoryHistory, createRootRoute, createRouter, RouterProvider, } from "@tanstack/react-router"; import { createElement, type ReactElement } from "react"; import { renderToStaticMarkup } from "react-dom/server"; import { describe, expect, it } from "vitest"; import { LocaleProvider } from "~/i18n"; import { handlePluginThumbnailRequest, pluginCardScreenshot } from "./thumbnails"; import { PluginCard } from "./plugin-card"; import type { Plugin } from "./registry"; const source = "https://cdn.jsdelivr.net/npm/paseo-example@1.2.3/preview.png"; const video = "https://cdn.jsdelivr.net/npm/paseo-example@1.2.3/demo.mp4"; const plugin: Plugin = { id: "acme/example", name: "Example", description: "An example", categories: ["themes"], author: { github: "acme" }, repository: { url: "https://github.com/acme/example" }, artifact: { kind: "npm", package: "paseo-example", version: "1.2.3", resolved: "https://registry.npmjs.org/example.tgz", integrity: "sha512-YWJj", }, media: [source], submittedAt: "2026-10-03", reviewedAt: "2026-10-03", updatedAt: "2026-10-03", publishedAt: "2026-10-03", installs: 42, }; const avatar = 'src="https://github.com/acme.png?size=80"'; /** Renders a card on an English page, inside the router and language provider every page has. */ async function renderOnPage(card: ReactElement): Promise { const router = createRouter({ routeTree: createRootRoute({ component: () => createElement(LocaleProvider, null, card) }), history: createMemoryHistory({ initialEntries: ["/"] }), }); await router.load(); return renderToStaticMarkup(createElement(RouterProvider, { router })); } describe("plugin card thumbnails", () => { it("uses the first image in the plugin's media, skipping a leading video", async () => { const html = await renderOnPage( createElement(PluginCard, { plugin: { ...plugin, media: [video, source] } }), ); expect(html).toContain(`/plugins/thumb/592/${encodeURIComponent(source)}?`); expect(html).not.toContain(encodeURIComponent(video)); }); it("shows the plugin tile when the media has no image", async () => { const html = await renderOnPage( createElement(PluginCard, { plugin: { ...plugin, media: [video] } }), ); expect(html.match(/]*>/g)).toEqual([expect.stringContaining(avatar)]); expect(html).not.toContain("E"); }); it("keeps a screenshot on an unsupported host visible at its original URL", async () => { const screenshot = "https://example.com/preview.png"; const html = await renderOnPage( createElement(PluginCard, { plugin: { ...plugin, media: [screenshot] } }), ); expect(html).toContain(`src="${screenshot}"`); expect(html).not.toContain("/plugins/thumb/"); }); it("shows the author's avatar and name beside the card detail", async () => { const html = await renderOnPage(createElement(PluginCard, { plugin }, "today")); expect(html).toContain(avatar); expect(html).toMatch(/>acme<\/span>