expo-popcore-app/components/message/MessageTabBar.test.tsx

284 lines
9.2 KiB
TypeScript

import React from 'react'
import { render, fireEvent } from '@testing-library/react-native'
import { MessageTabBar, TAB_ITEMS } from './MessageTabBar'
import type { MessageType } from './MessageTabBar'
describe('MessageTabBar Constants', () => {
describe('TAB_ITEMS', () => {
it('should have 4 tabs', () => {
expect(TAB_ITEMS).toHaveLength(4)
})
it('should have correct tab keys', () => {
const keys = TAB_ITEMS.map((tab) => tab.key)
expect(keys).toEqual(['all', 'activity', 'system', 'billing'])
})
it('should have correct tab labels', () => {
const labels = TAB_ITEMS.map((tab) => tab.label)
expect(labels).toEqual(['全部', '互动', '系统', '账单'])
})
it('should have correct tab types', () => {
const types = TAB_ITEMS.map((tab) => tab.type)
expect(types).toEqual([undefined, 'ACTIVITY', 'SYSTEM', 'BILLING'])
})
})
})
describe('MessageTabBar Component', () => {
const mockOnTabChange = jest.fn()
beforeEach(() => {
jest.clearAllMocks()
})
describe('Rendering', () => {
it('should render all 4 tabs', () => {
const { getByText } = render(
<MessageTabBar activeTab={undefined} onTabChange={mockOnTabChange} />
)
expect(getByText('全部')).toBeTruthy()
expect(getByText('互动')).toBeTruthy()
expect(getByText('系统')).toBeTruthy()
expect(getByText('账单')).toBeTruthy()
})
it('should render with testID for each tab', () => {
const { getByTestId } = render(
<MessageTabBar activeTab={undefined} onTabChange={mockOnTabChange} />
)
expect(getByTestId('tab-all')).toBeTruthy()
expect(getByTestId('tab-activity')).toBeTruthy()
expect(getByTestId('tab-system')).toBeTruthy()
expect(getByTestId('tab-billing')).toBeTruthy()
})
})
describe('Active Tab Highlighting', () => {
it('should highlight "全部" tab when activeTab is undefined', () => {
const { getByTestId } = render(
<MessageTabBar activeTab={undefined} onTabChange={mockOnTabChange} />
)
const allTab = getByTestId('tab-all')
const activityTab = getByTestId('tab-activity')
// Check that all tab has active indicator
expect(getByTestId('tab-all-active-indicator')).toBeTruthy()
// Check that activity tab does not have active indicator
expect(() => getByTestId('tab-activity-active-indicator')).toThrow()
})
it('should highlight "互动" tab when activeTab is ACTIVITY', () => {
const { getByTestId } = render(
<MessageTabBar activeTab="ACTIVITY" onTabChange={mockOnTabChange} />
)
expect(getByTestId('tab-activity-active-indicator')).toBeTruthy()
expect(() => getByTestId('tab-all-active-indicator')).toThrow()
})
it('should highlight "系统" tab when activeTab is SYSTEM', () => {
const { getByTestId } = render(
<MessageTabBar activeTab="SYSTEM" onTabChange={mockOnTabChange} />
)
expect(getByTestId('tab-system-active-indicator')).toBeTruthy()
expect(() => getByTestId('tab-all-active-indicator')).toThrow()
})
it('should highlight "账单" tab when activeTab is BILLING', () => {
const { getByTestId } = render(
<MessageTabBar activeTab="BILLING" onTabChange={mockOnTabChange} />
)
expect(getByTestId('tab-billing-active-indicator')).toBeTruthy()
expect(() => getByTestId('tab-all-active-indicator')).toThrow()
})
})
describe('Tab Press Interaction', () => {
it('should call onTabChange with undefined when "全部" tab is pressed', () => {
const { getByTestId } = render(
<MessageTabBar activeTab="ACTIVITY" onTabChange={mockOnTabChange} />
)
fireEvent.press(getByTestId('tab-all'))
expect(mockOnTabChange).toHaveBeenCalledWith(undefined)
})
it('should call onTabChange with ACTIVITY when "互动" tab is pressed', () => {
const { getByTestId } = render(
<MessageTabBar activeTab={undefined} onTabChange={mockOnTabChange} />
)
fireEvent.press(getByTestId('tab-activity'))
expect(mockOnTabChange).toHaveBeenCalledWith('ACTIVITY')
})
it('should call onTabChange with SYSTEM when "系统" tab is pressed', () => {
const { getByTestId } = render(
<MessageTabBar activeTab={undefined} onTabChange={mockOnTabChange} />
)
fireEvent.press(getByTestId('tab-system'))
expect(mockOnTabChange).toHaveBeenCalledWith('SYSTEM')
})
it('should call onTabChange with BILLING when "账单" tab is pressed', () => {
const { getByTestId } = render(
<MessageTabBar activeTab={undefined} onTabChange={mockOnTabChange} />
)
fireEvent.press(getByTestId('tab-billing'))
expect(mockOnTabChange).toHaveBeenCalledWith('BILLING')
})
it('should call onTabChange even when pressing the already active tab', () => {
const { getByTestId } = render(
<MessageTabBar activeTab={undefined} onTabChange={mockOnTabChange} />
)
fireEvent.press(getByTestId('tab-all'))
expect(mockOnTabChange).toHaveBeenCalledWith(undefined)
})
})
describe('Unread Badge Display', () => {
it('should show unread badge on "全部" tab when all count > 0', () => {
const { getByTestId, getByText } = render(
<MessageTabBar
activeTab={undefined}
onTabChange={mockOnTabChange}
unreadCounts={{ all: 5 }}
/>
)
expect(getByTestId('tab-all-badge')).toBeTruthy()
expect(getByText('5')).toBeTruthy()
})
it('should show unread badge on "互动" tab when activity count > 0', () => {
const { getByTestId, getByText } = render(
<MessageTabBar
activeTab={undefined}
onTabChange={mockOnTabChange}
unreadCounts={{ activity: 3 }}
/>
)
expect(getByTestId('tab-activity-badge')).toBeTruthy()
expect(getByText('3')).toBeTruthy()
})
it('should show unread badge on "系统" tab when system count > 0', () => {
const { getByTestId, getByText } = render(
<MessageTabBar
activeTab={undefined}
onTabChange={mockOnTabChange}
unreadCounts={{ system: 10 }}
/>
)
expect(getByTestId('tab-system-badge')).toBeTruthy()
expect(getByText('10')).toBeTruthy()
})
it('should show unread badge on "账单" tab when billing count > 0', () => {
const { getByTestId, getByText } = render(
<MessageTabBar
activeTab={undefined}
onTabChange={mockOnTabChange}
unreadCounts={{ billing: 2 }}
/>
)
expect(getByTestId('tab-billing-badge')).toBeTruthy()
expect(getByText('2')).toBeTruthy()
})
it('should show multiple badges when multiple counts > 0', () => {
const { getByTestId } = render(
<MessageTabBar
activeTab={undefined}
onTabChange={mockOnTabChange}
unreadCounts={{ all: 15, activity: 5, system: 8, billing: 2 }}
/>
)
expect(getByTestId('tab-all-badge')).toBeTruthy()
expect(getByTestId('tab-activity-badge')).toBeTruthy()
expect(getByTestId('tab-system-badge')).toBeTruthy()
expect(getByTestId('tab-billing-badge')).toBeTruthy()
})
it('should show "99+" when count exceeds 99', () => {
const { getByText } = render(
<MessageTabBar
activeTab={undefined}
onTabChange={mockOnTabChange}
unreadCounts={{ all: 150 }}
/>
)
expect(getByText('99+')).toBeTruthy()
})
})
describe('No Badge Display', () => {
it('should not show badge when unreadCounts is not provided', () => {
const { queryByTestId } = render(
<MessageTabBar activeTab={undefined} onTabChange={mockOnTabChange} />
)
expect(queryByTestId('tab-all-badge')).toBeNull()
expect(queryByTestId('tab-activity-badge')).toBeNull()
expect(queryByTestId('tab-system-badge')).toBeNull()
expect(queryByTestId('tab-billing-badge')).toBeNull()
})
it('should not show badge when count is 0', () => {
const { queryByTestId } = render(
<MessageTabBar
activeTab={undefined}
onTabChange={mockOnTabChange}
unreadCounts={{ all: 0, activity: 0, system: 0, billing: 0 }}
/>
)
expect(queryByTestId('tab-all-badge')).toBeNull()
expect(queryByTestId('tab-activity-badge')).toBeNull()
expect(queryByTestId('tab-system-badge')).toBeNull()
expect(queryByTestId('tab-billing-badge')).toBeNull()
})
it('should not show badge when count is undefined', () => {
const { queryByTestId } = render(
<MessageTabBar
activeTab={undefined}
onTabChange={mockOnTabChange}
unreadCounts={{}}
/>
)
expect(queryByTestId('tab-all-badge')).toBeNull()
expect(queryByTestId('tab-activity-badge')).toBeNull()
expect(queryByTestId('tab-system-badge')).toBeNull()
expect(queryByTestId('tab-billing-badge')).toBeNull()
})
})
})
describe('MessageTabBar Types', () => {
it('should accept valid MessageType values', () => {
const types: MessageType[] = [undefined, 'ACTIVITY', 'SYSTEM', 'BILLING']
types.forEach((type) => {
expect([undefined, 'ACTIVITY', 'SYSTEM', 'BILLING']).toContain(type)
})
})
})