feat(phase7): complete generation web flow and frontend build recovery

This commit is contained in:
Xiaoxia AI
2026-06-18 21:50:52 +08:00
parent 7f2f52bad8
commit 2f4d63eba5
19 changed files with 327 additions and 136 deletions
+11 -11
View File
@@ -2,19 +2,19 @@
* Login 组件单元测试
*/
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';
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 queryClient = new QueryClient({
defaultOptions: {
queries: { retry: false },
mutations: { retry: false },
},
});
const renderLogin = () => {
const queryClient = new QueryClient({
defaultOptions: {
queries: { retry: false },
mutations: { retry: false },
},
});
return render(
<QueryClientProvider client={queryClient}>
<BrowserRouter>
@@ -27,7 +27,7 @@ const renderLogin = () => {
describe('Login Component', () => {
it('should render login form', () => {
renderLogin();
expect(screen.getByPlaceholderText('邮箱')).toBeInTheDocument();
expect(screen.getByPlaceholderText('密码')).toBeInTheDocument();
expect(screen.getByRole('button', { name: '登录' })).toBeInTheDocument();
@@ -35,7 +35,7 @@ describe('Login Component', () => {
it('should show validation errors for empty fields', async () => {
renderLogin();
const submitButton = screen.getByRole('button', { name: '登录' });
fireEvent.click(submitButton);
@@ -47,7 +47,7 @@ describe('Login Component', () => {
it('should navigate to register page', () => {
renderLogin();
const registerLink = screen.getByText('立即注册');
expect(registerLink).toBeInTheDocument();
});
@@ -2,7 +2,7 @@
* WorkspaceList 组件单元测试
*/
import { render, screen, waitFor } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { BrowserRouter } from 'react-router-dom';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import WorkspaceList from '@/pages/workspace/WorkspaceList';
@@ -10,13 +10,13 @@ import * as workspaceApi from '@/api/workspace';
vi.mock('@/api/workspace');
const queryClient = new QueryClient({
defaultOptions: {
queries: { retry: false },
},
});
const renderWorkspaceList = () => {
const queryClient = new QueryClient({
defaultOptions: {
queries: { retry: false },
},
});
return render(
<QueryClientProvider client={queryClient}>
<BrowserRouter>
@@ -27,23 +27,23 @@ const renderWorkspaceList = () => {
};
describe('WorkspaceList', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('should render workspace list', async () => {
const mockWorkspaces = [
const mockWorkspaces: workspaceApi.Workspace[] = [
{
id: '1',
name: 'Test Workspace',
owner_user_id: 'user-1',
subscription_plan: 'free',
subscription_status: 'active',
created_at: '2024-01-01',
},
];
vi.mocked(workspaceApi.getWorkspaces).mockResolvedValue({
items: mockWorkspaces,
total: 1,
page: 1,
page_size: 10,
});
vi.mocked(workspaceApi.getWorkspaces).mockResolvedValue(mockWorkspaces);
renderWorkspaceList();
@@ -52,9 +52,13 @@ describe('WorkspaceList', () => {
});
});
it('should show create workspace button', () => {
it('should show create workspace button', async () => {
vi.mocked(workspaceApi.getWorkspaces).mockResolvedValue([]);
renderWorkspaceList();
expect(screen.getByText('创建工作空间')).toBeInTheDocument();
await waitFor(() => {
expect(screen.getByText('创建工作空间')).toBeInTheDocument();
});
});
});