fix(ui/tests): resolve frontend-lint failures in new test files

- useLogDetails.test.ts: add Wrapper.displayName, replace 'null as any'
  with null, type resolveCall promise resolver properly
- usePaginatedDailyActivity.test.ts: remove unused waitFor import,
  add Wrapper.displayName, change Record<string,any> to Record<string,unknown>
- UsageViewSelect.adminFiltering.test.tsx: replace all props:any with
  explicit SelectProps/BadgeProps/SelectOption types, replace (X as any).displayName
  with direct X.displayName assignment

no-explicit-any count: 2034 (budget: 2040). Prettier check: clean.
This commit is contained in:
Yaniv Israel 2026-06-11 21:46:51 +03:00
parent 556dc51f5b
commit 9beedc279b
3 changed files with 63 additions and 57 deletions

View file

@ -3,27 +3,47 @@ import { describe, it, expect, vi, beforeEach } from "vitest";
import { render, screen, fireEvent, act } from "@testing-library/react";
import { UsageViewSelect } from "../src/components/UsagePage/components/UsageViewSelect/UsageViewSelect";
// ── Types for antd mocks ─────────────────────────────────────────────────────
type SelectOption = {
value: string;
label: React.ReactNode;
};
type SelectProps = {
value?: string;
onChange?: (value: string) => void;
options?: SelectOption[];
};
type BadgeProps = {
count?: React.ReactNode;
children?: React.ReactNode;
};
// ── Mocks (mirrors the pattern from UsageViewSelect.test.tsx in src/) ──────────
vi.mock("antd", async () => {
const React = await import("react");
function Select(props: any) {
function Select(props: SelectProps) {
const { value, onChange, options } = props;
return React.createElement(
"select",
{ value, onChange: (e: any) => onChange?.(e.target.value), role: "combobox" },
options?.map((opt: any) =>
React.createElement("option", { key: opt.value, value: opt.value }, opt.label),
),
{
value,
onChange: (e: React.ChangeEvent<HTMLSelectElement>) => onChange?.(e.target.value),
role: "combobox",
},
options?.map((opt) => React.createElement("option", { key: opt.value, value: opt.value }, opt.label)),
);
}
(Select as any).displayName = "AntdSelect";
Select.displayName = "AntdSelect";
function Badge(props: any) {
function Badge(props: BadgeProps) {
return React.createElement("span", { "data-testid": "antd-badge" }, props.count, props.children);
}
(Badge as any).displayName = "AntdBadge";
Badge.displayName = "AntdBadge";
return { Select, Badge };
});
@ -53,9 +73,7 @@ const NON_ADMIN_VISIBLE = ["global", "organization", "team"];
// ── Helpers ────────────────────────────────────────────────────────────────────
function getOptionValues(): string[] {
return Array.from(screen.getByRole("combobox").querySelectorAll("option")).map(
(o) => (o as HTMLOptionElement).value,
);
return Array.from(screen.getByRole("combobox").querySelectorAll("option")).map((o) => (o as HTMLOptionElement).value);
}
// ── Tests ──────────────────────────────────────────────────────────────────────

View file

@ -34,8 +34,12 @@ function makeWrapper() {
const qc = new QueryClient({
defaultOptions: { queries: { retry: false } },
});
return ({ children }: { children: React.ReactNode }) =>
const Wrapper = ({ children }: { children: React.ReactNode }) =>
React.createElement(QueryClientProvider, { client: qc }, children);
Wrapper.displayName = "QueryClientWrapper";
return Wrapper;
}
// ── Tests ──────────────────────────────────────────────────────────────────────
@ -51,62 +55,44 @@ describe("useLogDetails — conditional lazy loading", () => {
});
it("should not call the API when enabled is false", () => {
renderHook(
() => useLogDetails("req-123", "2025-01-01 00:00:00", false),
{ wrapper: makeWrapper() },
);
renderHook(() => useLogDetails("req-123", "2025-01-01 00:00:00", false), { wrapper: makeWrapper() });
expect(mockApiCall).not.toHaveBeenCalled();
});
it("should not call the API when requestId is undefined", () => {
renderHook(
() => useLogDetails(undefined, "2025-01-01 00:00:00", true),
{ wrapper: makeWrapper() },
);
renderHook(() => useLogDetails(undefined, "2025-01-01 00:00:00", true), { wrapper: makeWrapper() });
expect(mockApiCall).not.toHaveBeenCalled();
});
it("should not call the API when startTime is undefined", () => {
renderHook(
() => useLogDetails("req-123", undefined, true),
{ wrapper: makeWrapper() },
);
renderHook(() => useLogDetails("req-123", undefined, true), { wrapper: makeWrapper() });
expect(mockApiCall).not.toHaveBeenCalled();
});
it("should not call the API when accessToken is null", () => {
mockUseAuthorized.mockReturnValue({ ...DEFAULT_AUTH, accessToken: null as any });
mockUseAuthorized.mockReturnValue({ ...DEFAULT_AUTH, accessToken: null });
renderHook(
() => useLogDetails("req-123", "2025-01-01 00:00:00", true),
{ wrapper: makeWrapper() },
);
renderHook(() => useLogDetails("req-123", "2025-01-01 00:00:00", true), { wrapper: makeWrapper() });
expect(mockApiCall).not.toHaveBeenCalled();
});
it("should call the API with accessToken, requestId and startTime when all conditions met", async () => {
const { result } = renderHook(
() => useLogDetails("req-123", "2025-01-01 00:00:00", true),
{ wrapper: makeWrapper() },
);
const { result } = renderHook(() => useLogDetails("req-123", "2025-01-01 00:00:00", true), {
wrapper: makeWrapper(),
});
await waitFor(() => expect(result.current.isSuccess).toBe(true));
expect(mockApiCall).toHaveBeenCalledWith(
"mock-access-token",
"req-123",
"2025-01-01 00:00:00",
);
expect(mockApiCall).toHaveBeenCalledWith("mock-access-token", "req-123", "2025-01-01 00:00:00");
});
it("should return the data from the API response", async () => {
const mockData = { messages: [{ role: "user", content: "hello" }], response: { id: "resp-1" } };
mockApiCall.mockResolvedValue(mockData);
const { result } = renderHook(
() => useLogDetails("req-456", "2025-01-02 12:00:00", true),
{ wrapper: makeWrapper() },
);
const { result } = renderHook(() => useLogDetails("req-456", "2025-01-02 12:00:00", true), {
wrapper: makeWrapper(),
});
await waitFor(() => expect(result.current.isSuccess).toBe(true));
@ -115,8 +101,7 @@ describe("useLogDetails — conditional lazy loading", () => {
it("should transition from disabled to enabled and trigger the API call", async () => {
const { result, rerender } = renderHook(
({ enabled }: { enabled: boolean }) =>
useLogDetails("req-789", "2025-01-03 00:00:00", enabled),
({ enabled }: { enabled: boolean }) => useLogDetails("req-789", "2025-01-03 00:00:00", enabled),
{ wrapper: makeWrapper(), initialProps: { enabled: false } },
);
@ -132,14 +117,17 @@ describe("useLogDetails — conditional lazy loading", () => {
it("should expose isLoading=true while the API call is in progress", async () => {
// Make the API call never resolve during this check
let resolveCall!: (v: any) => void;
mockApiCall.mockReturnValue(new Promise((res) => { resolveCall = res; }));
const { result } = renderHook(
() => useLogDetails("req-loading", "2025-01-04 00:00:00", true),
{ wrapper: makeWrapper() },
let resolveCall!: (v: { messages: unknown[]; response: Record<string, unknown> }) => void;
mockApiCall.mockReturnValue(
new Promise((res) => {
resolveCall = res;
}),
);
const { result } = renderHook(() => useLogDetails("req-loading", "2025-01-04 00:00:00", true), {
wrapper: makeWrapper(),
});
await waitFor(() => expect(result.current.isLoading).toBe(true));
// Clean up — resolve the pending promise to avoid open handles

View file

@ -1,21 +1,21 @@
import React from "react";
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import { renderHook, act, waitFor } from "@testing-library/react";
import { renderHook, act } from "@testing-library/react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { usePaginatedDailyActivity } from "../src/components/UsagePage/hooks/usePaginatedDailyActivity";
function makeWrapper() {
const qc = new QueryClient({ defaultOptions: { queries: { retry: false } } });
return ({ children }: { children: React.ReactNode }) =>
const Wrapper = ({ children }: { children: React.ReactNode }) =>
React.createElement(QueryClientProvider, { client: qc }, children);
Wrapper.displayName = "QueryClientWrapper";
return Wrapper;
}
/** Build a mock page response with controllable totals. */
function mockPage(
page: number,
totalPages: number,
extra: Record<string, any> = {},
) {
function mockPage(page: number, totalPages: number, extra: Record<string, unknown> = {}) {
return {
results: [{ date: `2025-01-0${page}`, spend: page }],
metadata: {