import React from 'react' import { render, screen, fireEvent, waitFor } from '@testing-library/react' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import VideoManagement from '../src/pages/VideoManagement/VideoManagement' // Mock Taro jest.mock('@tarojs/taro', () => ({ showToast: jest.fn(), showLoading: jest.fn(), hideLoading: jest.fn(), showShareMenu: jest.fn(), showModal: jest.fn(({ success }) => success?.({ confirm: true })), openDocument: jest.fn() })) // Mock API client jest.mock('../src/api/enterpriseOrderClient', () => ({ enterpriseOrderClient: { 'video-statistics': { $get: jest.fn() }, 'company-videos': { $get: jest.fn() }, 'batch-download': { $post: jest.fn() } } })) // Mock layouts jest.mock('@d8d/yongren-shared-ui/components/YongrenTabBarLayout', () => ({ YongrenTabBarLayout: ({ children, activeKey }: any) => (
{children}
) })) jest.mock('@d8d/mini-shared-ui-components/components/navbar', () => ({ Navbar: ({ title }: any) =>
{title}
})) const { enterpriseOrderClient } = require('../../api/enterpriseOrderClient') const Taro = require('@tarojs/taro') const createTestQueryClient = () => new QueryClient({ defaultOptions: { queries: { retry: false }, mutations: { retry: false } } }) const renderWithQueryClient = (component: React.ReactElement) => { const queryClient = createTestQueryClient() return render( {component} ) } describe('VideoManagement', () => { beforeEach(() => { jest.clearAllMocks() }) describe('视频列表加载', () => { it('应该显示加载状态', async () => { enterpriseOrderClient['video-statistics'].$get.mockResolvedValue({ ok: true, json: async () => ({ total: 10, stats: [] }) }) enterpriseOrderClient['company-videos'].$get.mockImplementation( () => new Promise(() => {}) // 永不resolve,测试加载状态 ) renderWithQueryClient() expect(screen.getByText('加载中...')).toBeInTheDocument() }) it('应该成功加载并显示视频列表', async () => { const mockStatistics = { total: 12, stats: [ { assetType: 'salary_video', count: 4, percentage: 33 }, { assetType: 'tax_video', count: 3, percentage: 25 }, { assetType: 'checkin_video', count: 5, percentage: 42 } ] } const mockVideos = { data: [ { id: '1', talentName: '张明', assetType: 'salary_video', status: 'verified', fileSize: 12345678, duration: 45, description: '工资发放确认视频', createdAt: '2023-11-25T10:00:00Z', fileUrl: 'https://example.com/video1.mp4' }, { id: '2', talentName: '李小红', assetType: 'tax_video', status: 'pending', fileSize: 10800000, duration: 38, description: '个税申报确认视频', createdAt: '2023-11-24T10:00:00Z', fileUrl: 'https://example.com/video2.mp4' } ] } enterpriseOrderClient['video-statistics'].$get.mockResolvedValue({ ok: true, json: async () => mockStatistics }) enterpriseOrderClient['company-videos'].$get.mockResolvedValue({ ok: true, json: async () => mockVideos }) renderWithQueryClient() await waitFor(() => { expect(screen.getByText('视频列表 (2)')).toBeInTheDocument() expect(screen.getByText('张明 - 工资视频')).toBeInTheDocument() expect(screen.getByText('李小红 - 个税视频')).toBeInTheDocument() expect(screen.getByText('已验证')).toBeInTheDocument() expect(screen.getByText('待审核')).toBeInTheDocument() }) }) it('应该显示空状态', async () => { enterpriseOrderClient['video-statistics'].$get.mockResolvedValue({ ok: true, json: async () => ({ total: 0, stats: [] }) }) enterpriseOrderClient['company-videos'].$get.mockResolvedValue({ ok: true, json: async () => ({ data: [] }) }) renderWithQueryClient() await waitFor(() => { expect(screen.getByText('暂无视频数据')).toBeInTheDocument() }) }) }) describe('视频分类筛选', () => { it('应该显示所有分类标签及计数', async () => { const mockStatistics = { total: 12, stats: [ { assetType: 'salary_video', count: 4 }, { assetType: 'tax_video', count: 3 }, { assetType: 'checkin_video', count: 5 } ] } enterpriseOrderClient['video-statistics'].$get.mockResolvedValue({ ok: true, json: async () => mockStatistics }) enterpriseOrderClient['company-videos'].$get.mockResolvedValue({ ok: true, json: async () => ({ data: [] }) }) renderWithQueryClient() await waitFor(() => { expect(screen.getByText('全部视频 (12)')).toBeInTheDocument() expect(screen.getByText('工资视频 (4)')).toBeInTheDocument() expect(screen.getByText('个税视频 (3)')).toBeInTheDocument() expect(screen.getByText('打卡视频 (5)')).toBeInTheDocument() }) }) it('应该能够切换视频分类', async () => { enterpriseOrderClient['video-statistics'].$get.mockResolvedValue({ ok: true, json: async () => ({ total: 10, stats: [] }) }) enterpriseOrderClient['company-videos'].$get.mockResolvedValue({ ok: true, json: async () => ({ data: [] }) }) renderWithQueryClient() await waitFor(() => { expect(screen.getByText('工资视频')).toBeInTheDocument() }) fireEvent.click(screen.getByText('工资视频')) await waitFor(() => { expect(enterpriseOrderClient['company-videos'].$get).toHaveBeenCalledWith( expect.objectContaining({ query: { assetType: 'salary_video' } }) ) }) }) }) describe('视频操作', () => { beforeEach(async () => { const mockVideos = { data: [ { id: '1', talentName: '张明', assetType: 'salary_video', status: 'verified', fileSize: 12345678, duration: 45, description: '工资发放确认视频', createdAt: '2023-11-25T10:00:00Z', fileUrl: 'https://example.com/video1.mp4' } ] } enterpriseOrderClient['video-statistics'].$get.mockResolvedValue({ ok: true, json: async () => ({ total: 1, stats: [] }) }) enterpriseOrderClient['company-videos'].$get.mockResolvedValue({ ok: true, json: async () => mockVideos }) }) it('应该能够选择视频进行批量下载', async () => { renderWithQueryClient() await waitFor(() => { expect(screen.getByText('张明 - 工资视频')).toBeInTheDocument() }) // 点击选择按钮 const selectButtons = screen.getAllByText('选择') fireEvent.click(selectButtons[0]) await waitFor(() => { expect(screen.getByText('已选择')).toBeInTheDocument() expect(screen.getByText('批量下载 (1)')).toBeInTheDocument() }) }) it('应该能够执行批量下载', async () => { enterpriseOrderClient['batch-download'].$post.mockResolvedValue({ ok: true, json: async () => ({ success: true }) }) renderWithQueryClient() await waitFor(() => { expect(screen.getByText('张明 - 工资视频')).toBeInTheDocument() }) // 先选择视频 const selectButtons = screen.getAllByText('选择') fireEvent.click(selectButtons[0]) // 再点击批量下载 fireEvent.click(screen.getByText(/批量下载/)) await waitFor(() => { expect(enterpriseOrderClient['batch-download'].$post).toHaveBeenCalled() expect(Taro.showToast).toHaveBeenCalledWith( expect.objectContaining({ title: '下载任务已创建' }) ) }) }) it('应该在批量下载前提示选择视频', async () => { renderWithQueryClient() await waitFor(() => { expect(screen.getByText('张明 - 工资视频')).toBeInTheDocument() }) // 直接点击批量下载,不选择视频 fireEvent.click(screen.getByText(/批量下载/)) expect(Taro.showToast).toHaveBeenCalledWith( expect.objectContaining({ title: '请先选择要下载的视频' }) ) }) it('应该能够播放视频', async () => { renderWithQueryClient() await waitFor(() => { expect(screen.getByText('张明 - 工资视频')).toBeInTheDocument() }) const playButton = screen.getByText('播放') fireEvent.click(playButton) expect(Taro.showModal).toHaveBeenCalledWith( expect.objectContaining({ title: '播放视频', content: '即将播放:张明 - 工资视频' }) ) }) it('应该能够下载单个视频', async () => { enterpriseOrderClient['batch-download'].$post.mockResolvedValue({ ok: true, json: async () => ({ success: true }) }) renderWithQueryClient() await waitFor(() => { expect(screen.getByText('张明 - 工资视频')).toBeInTheDocument() }) const downloadButton = screen.getByText('下载') fireEvent.click(downloadButton) await waitFor(() => { expect(enterpriseOrderClient['batch-download'].$post).toHaveBeenCalled() expect(Taro.showToast).toHaveBeenCalledWith( expect.objectContaining({ title: '下载成功' }) ) }) }) it('应该能够分享视频', async () => { renderWithQueryClient() await waitFor(() => { expect(screen.getByText('张明 - 工资视频')).toBeInTheDocument() }) const shareButton = screen.getByText('分享') fireEvent.click(shareButton) expect(Taro.showShareMenu).toHaveBeenCalledWith( expect.objectContaining({ withShareTicket: true }) ) }) }) describe('组件集成', () => { it('应该正确集成Navbar组件', async () => { enterpriseOrderClient['video-statistics'].$get.mockResolvedValue({ ok: true, json: async () => ({ total: 0, stats: [] }) }) enterpriseOrderClient['company-videos'].$get.mockResolvedValue({ ok: true, json: async () => ({ data: [] }) }) renderWithQueryClient() await waitFor(() => { const navbar = screen.getByTestId('navbar') expect(navbar).toBeInTheDocument() expect(navbar).toHaveTextContent('视频管理') }) }) it('应该正确集成TabBarLayout并激活settings标签', async () => { enterpriseOrderClient['video-statistics'].$get.mockResolvedValue({ ok: true, json: async () => ({ total: 0, stats: [] }) }) enterpriseOrderClient['company-videos'].$get.mockResolvedValue({ ok: true, json: async () => ({ data: [] }) }) renderWithQueryClient() await waitFor(() => { const layout = screen.getByTestId('tab-bar-layout') expect(layout).toHaveAttribute('data-active-key', 'settings') }) }) }) })