diff --git a/apps/desktop/src/components/__tests__/EnhancedChatMessageV2.test.tsx b/apps/desktop/src/components/__tests__/EnhancedChatMessageV2.test.tsx
deleted file mode 100644
index 0f9bb2e..0000000
--- a/apps/desktop/src/components/__tests__/EnhancedChatMessageV2.test.tsx
+++ /dev/null
@@ -1,140 +0,0 @@
-import { render, screen, fireEvent } from '@testing-library/react';
-import '@testing-library/jest-dom';
-import { describe, test, expect, vi } from 'vitest';
-import { EnhancedChatMessageV2 } from '../EnhancedChatMessageV2';
-
-// Mock 数据
-const mockUserMessage = {
- id: '1',
- type: 'user' as const,
- content: '请推荐一些夏日穿搭',
- timestamp: new Date('2024-01-01T10:00:00Z'),
- status: 'sent' as const
-};
-
-const mockAssistantMessage = {
- id: '2',
- type: 'assistant' as const,
- content: '夏日穿搭建议:选择轻薄透气的面料,如棉麻材质。推荐搭配清爽的色彩,如白色、浅蓝色等。',
- timestamp: new Date('2024-01-01T10:01:00Z'),
- status: 'sent' as const,
- metadata: {
- responseTime: 1500,
- modelUsed: 'gemini-pro',
- sources: [
- {
- title: '夏日穿搭指南',
- uri: 'https://example.com/summer-style.jpg',
- content: {
- type: 'image',
- image_url: 'https://example.com/summer-style.jpg',
- description: '清爽夏日穿搭示例'
- }
- }
- ],
- grounding_metadata: {
- grounding_supports: [
- {
- start_index: 0,
- end_index: 20,
- grounding_chunk_indices: [0]
- }
- ],
- sources: [
- {
- chunk_index: 0,
- title: '夏日穿搭指南',
- uri: 'https://example.com/summer-style.jpg',
- content: {
- type: 'image',
- image_url: 'https://example.com/summer-style.jpg',
- description: '清爽夏日穿搭示例'
- }
- }
- ]
- }
- }
-};
-
-describe('EnhancedChatMessageV2', () => {
- test('渲染用户消息', () => {
- render();
-
- expect(screen.getByText('请推荐一些夏日穿搭')).toBeInTheDocument();
- expect(screen.getByText('10:00')).toBeInTheDocument();
- });
-
- test('渲染助手消息', () => {
- render();
-
- expect(screen.getByText(/夏日穿搭建议/)).toBeInTheDocument();
- expect(screen.getByText('10:01')).toBeInTheDocument();
- expect(screen.getByText('• 响应时间: 1500ms')).toBeInTheDocument();
- expect(screen.getByText('• gemini-pro')).toBeInTheDocument();
- });
-
- test('显示素材来源', () => {
- render(
-
- );
-
- expect(screen.getByText('相关素材 (1)')).toBeInTheDocument();
- });
-
- test('复制消息功能', async () => {
- // Mock clipboard API
- const mockWriteText = vi.fn().mockImplementation(() => Promise.resolve());
- Object.assign(navigator, {
- clipboard: {
- writeText: mockWriteText,
- },
- });
-
- render();
-
- const copyButton = screen.getByTitle('复制消息');
- fireEvent.click(copyButton);
-
- expect(mockWriteText).toHaveBeenCalledWith('请推荐一些夏日穿搭');
- });
-
- test('展开/收起素材来源', () => {
- render(
-
- );
-
- // 检查是否显示了素材来源标题
- expect(screen.getByText('相关素材 (1)')).toBeInTheDocument();
- });
-
- test('角标引用功能', () => {
- render(
-
- );
-
- // 检查是否渲染了消息内容
- expect(screen.getByText(/夏日穿搭建议/)).toBeInTheDocument();
- });
-
- test('发送中状态显示', () => {
- const sendingMessage = {
- ...mockUserMessage,
- status: 'sending' as const
- };
-
- render();
-
- expect(screen.getByText('发送中...')).toBeInTheDocument();
- });
-});
diff --git a/apps/desktop/src/components/__tests__/ProjectCard.test.tsx b/apps/desktop/src/components/__tests__/ProjectCard.test.tsx
deleted file mode 100644
index 2466808..0000000
--- a/apps/desktop/src/components/__tests__/ProjectCard.test.tsx
+++ /dev/null
@@ -1,120 +0,0 @@
-import { describe, it, expect, vi, beforeEach } from 'vitest';
-import { render, screen, fireEvent } from '@testing-library/react';
-import { ProjectCard } from '../ProjectCard';
-import { Project } from '../../types/project';
-
-// Mock date-fns
-vi.mock('date-fns', () => ({
- formatDistanceToNow: vi.fn(() => '2 天前'),
-}));
-
-vi.mock('date-fns/locale', () => ({
- zhCN: {},
-}));
-
-const mockProject: Project = {
- id: '1',
- name: 'Test Project',
- path: '/path/to/project',
- description: 'Test description',
- created_at: '2023-01-01T00:00:00Z',
- updated_at: '2023-01-02T00:00:00Z',
- is_active: true,
-};
-
-const mockProps = {
- project: mockProject,
- onOpen: vi.fn(),
- onEdit: vi.fn(),
- onDelete: vi.fn(),
-};
-
-describe('ProjectCard', () => {
- beforeEach(() => {
- vi.clearAllMocks();
- });
-
- it('renders project information correctly', () => {
- render();
-
- expect(screen.getByText('Test Project')).toBeInTheDocument();
- expect(screen.getByText('Test description')).toBeInTheDocument();
- expect(screen.getByText('project')).toBeInTheDocument();
- expect(screen.getByText('2 天前')).toBeInTheDocument();
- });
-
- it('calls onOpen when open button is clicked', () => {
- render();
-
- const openButton = screen.getByText('打开');
- fireEvent.click(openButton);
-
- expect(mockProps.onOpen).toHaveBeenCalledWith(mockProject);
- });
-
- it('calls onEdit when edit button is clicked', () => {
- render();
-
- const editButton = screen.getByText('编辑');
- fireEvent.click(editButton);
-
- expect(mockProps.onEdit).toHaveBeenCalledWith(mockProject);
- });
-
- it('renders without description', () => {
- const projectWithoutDescription = { ...mockProject, description: undefined };
- render();
-
- expect(screen.getByText('Test Project')).toBeInTheDocument();
- expect(screen.queryByText('Test description')).not.toBeInTheDocument();
- });
-
- it('shows menu when more button is clicked', () => {
- render();
-
- // 找到更多按钮并点击 - 使用更通用的选择器
- const moreButtons = screen.getAllByRole('button');
- const moreButton = moreButtons.find(button =>
- button.querySelector('svg') && !button.textContent?.includes('编辑') && !button.textContent?.includes('打开')
- );
-
- if (moreButton) {
- fireEvent.click(moreButton);
-
- // 检查菜单项是否显示
- expect(screen.getByText('打开项目')).toBeInTheDocument();
- expect(screen.getAllByText('编辑')).toHaveLength(2); // 一个在菜单中,一个在按钮中
- expect(screen.getByText('删除')).toBeInTheDocument();
- }
- });
-
- it('calls onDelete when delete menu item is clicked', () => {
- render();
-
- // 打开菜单
- const moreButtons = screen.getAllByRole('button');
- const moreButton = moreButtons.find(button =>
- button.querySelector('svg') && !button.textContent?.includes('编辑') && !button.textContent?.includes('打开')
- );
-
- if (moreButton) {
- fireEvent.click(moreButton);
-
- // 点击删除
- const deleteButton = screen.getByText('删除');
- fireEvent.click(deleteButton);
-
- expect(mockProps.onDelete).toHaveBeenCalledWith(mockProject.id);
- }
- });
-
- it('extracts directory name correctly', () => {
- const projectWithWindowsPath = {
- ...mockProject,
- path: 'C:\\Users\\test\\MyProject',
- };
-
- render();
- expect(screen.getByText('MyProject')).toBeInTheDocument();
- });
-});
diff --git a/apps/desktop/src/components/__tests__/TaskCard.test.tsx b/apps/desktop/src/components/__tests__/TaskCard.test.tsx
deleted file mode 100644
index 4a8b056..0000000
--- a/apps/desktop/src/components/__tests__/TaskCard.test.tsx
+++ /dev/null
@@ -1,117 +0,0 @@
-import React from 'react';
-import { render, screen, fireEvent } from '@testing-library/react';
-import '@testing-library/jest-dom';
-import TaskCard from '../TaskCard';
-import { TaskDetail } from '../../types/uniComfyui';
-
-// Mock the service
-jest.mock('../../services/uniComfyuiService', () => ({
- UniComfyUIService: {
- formatTaskStatus: jest.fn((status: string) => ({
- text: status === 'completed' ? '已完成' : '执行中',
- color: status === 'completed' ? 'text-green-600' : 'text-blue-600'
- })),
- getTaskStatusIcon: jest.fn(() => '✅'),
- formatTaskExecutionTime: jest.fn(() => '2分钟'),
- formatFileSize: jest.fn(() => '1.2 MB'),
- isImageFile: jest.fn(() => true),
- isVideoFile: jest.fn(() => false),
- generatePreviewUrl: jest.fn(() => '/test-image.jpg')
- }
-}));
-
-const mockTask: TaskDetail = {
- id: 1,
- workflow_run_id: 'test-task-123',
- workflow_name: 'Test Workflow',
- task_type: 'single',
- status: 'completed',
- input_params: {},
- created_at: '2024-01-01T10:00:00Z',
- started_at: '2024-01-01T10:01:00Z',
- completed_at: '2024-01-01T10:03:00Z',
- result_files: [
- {
- id: 'file-1',
- task_id: 'test-task-123',
- file_name: 'result.jpg',
- file_path: '/path/to/result.jpg',
- file_url: 'http://example.com/result.jpg',
- file_type: 'image',
- file_size: 1024000,
- mime_type: 'image/jpeg',
- created_at: '2024-01-01T10:03:00Z',
- thumbnail_url: 'http://example.com/thumb.jpg'
- }
- ]
-};
-
-describe('TaskCard', () => {
- it('renders task information correctly', () => {
- render();
-
- expect(screen.getByText('Test Workflow')).toBeInTheDocument();
- expect(screen.getByText('ID: test-task-123')).toBeInTheDocument();
- expect(screen.getByText('单个任务')).toBeInTheDocument();
- });
-
- it('calls onViewDetail when view button is clicked', () => {
- const mockOnViewDetail = jest.fn();
- render();
-
- const viewButton = screen.getByTitle('查看详情');
- fireEvent.click(viewButton);
-
- expect(mockOnViewDetail).toHaveBeenCalledWith(mockTask);
- });
-
- it('calls onDownload when download button is clicked', () => {
- const mockOnDownload = jest.fn();
- render();
-
- const downloadButton = screen.getByTitle('下载结果');
- fireEvent.click(downloadButton);
-
- expect(mockOnDownload).toHaveBeenCalledWith(mockTask);
- });
-
- it('shows retry button for failed tasks', () => {
- const failedTask = { ...mockTask, status: 'failed' as const };
- const mockOnRetry = jest.fn();
-
- render();
-
- const retryButton = screen.getByTitle('重试任务');
- expect(retryButton).toBeInTheDocument();
-
- fireEvent.click(retryButton);
- expect(mockOnRetry).toHaveBeenCalledWith(failedTask);
- });
-
- it('displays error message for failed tasks', () => {
- const failedTask = {
- ...mockTask,
- status: 'failed' as const,
- error_message: 'Task execution failed'
- };
-
- render();
-
- expect(screen.getByText('Task execution failed')).toBeInTheDocument();
- });
-
- it('renders in compact mode', () => {
- render();
-
- // In compact mode, the task name should have smaller text
- const taskName = screen.getByText('Test Workflow');
- expect(taskName).toHaveClass('text-sm');
- });
-
- it('hides actions when showActions is false', () => {
- render();
-
- expect(screen.queryByTitle('查看详情')).not.toBeInTheDocument();
- expect(screen.queryByTitle('下载结果')).not.toBeInTheDocument();
- });
-});