ci: Prettier纳入两层防御体系 (#520)
CI Build & Deploy Pipeline / Staging E2E Tests (push) Failing after 2m50s
CI Build & Deploy Pipeline / Production Browser E2E (push) Failing after 1437h19m24s
CI Build & Deploy Pipeline / Build Production Web Image (push) Failing after 1437h19m26s
CI Build & Deploy Pipeline / Deploy Production (push) Failing after 1437h19m25s
CI Build & Deploy Pipeline / Build Production API Image (push) Failing after 1437h19m26s
CI/CD Pipeline / Check if frontend-only change (push) Failing after 1437h21m16s
CI Build & Deploy Pipeline / Build Staging API Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Staging Web Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Staging Worker Image (push) Has been skipped
CI Build & Deploy Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Has been skipped
CI Build & Deploy Pipeline / Staging API Integration Tests (push) Has been skipped
CI Build & Deploy Pipeline / Build Production Worker Image (push) Failing after 1437h51m29s
CI/CD Pipeline / Validate Code Quality And Tests (push) Has been skipped
CI/CD Pipeline / Unit Tests (push) Has been skipped
CI/CD Pipeline / Integration Tests (push) Has been skipped
CI/CD Pipeline / Frontend Lint (push) Has been skipped
CI Build & Deploy Pipeline / Staging E2E Tests (push) Failing after 2m50s
CI Build & Deploy Pipeline / Production Browser E2E (push) Failing after 1437h19m24s
CI Build & Deploy Pipeline / Build Production Web Image (push) Failing after 1437h19m26s
CI Build & Deploy Pipeline / Deploy Production (push) Failing after 1437h19m25s
CI Build & Deploy Pipeline / Build Production API Image (push) Failing after 1437h19m26s
CI/CD Pipeline / Check if frontend-only change (push) Failing after 1437h21m16s
CI Build & Deploy Pipeline / Build Staging API Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Staging Web Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Staging Worker Image (push) Has been skipped
CI Build & Deploy Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Has been skipped
CI Build & Deploy Pipeline / Staging API Integration Tests (push) Has been skipped
CI Build & Deploy Pipeline / Build Production Worker Image (push) Failing after 1437h51m29s
CI/CD Pipeline / Validate Code Quality And Tests (push) Has been skipped
CI/CD Pipeline / Unit Tests (push) Has been skipped
CI/CD Pipeline / Integration Tests (push) Has been skipped
CI/CD Pipeline / Frontend Lint (push) Has been skipped
Co-authored-by: xiaoxia <dev@xiaoxiajianji.com> Co-committed-by: xiaoxia <dev@xiaoxiajianji.com>
This commit was merged in pull request #520.
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
/**
|
||||
* Login 组件单元测试
|
||||
*/
|
||||
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import Login from "@/pages/auth/Login";
|
||||
import { render, screen, fireEvent, waitFor } from "@testing-library/react"
|
||||
import { describe, it, expect } from "vitest"
|
||||
import { BrowserRouter } from "react-router-dom"
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
|
||||
import Login from "@/pages/auth/Login"
|
||||
|
||||
const renderLogin = () => {
|
||||
const queryClient = new QueryClient({
|
||||
@@ -13,7 +13,7 @@ const renderLogin = () => {
|
||||
queries: { retry: false },
|
||||
mutations: { retry: false },
|
||||
},
|
||||
});
|
||||
})
|
||||
|
||||
return render(
|
||||
<QueryClientProvider client={queryClient}>
|
||||
@@ -21,34 +21,34 @@ const renderLogin = () => {
|
||||
<Login />
|
||||
</BrowserRouter>
|
||||
</QueryClientProvider>,
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
describe.skip("Login Component", () => {
|
||||
it("should render login form", () => {
|
||||
renderLogin();
|
||||
renderLogin()
|
||||
|
||||
expect(screen.getByPlaceholderText("邮箱")).toBeInTheDocument();
|
||||
expect(screen.getByPlaceholderText("密码")).toBeInTheDocument();
|
||||
expect(screen.getByRole("button", { name: "登录" })).toBeInTheDocument();
|
||||
});
|
||||
expect(screen.getByPlaceholderText("邮箱")).toBeInTheDocument()
|
||||
expect(screen.getByPlaceholderText("密码")).toBeInTheDocument()
|
||||
expect(screen.getByRole("button", { name: "登录" })).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it("should show validation errors for empty fields", async () => {
|
||||
renderLogin();
|
||||
renderLogin()
|
||||
|
||||
const submitButton = screen.getByRole("button", { name: "登录" });
|
||||
fireEvent.click(submitButton);
|
||||
const submitButton = screen.getByRole("button", { name: "登录" })
|
||||
fireEvent.click(submitButton)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("请输入邮箱")).toBeInTheDocument();
|
||||
expect(screen.getByText("请输入密码")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
expect(screen.getByText("请输入邮箱")).toBeInTheDocument()
|
||||
expect(screen.getByText("请输入密码")).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
it("should navigate to register page", () => {
|
||||
renderLogin();
|
||||
renderLogin()
|
||||
|
||||
const registerLink = screen.getByText("立即注册");
|
||||
expect(registerLink).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
const registerLink = screen.getByText("立即注册")
|
||||
expect(registerLink).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
/**
|
||||
* useAuth Hook 单元测试
|
||||
*/
|
||||
import { renderHook, waitFor } from "@testing-library/react";
|
||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
||||
import { useLogin, useRegister, useLogout } from "@/hooks/useAuth";
|
||||
import * as authApi from "@/api/auth";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
import React from "react";
|
||||
import { renderHook, waitFor } from "@testing-library/react"
|
||||
import { describe, it, expect, vi, beforeEach } from "vitest"
|
||||
import { useLogin, useRegister, useLogout } from "@/hooks/useAuth"
|
||||
import * as authApi from "@/api/auth"
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
|
||||
import { BrowserRouter } from "react-router-dom"
|
||||
import React from "react"
|
||||
|
||||
// Mock API
|
||||
vi.mock("@/api/auth");
|
||||
vi.mock("@/api/auth")
|
||||
vi.mock("react-router-dom", async () => {
|
||||
const actual = await vi.importActual("react-router-dom");
|
||||
const actual = await vi.importActual("react-router-dom")
|
||||
return {
|
||||
...actual,
|
||||
useNavigate: () => vi.fn(),
|
||||
};
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
// Test wrapper
|
||||
const createWrapper = () => {
|
||||
@@ -26,19 +26,19 @@ const createWrapper = () => {
|
||||
queries: { retry: false },
|
||||
mutations: { retry: false },
|
||||
},
|
||||
});
|
||||
})
|
||||
return ({ children }: { children: React.ReactNode }) => (
|
||||
<BrowserRouter>
|
||||
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
||||
</BrowserRouter>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
describe.skip("useAuth", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
localStorage.clear();
|
||||
});
|
||||
vi.clearAllMocks()
|
||||
localStorage.clear()
|
||||
})
|
||||
|
||||
it("should login successfully", async () => {
|
||||
const mockResponse = {
|
||||
@@ -49,26 +49,26 @@ describe.skip("useAuth", () => {
|
||||
email: "test@example.com",
|
||||
username: "testuser",
|
||||
display_name: "Test User",
|
||||
};
|
||||
}
|
||||
|
||||
vi.mocked(authApi.login).mockResolvedValue(mockResponse);
|
||||
vi.mocked(authApi.login).mockResolvedValue(mockResponse)
|
||||
vi.mocked(authApi.getCurrentUser).mockResolvedValue({
|
||||
id: "1",
|
||||
email: "test@example.com",
|
||||
username: "testuser",
|
||||
display_name: "Test User",
|
||||
});
|
||||
})
|
||||
|
||||
const { result } = renderHook(() => useLogin(), {
|
||||
wrapper: createWrapper(),
|
||||
});
|
||||
})
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current).toBeDefined();
|
||||
});
|
||||
expect(result.current).toBeDefined()
|
||||
})
|
||||
|
||||
expect(authApi.login).toBeDefined();
|
||||
});
|
||||
expect(authApi.login).toBeDefined()
|
||||
})
|
||||
|
||||
it("should register successfully", async () => {
|
||||
const mockResponse = {
|
||||
@@ -77,34 +77,34 @@ describe.skip("useAuth", () => {
|
||||
username: "testuser",
|
||||
display_name: "Test User",
|
||||
message: "注册成功",
|
||||
};
|
||||
}
|
||||
|
||||
vi.mocked(authApi.register).mockResolvedValue(mockResponse);
|
||||
vi.mocked(authApi.register).mockResolvedValue(mockResponse)
|
||||
|
||||
const { result } = renderHook(() => useRegister(), {
|
||||
wrapper: createWrapper(),
|
||||
});
|
||||
})
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current).toBeDefined();
|
||||
});
|
||||
expect(result.current).toBeDefined()
|
||||
})
|
||||
|
||||
expect(authApi.register).toBeDefined();
|
||||
});
|
||||
expect(authApi.register).toBeDefined()
|
||||
})
|
||||
|
||||
it("should logout successfully", async () => {
|
||||
localStorage.setItem("access_token", "mock-token");
|
||||
localStorage.setItem("access_token", "mock-token")
|
||||
|
||||
vi.mocked(authApi.logout).mockResolvedValue(undefined);
|
||||
vi.mocked(authApi.logout).mockResolvedValue(undefined)
|
||||
|
||||
const { result } = renderHook(() => useLogout(), {
|
||||
wrapper: createWrapper(),
|
||||
});
|
||||
})
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current).toBeDefined();
|
||||
});
|
||||
expect(result.current).toBeDefined()
|
||||
})
|
||||
|
||||
expect(authApi.logout).toBeDefined();
|
||||
});
|
||||
});
|
||||
expect(authApi.logout).toBeDefined()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/**
|
||||
* 测试环境设置
|
||||
*/
|
||||
import { expect, afterEach } from "vitest";
|
||||
import { cleanup } from "@testing-library/react";
|
||||
import * as matchers from "@testing-library/jest-dom/matchers";
|
||||
import { expect, afterEach } from "vitest"
|
||||
import { cleanup } from "@testing-library/react"
|
||||
import * as matchers from "@testing-library/jest-dom/matchers"
|
||||
|
||||
// Mock window.matchMedia for Ant Design components
|
||||
Object.defineProperty(window, "matchMedia", {
|
||||
@@ -18,15 +18,15 @@ Object.defineProperty(window, "matchMedia", {
|
||||
removeEventListener: () => {},
|
||||
dispatchEvent: () => false,
|
||||
}),
|
||||
});
|
||||
})
|
||||
|
||||
// 扩展 Vitest 的 expect
|
||||
expect.extend(matchers);
|
||||
expect.extend(matchers)
|
||||
|
||||
// 每次测试后清理
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
});
|
||||
cleanup()
|
||||
})
|
||||
|
||||
// 全局类型声明
|
||||
declare global {
|
||||
@@ -40,4 +40,4 @@ declare global {
|
||||
}
|
||||
|
||||
// 导出空对象以使文件成为模块
|
||||
export {};
|
||||
export {}
|
||||
|
||||
Reference in New Issue
Block a user