Skip to content

Commit

Permalink
test(user-user): add unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
TinsFox committed Nov 3, 2024
1 parent 3bf044b commit cccd959
Show file tree
Hide file tree
Showing 2 changed files with 155 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,7 @@ dist-ssr
#vitepress
docs/.vitepress/dist
docs/.vitepress/cache


# vitest
coverage/
151 changes: 151 additions & 0 deletions src/hooks/query/use-user.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
import { renderHook, waitFor } from "@testing-library/react"
import type { ReactNode } from "react"
import * as router from "react-router-dom"
import { beforeEach, describe, expect, it, vi } from "vitest"

import { apiFetch } from "@/lib/api-fetch"

import { useUser, useUserLoginMutation, useUserLogoutMutation, useUsers } from "./use-user"

// Mock apiFetch
vi.mock("@/lib/api-fetch")
// Mock useNavigate
vi.mock("react-router-dom")

describe("User Hooks", () => {
let queryClient: QueryClient

beforeEach(() => {
queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: false,
},
},
})
vi.clearAllMocks()
})

// 测试包装器
const createWrapper = () => {
return function Wrapper({ children }: { children: ReactNode }) {
return (
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
)
}
}

describe("useUser", () => {
it("should fetch user info successfully", async () => {
const mockUserData = {
id: 1,
name: "Test User",
email: "[email protected]",
}

// Mock API response
vi.mocked(apiFetch).mockResolvedValueOnce(mockUserData)

const { result } = renderHook(() => useUser(), {
wrapper: createWrapper(),
})

await waitFor(() => {
expect(result.current.data).toEqual(mockUserData)
})

expect(apiFetch).toHaveBeenCalledWith("/api/user/info")
})
})

describe("useUserLoginMutation", () => {
it("should handle login mutation", async () => {
const mockLoginResponse = { token: "test-token" }
vi.mocked(apiFetch).mockResolvedValueOnce(mockLoginResponse)

const { result } = renderHook(() => useUserLoginMutation(), {
wrapper: createWrapper(),
})

const loginData = { email: "[email protected]", password: "password" }
result.current.mutate(loginData)

await waitFor(() => {
expect(apiFetch).toHaveBeenCalledWith("/api/auth/login", {
method: "POST",
body: loginData,
})
})
})
})

describe("useUserLogoutMutation", () => {
it("should handle logout mutation", async () => {
const mockNavigate = vi.fn()
vi.spyOn(router, "useNavigate").mockImplementation(() => mockNavigate)
vi.mocked(apiFetch).mockResolvedValueOnce({})

const { result } = renderHook(() => useUserLogoutMutation(), {
wrapper: createWrapper(),
})

result.current.mutate()

await waitFor(() => {
expect(apiFetch).toHaveBeenCalledWith("/api/logout")
expect(mockNavigate).toHaveBeenCalledWith("/login")
})
})
})

describe("useUsers", () => {
it("should fetch users list with pagination", async () => {
const mockUsersData = {
list: [{ id: 1, name: "User 1" }],
total: 1,
page: 0,
pageSize: 10,
}

vi.mocked(apiFetch).mockResolvedValueOnce(mockUsersData)

const pagination = { pageIndex: 0, pageSize: 10 }
const { result } = renderHook(() => useUsers(pagination), {
wrapper: createWrapper(),
})

await waitFor(() => {
expect(result.current.data).toEqual(mockUsersData)
expect(result.current.isPending).toBe(false)
})

expect(apiFetch).toHaveBeenCalledWith("/api/team-users", {
params: {
page: pagination.pageIndex,
pageSize: pagination.pageSize,
},
})
})

it("should return default values when data is undefined", async () => {
vi.mocked(apiFetch).mockResolvedValueOnce()

const pagination = { pageIndex: 0, pageSize: 10 }
const { result } = renderHook(() => useUsers(pagination), {
wrapper: createWrapper(),
})

await waitFor(() => {
expect(result.current.data).toEqual({
list: [],
total: 0,
page: 0,
pageSize: 0,
})
})
})
})
})

0 comments on commit cccd959

Please sign in to comment.