File size: 5,104 Bytes
fd2c364 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | import { describe, it, expect, vi } from "vitest";
import { render, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { ModelSelector } from "#/components/shared/modals/settings/model-selector";
import type {
LLMProvider,
LLMModel,
} from "#/api/config-service/config-service.types";
const mockProviders: LLMProvider[] = [
{ name: "openai", verified: true },
{ name: "azure", verified: false },
{ name: "vertex_ai", verified: false },
];
const model = (partial: Partial<LLMModel> & Pick<LLMModel, "name">): LLMModel => ({
provider: null,
verified: false,
free: false,
default: false,
...partial,
});
const mockModelsByProvider: Record<string, LLMModel[]> = {
openai: [
model({ provider: "openai", name: "gpt-4o", verified: true }),
model({ provider: "openai", name: "gpt-4o-mini", verified: true }),
],
azure: [
model({ provider: "azure", name: "ada" }),
model({ provider: "azure", name: "gpt-35-turbo" }),
],
vertex_ai: [
model({ provider: "vertex_ai", name: "chat-bison" }),
model({ provider: "vertex_ai", name: "chat-bison-32k" }),
],
};
vi.mock("#/hooks/query/use-search-providers", () => ({
useSearchProviders: () => ({ data: mockProviders }),
}));
vi.mock("#/hooks/query/use-provider-models", () => ({
useProviderModels: (provider: string | null) => ({
data: provider ? (mockModelsByProvider[provider] ?? []) : [],
}),
}));
vi.mock("react-i18next", () => ({
useTranslation: () => ({
t: (key: string) => {
const translations: Record<string, string> = {
LLM$PROVIDER: "LLM Provider",
LLM$MODEL: "LLM Model",
LLM$SELECT_PROVIDER_PLACEHOLDER: "Select a provider",
LLM$SELECT_MODEL_PLACEHOLDER: "Select a model",
};
return translations[key] || key;
},
}),
}));
function renderWithQuery(ui: React.ReactElement) {
const queryClient = new QueryClient({
defaultOptions: { queries: { retry: false } },
});
return render(
<QueryClientProvider client={queryClient}>{ui}</QueryClientProvider>,
);
}
describe("ModelSelector", () => {
it("should display the provider selector", async () => {
const user = userEvent.setup();
renderWithQuery(<ModelSelector />);
const selector = screen.getByLabelText("LLM Provider");
expect(selector).toBeInTheDocument();
await user.click(selector);
expect(screen.getByText("OpenAI")).toBeInTheDocument();
expect(screen.getByText("Azure")).toBeInTheDocument();
expect(screen.getByText("VertexAI")).toBeInTheDocument();
});
it("should disable the model selector if the provider is not selected", async () => {
const user = userEvent.setup();
renderWithQuery(<ModelSelector />);
const modelSelector = screen.getByLabelText("LLM Model");
expect(modelSelector).toBeDisabled();
const providerSelector = screen.getByLabelText("LLM Provider");
await user.click(providerSelector);
const vertexAI = screen.getByText("VertexAI");
await user.click(vertexAI);
expect(modelSelector).not.toBeDisabled();
});
it("should display the model selector", async () => {
const user = userEvent.setup();
renderWithQuery(<ModelSelector />);
const providerSelector = screen.getByLabelText("LLM Provider");
await user.click(providerSelector);
const azureProvider = screen.getByText("Azure");
await user.click(azureProvider);
const modelSelector = screen.getByLabelText("LLM Model");
await user.click(modelSelector);
expect(screen.getByText("ada")).toBeInTheDocument();
expect(screen.getByText("gpt-35-turbo")).toBeInTheDocument();
});
it("should call onChange when the provider and model change", async () => {
const user = userEvent.setup();
const onChange = vi.fn();
renderWithQuery(<ModelSelector onChange={onChange} />);
const providerSelector = screen.getByLabelText("LLM Provider");
await user.click(providerSelector);
await user.click(screen.getByText("Azure"));
const modelSelector = screen.getByLabelText("LLM Model");
await user.click(modelSelector);
await user.click(screen.getByText("ada"));
expect(onChange).toHaveBeenNthCalledWith(1, "azure", null);
expect(onChange).toHaveBeenNthCalledWith(2, "azure", "ada");
});
it("should have a default value if passed", async () => {
renderWithQuery(<ModelSelector currentModel="azure/ada" />);
await waitFor(() => {
expect(screen.getByLabelText("LLM Provider")).toHaveValue("Azure");
expect(screen.getByLabelText("LLM Model")).toHaveValue("ada");
});
});
it("should not render placeholder text on the provider or model inputs", () => {
renderWithQuery(<ModelSelector />);
const providerInput = screen.getByLabelText("LLM Provider");
const modelInput = screen.getByLabelText("LLM Model");
expect(providerInput.getAttribute("placeholder") ?? "").toBe("");
expect(modelInput.getAttribute("placeholder") ?? "").toBe("");
});
});
|