Files
OmniRoute/tests/unit/ui/providerCardGenericIcon.test.tsx
Diego Rodrigues de Sa e Souza bb1b01124b fix(assets): replace unresolved provider logos with generic icons (#11750)
Merged via /merge-batch (v3.8.51 provenance sweep). Boarded and validated together with the batch's other provenance PRs in a combined worktree — full gate suite green. Reconciled against 3 sibling PRs (#11735, #11736, #11711) that landed first and independently retired 6 further unproven assets this PR never targeted, in both the README media-badge row and the "148 non-target assets" golden count (now the real 142, computed not guessed). This PR's own 23 node:test + 91 vitest focused tests all pass. Thank you for the careful provenance/generic-fallback work.
2026-08-28 04:54:00 -03:00

90 lines
3.0 KiB
TypeScript

// @vitest-environment jsdom
import React from "react";
import { act } from "react";
import { createRoot, type Root } from "react-dom/client";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
vi.mock("next-intl", () => ({ useTranslations: () => (key: string) => key }));
vi.mock("next/navigation", () => ({ useRouter: () => ({ push: () => {} }) }));
vi.mock("@/shared/components/ProviderTestSlideOver", () => ({ default: () => null }));
vi.mock("@/shared/components/ProviderIcon", () => ({
default: ({ src }: { src?: string }) => (
<span data-provider-icon="dynamic" data-provider-icon-src={src || ""} />
),
}));
vi.mock("next/image", () => ({
default: ({ src, alt }: { src: string; alt: string }) => (
// eslint-disable-next-line @next/next/no-img-element -- deterministic next/image test double
<img data-testid="next-image" src={src} alt={alt} />
),
}));
const { default: ProviderCard } =
await import("@/app/(dashboard)/dashboard/providers/components/ProviderCard");
let container: HTMLDivElement | null = null;
let root: Root | null = null;
beforeEach(() => {
(
globalThis as typeof globalThis & { IS_REACT_ACT_ENVIRONMENT?: boolean }
).IS_REACT_ACT_ENVIRONMENT = true;
});
function renderCard(providerId: string, provider: { apiType?: string; iconUrl?: string } = {}) {
container = document.createElement("div");
document.body.appendChild(container);
root = createRoot(container);
act(() => {
root!.render(
<ProviderCard
providerId={providerId}
provider={{ id: providerId, name: providerId, ...provider }}
stats={{ total: 0, connected: 0, error: 0, warning: 0 }}
authType="apikey"
onToggle={() => {}}
/>
);
});
return container;
}
afterEach(() => {
if (root) {
act(() => root!.unmount());
root = null;
}
container?.remove();
container = null;
});
describe("ProviderCard — compatible-provider generic icon", () => {
it.each([
["openai-compatible-chat", "chat-completions"],
["openai-compatible-responses", "responses"],
["anthropic-compatible-chat", "anthropic"],
["anthropic-compatible-cc-chat", "anthropic"],
])("uses the bundled generic asset for %s", (providerId, apiType) => {
const rendered = renderCard(providerId, { apiType });
expect(rendered.querySelector('[data-testid="next-image"]')?.getAttribute("src")).toBe(
"/providers/cli-generic.svg"
);
expect(rendered.querySelector('[data-provider-icon="dynamic"]')).toBeNull();
});
it("preserves an operator-supplied icon URL instead of replacing it with the generic asset", () => {
const iconUrl = "https://example.com/operator-compatible.svg";
const rendered = renderCard("openai-compatible-custom", { iconUrl });
expect(rendered.querySelector('[data-testid="next-image"]')).toBeNull();
expect(
rendered
.querySelector('[data-provider-icon="dynamic"]')
?.getAttribute("data-provider-icon-src")
).toBe(iconUrl);
});
});