fix(build): JellyseerStatsResponse export/import spelling + test mock type

The frontend production build (tsc -b) was failing, which blocked deployment:

- api/jellyseerr.ts exported `JellyseerrStatsResponse` (double-r) while every
  import used `JellyseerStatsResponse` (single-r) — a mismatch TS reported as
  "no exported member" (with a misleading identical-name suggestion). The
  sibling types (JellyseerStat, JellyseerRecentRequest) are single-r, so
  align the export to single-r. (tsc --noEmit missed it because the root
  tsconfig is solution-style; tsc -b builds the app project and catches it.)
- RequestsTab.test.tsx's useJellyseerrStats mock returned a partial object
  that didn't satisfy UseQueryResult's full shape; cast via a typed helper.

`npm run build` (tsc -b && vite build) now succeeds; 184/184 tests + ESLint clean.
This commit is contained in:
Developer
2026-07-12 16:30:59 +00:00
parent e757f4ba21
commit 54851779fb
4 changed files with 28 additions and 16 deletions
@@ -2,6 +2,7 @@ import { describe, it, expect, vi } from "vitest";
import { render, screen } from "@testing-library/react";
import { RequestsTab } from "../RequestsTab";
import { useJellyseerrStats } from "../../../hooks/useJellyseer";
import type { JellyseerStatsResponse } from "../../../api/jellyseerr";
import type { ServiceInstance } from "../../../types";
// Mock the stats hook so the tab renders without a QueryClientProvider and we
@@ -10,7 +11,16 @@ vi.mock("../../../hooks/useJellyseer", () => ({
useJellyseerrStats: vi.fn(),
}));
const mockUseJellyseerrStats = vi.mocked(useJellyseerrStats);
type StatsResult = ReturnType<typeof useJellyseerrStats>;
function mockStats(result: {
data: JellyseerStatsResponse | undefined;
isLoading: boolean;
error: Error | null;
}) {
// UseQueryResult has many fields; cast the partial we care about.
mockUseJellyseerrStats.mockReturnValue(result as unknown as StatsResult);
}
function makeInstance(
config: Record<string, unknown>,
@@ -30,7 +40,7 @@ function makeInstance(
describe("RequestsTab", () => {
it("shows empty-state CTA when Jellyseerr is not configured", () => {
mockUseJellyseerrStats.mockReturnValue({ data: undefined, isLoading: false, error: null });
mockStats({ data: undefined, isLoading: false, error: null });
render(
<RequestsTab
instance={makeInstance({
@@ -44,7 +54,7 @@ describe("RequestsTab", () => {
});
it("shows empty-state when only URL is set (api key secret missing)", () => {
mockUseJellyseerrStats.mockReturnValue({ data: undefined, isLoading: false, error: null });
mockStats({ data: undefined, isLoading: false, error: null });
render(
<RequestsTab
instance={makeInstance({ jellyseerr_url: "https://requests.example.com" })}
@@ -54,14 +64,20 @@ describe("RequestsTab", () => {
});
it("shows the configured Jellyseerr URL and the stats grid", () => {
mockUseJellyseerrStats.mockReturnValue({
mockStats({
data: {
stats: [
{ key: "pending", label: "Pending", value: 3 },
{ key: "total", label: "Total", value: 42 },
],
recent: [
{ id: 1, name: "Inception", type: "movie", status: "pending", media_status: "available" },
{
id: 1,
name: "Inception",
type: "movie",
status: "pending",
media_status: "available",
},
],
},
isLoading: false,
@@ -83,11 +99,7 @@ describe("RequestsTab", () => {
});
it("surfaces a fetch error", () => {
mockUseJellyseerrStats.mockReturnValue({
data: undefined,
isLoading: false,
error: new Error("boom"),
});
mockStats({ data: undefined, isLoading: false, error: new Error("boom") });
render(
<RequestsTab
instance={makeInstance(