import { MutationCache, QueryCache, QueryClient, QueryClientProvider, useQuery } from "@tanstack/react-query"; import { render } from "@testing-library/react"; import { describe, expect, test } from "bun:test"; import { createElement, useRef } from "react"; import { useCreateProject } from "../../../src/web/shared/hooks/use-projects"; import { installFetchMock, jsonResponse } from "../test-utils"; describe("QueryClient MutationCache onError", () => { test("mutation 错误触发 MutationCache onError 回调", async () => { installFetchMock(() => jsonResponse({ error: "项目名称已存在" }, { status: 409 })); const errors: string[] = []; const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } }, mutationCache: new MutationCache({ onError: (error: Error) => { errors.push(error.message); }, }), }); function TestComponent({ onResult }: { onResult: (mutate: () => void) => void }) { const { mutate } = useCreateProject(); const called = useRef(false); if (!called.current) { called.current = true; onResult(() => { mutate( { name: "test" }, { onError: () => {}, }, ); }); } return null; } render( createElement( QueryClientProvider, { client: queryClient }, createElement(TestComponent, { onResult: (fn) => fn() }), ), ); await new Promise((resolve) => setTimeout(resolve, 200)); expect(errors.length).toBe(1); expect(errors[0]).toBe("项目名称已存在"); }); }); describe("QueryClient QueryCache onError", () => { test("query 错误触发 QueryCache onError 回调", async () => { installFetchMock(() => new Response("broken", { status: 500 })); const errors: string[] = []; const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } }, queryCache: new QueryCache({ onError: (error: Error) => { errors.push(error.message); }, }), }); function TestComponent({ onResult }: { onResult: (trigger: () => void) => void }) { const called = useRef(false); useQuery({ queryFn: () => Promise.reject(new Error("test query error")), queryKey: ["test-query-error"], }); if (!called.current) { called.current = true; onResult(() => { // no-op trigger }); } return null; } render( createElement( QueryClientProvider, { client: queryClient }, createElement(TestComponent, { onResult: (fn) => fn() }), ), ); await new Promise((resolve) => setTimeout(resolve, 200)); expect(errors.length).toBe(1); expect(errors[0]).toBe("test query error"); }); });