298 lines
10 KiB
TypeScript
298 lines
10 KiB
TypeScript
import React from 'react'
|
|
import { render, fireEvent } from '@testing-library/react-native'
|
|
import { View } from 'react-native'
|
|
import { SocialActionBar } from './SocialActionBar'
|
|
|
|
// Mock LinearGradient to return a simple View
|
|
jest.mock('expo-linear-gradient', () => ({
|
|
LinearGradient: ({ children, testID }) => <View testID={testID}>{children}</View>,
|
|
}))
|
|
|
|
describe('SocialActionBar Component', () => {
|
|
describe('Component Export', () => {
|
|
it('should be defined', () => {
|
|
expect(SocialActionBar).toBeDefined()
|
|
})
|
|
|
|
it('should be wrapped with React.memo', () => {
|
|
expect(typeof SocialActionBar).toBe('object')
|
|
})
|
|
})
|
|
|
|
describe('Props Interface', () => {
|
|
it('should accept templateId prop', () => {
|
|
const props = { templateId: 'test-template-1' }
|
|
expect(props.templateId).toBe('test-template-1')
|
|
})
|
|
|
|
it('should accept liked prop', () => {
|
|
const props = { liked: true }
|
|
expect(props.liked).toBe(true)
|
|
})
|
|
|
|
it('should accept favorited prop', () => {
|
|
const props = { favorited: true }
|
|
expect(props.favorited).toBe(true)
|
|
})
|
|
|
|
it('should accept likeCount prop', () => {
|
|
const props = { likeCount: 100 }
|
|
expect(props.likeCount).toBe(100)
|
|
})
|
|
|
|
it('should accept favoriteCount prop', () => {
|
|
const props = { favoriteCount: 50 }
|
|
expect(props.favoriteCount).toBe(50)
|
|
})
|
|
|
|
it('should accept loading prop', () => {
|
|
const props = { loading: true }
|
|
expect(props.loading).toBe(true)
|
|
})
|
|
|
|
it('should accept onLike callback', () => {
|
|
const onLike = jest.fn()
|
|
expect(typeof onLike).toBe('function')
|
|
})
|
|
|
|
it('should accept onUnlike callback', () => {
|
|
const onUnlike = jest.fn()
|
|
expect(typeof onUnlike).toBe('function')
|
|
})
|
|
|
|
it('should accept onFavorite callback', () => {
|
|
const onFavorite = jest.fn()
|
|
expect(typeof onFavorite).toBe('function')
|
|
})
|
|
|
|
it('should accept onUnfavorite callback', () => {
|
|
const onUnfavorite = jest.fn()
|
|
expect(typeof onUnfavorite).toBe('function')
|
|
})
|
|
|
|
it('should accept testID prop', () => {
|
|
const props = { testID: 'social-action-bar' }
|
|
expect(props.testID).toBe('social-action-bar')
|
|
})
|
|
})
|
|
|
|
describe('Default Values', () => {
|
|
it('should have default liked value of false', () => {
|
|
const defaultLiked = false
|
|
expect(defaultLiked).toBe(false)
|
|
})
|
|
|
|
it('should have default favorited value of false', () => {
|
|
const defaultFavorited = false
|
|
expect(defaultFavorited).toBe(false)
|
|
})
|
|
|
|
it('should have default loading value of false', () => {
|
|
const defaultLoading = false
|
|
expect(defaultLoading).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('Rendering', () => {
|
|
it('should render successfully', () => {
|
|
const { getByTestId } = render(
|
|
<SocialActionBar templateId="test-1" testID="social-action-bar" />
|
|
)
|
|
expect(getByTestId('social-action-bar')).toBeTruthy()
|
|
})
|
|
|
|
it('should render with default props', () => {
|
|
const { getByTestId } = render(
|
|
<SocialActionBar templateId="test-1" testID="social-action-bar-default" />
|
|
)
|
|
expect(getByTestId('social-action-bar-default')).toBeTruthy()
|
|
})
|
|
|
|
it('should render LikeButton and FavoriteButton', () => {
|
|
const { getByTestId } = render(
|
|
<SocialActionBar templateId="test-1" testID="social-action-bar-buttons" />
|
|
)
|
|
const container = getByTestId('social-action-bar-buttons')
|
|
expect(container).toBeTruthy()
|
|
})
|
|
})
|
|
|
|
describe('Gradient Background', () => {
|
|
it('should render with gradient background', () => {
|
|
const { getByTestId } = render(
|
|
<SocialActionBar templateId="test-1" testID="social-action-bar-gradient" />
|
|
)
|
|
const container = getByTestId('social-action-bar-gradient')
|
|
expect(container).toBeTruthy()
|
|
})
|
|
})
|
|
|
|
describe('Like Button Integration', () => {
|
|
it('should pass liked state to LikeButton', () => {
|
|
const { getByTestId } = render(
|
|
<SocialActionBar templateId="test-1" liked={true} testID="social-action-bar-liked" />
|
|
)
|
|
const container = getByTestId('social-action-bar-liked')
|
|
expect(container).toBeTruthy()
|
|
})
|
|
|
|
it('should pass likeCount to LikeButton', () => {
|
|
const { getByTestId, getByText } = render(
|
|
<SocialActionBar templateId="test-1" likeCount={42} testID="social-action-bar-like-count" />
|
|
)
|
|
const container = getByTestId('social-action-bar-like-count')
|
|
expect(container).toBeTruthy()
|
|
expect(getByText('42')).toBeTruthy()
|
|
})
|
|
|
|
it('should call onLike when like button is pressed and not liked', () => {
|
|
const onLike = jest.fn()
|
|
const { getByTestId } = render(
|
|
<SocialActionBar templateId="test-1" liked={false} onLike={onLike} testID="social-action-bar-on-like" />
|
|
)
|
|
const container = getByTestId('social-action-bar-on-like')
|
|
// 模拟点击 LikeButton
|
|
fireEvent.press(container)
|
|
// 由于 LikeButton 在内部,我们需要通过 testID 来找到它
|
|
const likeButton = getByTestId('social-action-bar-on-like-like-button')
|
|
fireEvent.press(likeButton)
|
|
expect(onLike).toHaveBeenCalledTimes(1)
|
|
})
|
|
|
|
it('should call onUnlike when like button is pressed and already liked', () => {
|
|
const onUnlike = jest.fn()
|
|
const { getByTestId } = render(
|
|
<SocialActionBar templateId="test-1" liked={true} onUnlike={onUnlike} testID="social-action-bar-on-unlike" />
|
|
)
|
|
const container = getByTestId('social-action-bar-on-unlike')
|
|
const likeButton = getByTestId('social-action-bar-on-unlike-like-button')
|
|
fireEvent.press(likeButton)
|
|
expect(onUnlike).toHaveBeenCalledTimes(1)
|
|
})
|
|
})
|
|
|
|
describe('Favorite Button Integration', () => {
|
|
it('should pass favorited state to FavoriteButton', () => {
|
|
const { getByTestId } = render(
|
|
<SocialActionBar templateId="test-1" favorited={true} testID="social-action-bar-favorited" />
|
|
)
|
|
const container = getByTestId('social-action-bar-favorited')
|
|
expect(container).toBeTruthy()
|
|
})
|
|
|
|
it('should pass favoriteCount to FavoriteButton', () => {
|
|
const { getByTestId, getByText } = render(
|
|
<SocialActionBar templateId="test-1" favoriteCount={88} testID="social-action-bar-favorite-count" />
|
|
)
|
|
const container = getByTestId('social-action-bar-favorite-count')
|
|
expect(container).toBeTruthy()
|
|
expect(getByText('88')).toBeTruthy()
|
|
})
|
|
|
|
it('should call onFavorite when favorite button is pressed and not favorited', () => {
|
|
const onFavorite = jest.fn()
|
|
const { getByTestId } = render(
|
|
<SocialActionBar templateId="test-1" favorited={false} onFavorite={onFavorite} testID="social-action-bar-on-favorite" />
|
|
)
|
|
const container = getByTestId('social-action-bar-on-favorite')
|
|
const favoriteButton = getByTestId('social-action-bar-on-favorite-favorite-button')
|
|
fireEvent.press(favoriteButton)
|
|
expect(onFavorite).toHaveBeenCalledTimes(1)
|
|
})
|
|
|
|
it('should call onUnfavorite when favorite button is pressed and already favorited', () => {
|
|
const onUnfavorite = jest.fn()
|
|
const { getByTestId } = render(
|
|
<SocialActionBar templateId="test-1" favorited={true} onUnfavorite={onUnfavorite} testID="social-action-bar-on-unfavorite" />
|
|
)
|
|
const container = getByTestId('social-action-bar-on-unfavorite')
|
|
const favoriteButton = getByTestId('social-action-bar-on-unfavorite-favorite-button')
|
|
fireEvent.press(favoriteButton)
|
|
expect(onUnfavorite).toHaveBeenCalledTimes(1)
|
|
})
|
|
})
|
|
|
|
describe('Loading State', () => {
|
|
it('should pass loading state to both buttons', () => {
|
|
const { getByTestId } = render(
|
|
<SocialActionBar templateId="test-1" loading={true} testID="social-action-bar-loading" />
|
|
)
|
|
const container = getByTestId('social-action-bar-loading')
|
|
expect(container).toBeTruthy()
|
|
})
|
|
|
|
it('should disable buttons when loading', () => {
|
|
const onLike = jest.fn()
|
|
const onFavorite = jest.fn()
|
|
const { getByTestId } = render(
|
|
<SocialActionBar
|
|
templateId="test-1"
|
|
loading={true}
|
|
onLike={onLike}
|
|
onFavorite={onFavorite}
|
|
testID="social-action-bar-loading-disabled"
|
|
/>
|
|
)
|
|
const container = getByTestId('social-action-bar-loading-disabled')
|
|
const likeButton = getByTestId('social-action-bar-loading-disabled-like-button')
|
|
const favoriteButton = getByTestId('social-action-bar-loading-disabled-favorite-button')
|
|
|
|
fireEvent.press(likeButton)
|
|
fireEvent.press(favoriteButton)
|
|
|
|
// 当 loading 时,不应该调用回调
|
|
expect(onLike).not.toHaveBeenCalled()
|
|
expect(onFavorite).not.toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
describe('Layout', () => {
|
|
it('should render buttons in horizontal layout', () => {
|
|
const { getByTestId } = render(
|
|
<SocialActionBar templateId="test-1" testID="social-action-bar-horizontal" />
|
|
)
|
|
const container = getByTestId('social-action-bar-horizontal')
|
|
expect(container).toBeTruthy()
|
|
})
|
|
})
|
|
|
|
describe('Edge Cases', () => {
|
|
it('should handle zero counts', () => {
|
|
const { getByText } = render(
|
|
<SocialActionBar templateId="test-1" likeCount={0} favoriteCount={0} testID="social-action-bar-zero" />
|
|
)
|
|
expect(getByText('0')).toBeTruthy()
|
|
})
|
|
|
|
it('should handle large counts', () => {
|
|
const { getByText } = render(
|
|
<SocialActionBar templateId="test-1" likeCount={9999} favoriteCount={8888} testID="social-action-bar-large" />
|
|
)
|
|
expect(getByText('9999')).toBeTruthy()
|
|
expect(getByText('8888')).toBeTruthy()
|
|
})
|
|
|
|
it('should handle missing callback functions', () => {
|
|
const { getByTestId } = render(
|
|
<SocialActionBar templateId="test-1" testID="social-action-bar-no-callback" />
|
|
)
|
|
const container = getByTestId('social-action-bar-no-callback')
|
|
const likeButton = getByTestId('social-action-bar-no-callback-like-button')
|
|
const favoriteButton = getByTestId('social-action-bar-no-callback-favorite-button')
|
|
|
|
expect(() => {
|
|
fireEvent.press(likeButton)
|
|
fireEvent.press(favoriteButton)
|
|
}).not.toThrow()
|
|
})
|
|
|
|
it('should handle both liked and favorited states', () => {
|
|
const { getByTestId } = render(
|
|
<SocialActionBar templateId="test-1" liked={true} favorited={true} testID="social-action-bar-both" />
|
|
)
|
|
const container = getByTestId('social-action-bar-both')
|
|
expect(container).toBeTruthy()
|
|
})
|
|
})
|
|
})
|