fix(web): null-guard в мутациях (no active project), AuthContext различает 401 и ошибки сервера
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BwxdSt4reTm7Dj1oxRvpP3
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
import { renderHook, waitFor } from "@testing-library/react"
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
|
||||
import { describe, it, expect, vi, beforeEach } from "vitest"
|
||||
import type { ReactNode } from "react"
|
||||
import { AuthProvider } from "@/auth/AuthContext"
|
||||
import { api, UnauthorizedError } from "@/api/client"
|
||||
import { useDeleteAccount } from "./useApi"
|
||||
|
||||
beforeEach(() => {
|
||||
vi.restoreAllMocks()
|
||||
})
|
||||
|
||||
function wrapper({ children }: { children: ReactNode }) {
|
||||
const qc = new QueryClient({ defaultOptions: { mutations: { retry: false } } })
|
||||
return (
|
||||
<QueryClientProvider client={qc}>
|
||||
<AuthProvider>{children}</AuthProvider>
|
||||
</QueryClientProvider>
|
||||
)
|
||||
}
|
||||
|
||||
describe("useApi mutations — null project guard", () => {
|
||||
it("mutate() without an active project fails with a clear error, not a TypeError", async () => {
|
||||
// No session yet => AuthContext resolves project to null.
|
||||
vi.spyOn(api.auth, "me").mockRejectedValue(new UnauthorizedError())
|
||||
vi.spyOn(api, "deleteAccount")
|
||||
|
||||
const { result } = renderHook(() => useDeleteAccount(), { wrapper })
|
||||
|
||||
result.current.mutate("acc-1")
|
||||
|
||||
await waitFor(() => expect(result.current.isError).toBe(true))
|
||||
|
||||
expect(result.current.error).toBeInstanceOf(Error)
|
||||
expect(result.current.error).not.toBeInstanceOf(TypeError)
|
||||
expect((result.current.error as Error).message).toBe("no active project")
|
||||
expect(api.deleteAccount).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user