import React from 'react' import { render, fireEvent } from '@testing-library/react-native' import { AnnouncementBanner, type Announcement } from './AnnouncementBanner' // Mock expo-linear-gradient jest.mock('expo-linear-gradient', () => ({ LinearGradient: ({ children, ...props }: any) => { const { View } = require('react-native') return {children} }, })) describe('AnnouncementBanner', () => { const mockAnnouncements: Announcement[] = [ { id: 'ann-1', title: '系统维护通知', content: '系统将于今晚进行维护', link: 'https://example.com/maintenance', createdAt: new Date('2026-01-29T10:00:00Z'), }, { id: 'ann-2', title: '新功能上线', content: '我们推出了全新的AI生成功能', createdAt: new Date('2026-01-28T10:00:00Z'), }, { id: 'ann-3', title: '活动公告', content: '春节活动即将开始', link: 'https://example.com/event', createdAt: new Date('2026-01-27T10:00:00Z'), }, ] const mockOnPress = jest.fn() beforeEach(() => { jest.clearAllMocks() }) describe('Empty State', () => { it('should not render anything when announcements array is empty', () => { const { toJSON } = render( ) expect(toJSON()).toBeNull() }) it('should not render anything when announcements is undefined', () => { const { toJSON } = render( ) expect(toJSON()).toBeNull() }) }) describe('Single Announcement', () => { it('should render single announcement title', () => { const singleAnnouncement = [mockAnnouncements[0]] const { getByText } = render( ) expect(getByText('系统维护通知')).toBeTruthy() }) it('should render announcement banner container', () => { const singleAnnouncement = [mockAnnouncements[0]] const { getByTestId } = render( ) expect(getByTestId('announcement-banner')).toBeTruthy() }) }) describe('Multiple Announcements', () => { it('should render multiple announcements', () => { const { getByText } = render( ) expect(getByText('系统维护通知')).toBeTruthy() }) it('should render horizontal scroll view for multiple announcements', () => { const { getByTestId } = render( ) expect(getByTestId('announcement-scroll-view')).toBeTruthy() }) it('should render all announcement items', () => { const { getAllByTestId } = render( ) const items = getAllByTestId(/^announcement-item-/) expect(items.length).toBe(3) }) }) describe('Press Interaction', () => { it('should call onPress with correct announcement when pressed', () => { const singleAnnouncement = [mockAnnouncements[0]] const { getByTestId } = render( ) fireEvent.press(getByTestId('announcement-item-ann-1')) expect(mockOnPress).toHaveBeenCalledTimes(1) expect(mockOnPress).toHaveBeenCalledWith(mockAnnouncements[0]) }) it('should call onPress with correct announcement for each item', () => { const { getByTestId } = render( ) fireEvent.press(getByTestId('announcement-item-ann-2')) expect(mockOnPress).toHaveBeenCalledWith(mockAnnouncements[1]) }) it('should not crash when onPress is not provided', () => { const singleAnnouncement = [mockAnnouncements[0]] const { getByTestId } = render( ) expect(() => { fireEvent.press(getByTestId('announcement-item-ann-1')) }).not.toThrow() }) }) describe('Gradient Background Style', () => { it('should render with gradient background', () => { const singleAnnouncement = [mockAnnouncements[0]] const { getByTestId } = render( ) const banner = getByTestId('announcement-banner') expect(banner).toBeTruthy() }) it('should apply gradient colors', () => { const singleAnnouncement = [mockAnnouncements[0]] const { getByTestId } = render( ) const gradientContainer = getByTestId('gradient-container') expect(gradientContainer.props.colors).toEqual(['#FF9966', '#FF6699', '#9966FF']) }) }) describe('Announcement Icon', () => { it('should render announcement icon', () => { const singleAnnouncement = [mockAnnouncements[0]] const { getByTestId } = render( ) expect(getByTestId('announcement-icon')).toBeTruthy() }) }) }) describe('Announcement Type', () => { it('should have required id field', () => { const announcement: Announcement = { id: 'test-id', title: 'Test Title', createdAt: new Date(), } expect(announcement.id).toBeDefined() }) it('should have required title field', () => { const announcement: Announcement = { id: 'test-id', title: 'Test Title', createdAt: new Date(), } expect(announcement.title).toBeDefined() }) it('should have optional content field', () => { const announcement: Announcement = { id: 'test-id', title: 'Test Title', content: 'Test Content', createdAt: new Date(), } expect(announcement.content).toBe('Test Content') }) it('should have optional link field', () => { const announcement: Announcement = { id: 'test-id', title: 'Test Title', link: 'https://example.com', createdAt: new Date(), } expect(announcement.link).toBe('https://example.com') }) })