/* @vitest-environment jsdom */ import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import { beforeEach, expect, test, vi } from 'vitest'; import { PlatformFeedbackView } from './PlatformFeedbackView'; class MockFileReader { result: string | ArrayBuffer | null = null; onload: null | (() => void) = null; onerror: null | (() => void) = null; readAsDataURL(file: File) { this.result = `data:${file.type};base64,ZmVlZGJhY2s=`; this.onload?.(); } } beforeEach(() => { vi.stubGlobal('FileReader', MockFileReader); }); test('PlatformFeedbackView renders reference feedback fields', () => { render(); expect(screen.getByText('帮助与反馈')).toBeTruthy(); expect(screen.getByText('反馈问题')).toBeTruthy(); expect(screen.getByLabelText('问题描述')).toBeTruthy(); expect(screen.getByText('0/200')).toBeTruthy(); expect(screen.getByText('上传凭证(提供问题截图)')).toBeTruthy(); expect(screen.getByText('上传凭证')).toBeTruthy(); expect(screen.getByLabelText('联系电话')).toBeTruthy(); expect(screen.getByRole('button', { name: '提交' })).toBeTruthy(); expect(screen.getByRole('button', { name: '查看反馈与投诉记录' })).toBeTruthy(); }); test('PlatformFeedbackView validates minimum description length before submit', () => { const onSubmit = vi.fn(); render(); fireEvent.change(screen.getByLabelText('问题描述'), { target: { value: '太短' }, }); fireEvent.click(screen.getByRole('button', { name: '提交' })); expect(screen.getByText('请填写10个字以上的问题描述')).toBeTruthy(); expect(onSubmit).not.toHaveBeenCalled(); }); test('PlatformFeedbackView submits trimmed payload', async () => { const onSubmit = vi.fn(); render(); fireEvent.change(screen.getByLabelText('问题描述'), { target: { value: ' 这个反馈页面无法正常上传图片 ' }, }); fireEvent.change(screen.getByLabelText('联系电话'), { target: { value: ' 13800000000 ' }, }); fireEvent.click(screen.getByRole('button', { name: '提交' })); await waitFor(() => expect(onSubmit).toHaveBeenCalledTimes(1)); expect(onSubmit).toHaveBeenCalledWith({ description: '这个反馈页面无法正常上传图片', contactPhone: '13800000000', evidenceItems: [], }); await waitFor(() => expect(screen.getByText('反馈已提交')).toBeTruthy()); }); test('PlatformFeedbackView previews image data urls and submits evidence items', async () => { const onSubmit = vi.fn(); render(); const file = new File(['feedback'], 'preview.png', { type: 'image/png' }); fireEvent.change(document.querySelector('input[type="file"]') as HTMLInputElement, { target: { files: [file] }, }); const preview = await screen.findByAltText('反馈凭证预览'); expect(preview.getAttribute('src')).toBe( 'data:image/png;base64,ZmVlZGJhY2s=', ); fireEvent.change(screen.getByLabelText('问题描述'), { target: { value: '图片上传后现在应该展示预览' }, }); fireEvent.click(screen.getByRole('button', { name: '提交' })); await waitFor(() => expect(onSubmit).toHaveBeenCalledTimes(1)); expect(onSubmit).toHaveBeenCalledWith({ description: '图片上传后现在应该展示预览', contactPhone: null, evidenceItems: [ { fileName: 'preview.png', contentType: 'image/png', sizeBytes: file.size, dataUrl: 'data:image/png;base64,ZmVlZGJhY2s=', }, ], }); }); test('PlatformFeedbackView calls back from header home button', () => { const onBack = vi.fn(); render(); fireEvent.click(screen.getByRole('button', { name: '返回我的页签' })); expect(onBack).toHaveBeenCalledTimes(1); });