| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486 |
- import { describe, it, expect, vi, beforeEach } from 'vitest';
- import { render, screen, fireEvent, waitFor } from '@testing-library/react';
- import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
- import CompanyManagement from '../../src/components/CompanyManagement';
- import { companyClientManager } from '../../src/api/companyClient';
- // Mock PlatformSelector
- vi.mock('@d8d/allin-platform-management-ui/components', () => ({
- PlatformSelector: vi.fn(({ value, onChange, placeholder, testId }) => (
- <select
- data-testid={testId}
- value={value?.toString() || ''}
- onChange={(e) => onChange?.(parseInt(e.target.value))}
- >
- <option value="">{placeholder || '请选择平台'}</option>
- <option value="1">测试平台</option>
- <option value="2">另一个平台</option>
- </select>
- ))
- }));
- // 完整的mock响应对象
- const createMockResponse = (status: number, data?: any) => ({
- status,
- ok: status >= 200 && status < 300,
- body: null,
- bodyUsed: false,
- statusText: status === 200 ? 'OK' : status === 201 ? 'Created' : status === 204 ? 'No Content' : 'Error',
- headers: new Headers(),
- url: '',
- redirected: false,
- type: 'basic' as ResponseType,
- json: async () => data || {},
- text: async () => '',
- blob: async () => new Blob(),
- arrayBuffer: async () => new ArrayBuffer(0),
- formData: async () => new FormData(),
- clone: function() { return this; }
- });
- // Mock API client
- vi.mock('../../src/api/companyClient', () => {
- const mockCompanyClient = {
- getAllCompanies: {
- $get: vi.fn(() => Promise.resolve(createMockResponse(200, {
- data: [
- {
- id: 1,
- platformId: 1,
- companyName: '测试公司',
- contactPerson: '张三',
- contactPhone: '13800138000',
- contactEmail: 'zhangsan@example.com',
- address: '北京市朝阳区',
- status: 1,
- createTime: '2024-01-01T00:00:00Z',
- updateTime: '2024-01-01T00:00:00Z',
- platform: {
- id: 1,
- platformName: '测试平台'
- }
- }
- ],
- total: 1
- }))),
- },
- searchCompanies: {
- $get: vi.fn(() => Promise.resolve(createMockResponse(200, {
- data: [
- {
- id: 2,
- platformId: 1,
- companyName: '搜索测试公司',
- contactPerson: '李四',
- contactPhone: '13900139000',
- contactEmail: 'lisi@example.com',
- address: '上海市浦东新区',
- status: 1,
- createTime: '2024-01-02T00:00:00Z',
- updateTime: '2024-01-02T00:00:00Z',
- platform: {
- id: 1,
- platformName: '测试平台'
- }
- }
- ],
- total: 1
- }))),
- },
- createCompany: {
- $post: vi.fn(() => Promise.resolve(createMockResponse(200, {
- success: true
- }))),
- },
- updateCompany: {
- $post: vi.fn(() => Promise.resolve(createMockResponse(200, {
- success: true
- }))),
- },
- deleteCompany: {
- $post: vi.fn(() => Promise.resolve(createMockResponse(200, {
- success: true
- }))),
- },
- getCompany: {
- ':id': {
- $get: vi.fn(() => Promise.resolve(createMockResponse(200, {
- id: 1,
- platformId: 1,
- companyName: '测试公司',
- contactPerson: '张三',
- contactPhone: '13800138000',
- contactEmail: 'zhangsan@example.com',
- address: '北京市朝阳区',
- status: 1,
- createTime: '2024-01-01T00:00:00Z',
- updateTime: '2024-01-01T00:00:00Z',
- platform: {
- id: 1,
- platformName: '测试平台'
- }
- }))),
- }
- },
- getCompaniesByPlatform: {
- ':platformId': {
- $get: vi.fn(() => Promise.resolve(createMockResponse(200, []))),
- }
- }
- };
- const mockClientManager = {
- get: vi.fn(() => mockCompanyClient),
- reset: vi.fn()
- };
- return {
- companyClientManager: mockClientManager
- };
- });
- // Mock sonner
- vi.mock('sonner', () => ({
- toast: {
- success: vi.fn(),
- error: vi.fn(),
- warning: vi.fn(),
- info: vi.fn()
- }
- }));
- describe('CompanyManagement 集成测试', () => {
- let queryClient: QueryClient;
- beforeEach(() => {
- queryClient = new QueryClient({
- defaultOptions: {
- queries: {
- retry: false,
- },
- },
- });
- vi.clearAllMocks();
- });
- const renderComponent = () => {
- return render(
- <QueryClientProvider client={queryClient}>
- <CompanyManagement />
- </QueryClientProvider>
- );
- };
- it('应该渲染公司管理页面', async () => {
- renderComponent();
- // 检查页面标题
- expect(screen.getByText('公司管理')).toBeInTheDocument();
- expect(screen.getByText('管理所有公司信息,包括创建、编辑、删除和搜索功能')).toBeInTheDocument();
- // 检查搜索输入框
- expect(screen.getByTestId('search-company-input')).toBeInTheDocument();
- expect(screen.getByTestId('search-company-button')).toBeInTheDocument();
- // 检查创建按钮
- expect(screen.getByTestId('create-company-button')).toBeInTheDocument();
- // 等待数据加载
- await waitFor(() => {
- expect(screen.getByText('测试公司')).toBeInTheDocument();
- });
- // 检查表格列
- expect(screen.getByText('公司名称')).toBeInTheDocument();
- expect(screen.getByText('平台')).toBeInTheDocument();
- expect(screen.getByText('联系人')).toBeInTheDocument();
- expect(screen.getByText('联系电话')).toBeInTheDocument();
- expect(screen.getByText('状态')).toBeInTheDocument();
- expect(screen.getByText('创建时间')).toBeInTheDocument();
- expect(screen.getByText('操作')).toBeInTheDocument();
- });
- it('应该显示公司列表数据', async () => {
- renderComponent();
- // 等待数据加载
- await waitFor(() => {
- expect(screen.getByText('测试公司')).toBeInTheDocument();
- });
- // 检查公司数据
- expect(screen.getByText('测试公司')).toBeInTheDocument();
- expect(screen.getByText('测试平台')).toBeInTheDocument();
- expect(screen.getByText('张三')).toBeInTheDocument();
- expect(screen.getByText('13800138000')).toBeInTheDocument();
- expect(screen.getByText('启用')).toBeInTheDocument();
- });
- it('应该打开创建公司模态框', async () => {
- renderComponent();
- // 点击创建按钮
- fireEvent.click(screen.getByTestId('create-company-button'));
- // 检查模态框标题
- await waitFor(() => {
- expect(screen.getByTestId('company-modal-title')).toHaveTextContent('创建公司');
- });
- // 检查表单字段
- expect(screen.getByTestId('create-company-platform-selector')).toBeInTheDocument();
- expect(screen.getByTestId('create-company-name-input')).toBeInTheDocument();
- expect(screen.getByTestId('create-company-contact-person-input')).toBeInTheDocument();
- expect(screen.getByTestId('create-company-contact-phone-input')).toBeInTheDocument();
- expect(screen.getByTestId('create-company-contact-email-input')).toBeInTheDocument();
- expect(screen.getByTestId('create-company-address-input')).toBeInTheDocument();
- });
- it('应该创建新公司', async () => {
- renderComponent();
- // 打开创建模态框
- fireEvent.click(screen.getByTestId('create-company-button'));
- await waitFor(() => {
- expect(screen.getByTestId('company-modal-title')).toHaveTextContent('创建公司');
- });
- // 填写表单
- fireEvent.change(screen.getByTestId('create-company-platform-selector'), { target: { value: '1' } });
- fireEvent.change(screen.getByTestId('create-company-name-input'), { target: { value: '新公司' } });
- fireEvent.change(screen.getByTestId('create-company-contact-person-input'), { target: { value: '王五' } });
- fireEvent.change(screen.getByTestId('create-company-contact-phone-input'), { target: { value: '13700137000' } });
- fireEvent.change(screen.getByTestId('create-company-contact-email-input'), { target: { value: 'wangwu@example.com' } });
- fireEvent.change(screen.getByTestId('create-company-address-input'), { target: { value: '深圳市南山区' } });
- // 提交表单
- fireEvent.click(screen.getByTestId('submit-create-company-button'));
- // 验证API调用
- await waitFor(() => {
- expect(companyClientManager.get().createCompany.$post).toHaveBeenCalledWith({
- json: expect.objectContaining({
- platformId: 1,
- companyName: '新公司',
- contactPerson: '王五',
- contactPhone: '13700137000',
- contactEmail: 'wangwu@example.com',
- address: '深圳市南山区'
- })
- });
- });
- });
- it('应该打开编辑公司模态框', async () => {
- renderComponent();
- // 等待数据加载
- await waitFor(() => {
- expect(screen.getByText('测试公司')).toBeInTheDocument();
- });
- // 点击编辑按钮
- fireEvent.click(screen.getByTestId('edit-company-button-1'));
- // 检查模态框标题
- await waitFor(() => {
- expect(screen.getByTestId('company-modal-title')).toHaveTextContent('编辑公司');
- });
- // 检查表单字段已填充
- expect(screen.getByTestId('edit-company-name-input')).toHaveValue('测试公司');
- expect(screen.getByTestId('edit-company-contact-person-input')).toHaveValue('张三');
- expect(screen.getByTestId('edit-company-contact-phone-input')).toHaveValue('13800138000');
- });
- it('应该更新公司信息', async () => {
- renderComponent();
- // 等待数据加载
- await waitFor(() => {
- expect(screen.getByText('测试公司')).toBeInTheDocument();
- });
- // 点击编辑按钮
- fireEvent.click(screen.getByTestId('edit-company-button-1'));
- await waitFor(() => {
- expect(screen.getByTestId('company-modal-title')).toHaveTextContent('编辑公司');
- });
- // 修改表单
- fireEvent.change(screen.getByTestId('edit-company-name-input'), { target: { value: '更新后的公司' } });
- fireEvent.change(screen.getByTestId('edit-company-contact-person-input'), { target: { value: '赵六' } });
- // 提交表单
- fireEvent.click(screen.getByTestId('submit-edit-company-button'));
- // 验证API调用
- await waitFor(() => {
- expect(companyClientManager.get().updateCompany.$post).toHaveBeenCalledWith({
- json: expect.objectContaining({
- id: 1,
- companyName: '更新后的公司',
- contactPerson: '赵六'
- })
- });
- });
- });
- it('应该打开删除确认对话框', async () => {
- renderComponent();
- // 等待数据加载
- await waitFor(() => {
- expect(screen.getByText('测试公司')).toBeInTheDocument();
- });
- // 点击删除按钮
- fireEvent.click(screen.getByTestId('delete-company-button-1'));
- // 检查删除确认对话框 - 使用getByRole和getByText
- // 对话框标题(使用heading角色)
- const dialogTitle = screen.getByRole('heading', { name: '确认删除' });
- expect(dialogTitle).toBeInTheDocument();
- // 对话框描述
- expect(screen.getByText('确定要删除这个公司吗?此操作不可恢复。')).toBeInTheDocument();
- // 按钮
- expect(screen.getByTestId('cancel-delete-company-button')).toBeInTheDocument();
- expect(screen.getByTestId('confirm-delete-company-button')).toBeInTheDocument();
- });
- it('应该搜索公司', async () => {
- renderComponent();
- // 输入搜索关键词
- fireEvent.change(screen.getByTestId('search-company-input'), { target: { value: '搜索' } });
- fireEvent.click(screen.getByTestId('search-company-button'));
- // 验证搜索API调用
- await waitFor(() => {
- expect(companyClientManager.get().searchCompanies.$get).toHaveBeenCalledWith({
- query: {
- name: '搜索',
- skip: 0,
- take: 10
- }
- });
- });
- });
- it('应该处理API错误', async () => {
- // Mock API错误
- (companyClientManager.get().getAllCompanies.$get as any).mockImplementationOnce(() =>
- Promise.resolve(createMockResponse(500, { message: '服务器错误' }))
- );
- renderComponent();
- // 等待错误处理 - 检查表格是否为空
- await waitFor(() => {
- // 表格应该显示空状态
- const tableBody = screen.getByRole('table').querySelector('tbody');
- expect(tableBody).toBeInTheDocument();
- // 检查是否有"暂无数据"或空状态
- const emptyCells = tableBody!.querySelectorAll('td');
- if (emptyCells.length > 0) {
- // 如果有单元格,检查是否包含空状态文本
- const hasEmptyState = Array.from(emptyCells).some(cell =>
- cell.textContent?.includes('暂无数据') ||
- cell.textContent?.includes('No data') ||
- cell.textContent?.includes('Empty')
- );
- expect(hasEmptyState).toBe(true);
- }
- });
- });
- it('应该仅公司名称为必填字段', async () => {
- renderComponent();
- // 打开创建模态框
- fireEvent.click(screen.getByTestId('create-company-button'));
- await waitFor(() => {
- expect(screen.getByTestId('company-modal-title')).toHaveTextContent('创建公司');
- });
- // 检查FormLabel标记 - 使用更精确的选择器
- expect(screen.getByText('平台(可选)')).toBeInTheDocument();
- // 查找模态框内的公司名称标签 - 使用更可靠的方法
- const modal = screen.getByRole('dialog');
- // 查找包含"公司名称"文本的label元素
- const companyNameLabel = Array.from(modal.querySelectorAll('label')).find(
- label => label.textContent === '公司名称'
- );
- expect(companyNameLabel).toBeInTheDocument();
- expect(companyNameLabel?.textContent).toBe('公司名称'); // 必填字段没有"(可选)"
- expect(screen.getByText('联系人(可选)')).toBeInTheDocument();
- expect(screen.getByText('联系电话(可选)')).toBeInTheDocument();
- expect(screen.getByText('联系邮箱(可选)')).toBeInTheDocument();
- expect(screen.getByText('地址(可选)')).toBeInTheDocument();
- });
- it('应该允许可选字段留空创建公司', async () => {
- renderComponent();
- // 打开创建模态框
- fireEvent.click(screen.getByTestId('create-company-button'));
- await waitFor(() => {
- expect(screen.getByTestId('company-modal-title')).toHaveTextContent('创建公司');
- });
- // 只填写公司名称,其他字段留空
- fireEvent.change(screen.getByTestId('create-company-name-input'), { target: { value: '仅名称公司' } });
- // 提交表单
- fireEvent.click(screen.getByTestId('submit-create-company-button'));
- // 验证API调用 - 只有公司名称被传递,其他字段为undefined
- await waitFor(() => {
- expect(companyClientManager.get().createCompany.$post).toHaveBeenCalledWith({
- json: expect.objectContaining({
- companyName: '仅名称公司'
- })
- });
- });
- });
- it('应该处理空字符串转换为undefined', async () => {
- renderComponent();
- // 打开创建模态框
- fireEvent.click(screen.getByTestId('create-company-button'));
- await waitFor(() => {
- expect(screen.getByTestId('company-modal-title')).toHaveTextContent('创建公司');
- });
- // 填写公司名称,其他字段输入空字符串
- fireEvent.change(screen.getByTestId('create-company-name-input'), { target: { value: '测试公司' } });
- fireEvent.change(screen.getByTestId('create-company-contact-person-input'), { target: { value: '' } });
- fireEvent.change(screen.getByTestId('create-company-contact-phone-input'), { target: { value: '' } });
- fireEvent.change(screen.getByTestId('create-company-contact-email-input'), { target: { value: '' } });
- fireEvent.change(screen.getByTestId('create-company-address-input'), { target: { value: '' } });
- // 提交表单
- fireEvent.click(screen.getByTestId('submit-create-company-button'));
- // 验证API调用 - 空字符串应该被转换为undefined
- await waitFor(() => {
- expect(companyClientManager.get().createCompany.$post).toHaveBeenCalledWith({
- json: expect.objectContaining({
- companyName: '测试公司'
- // 其他字段应该为undefined,不会被包含在请求中
- })
- });
- });
- });
- });
|