fix: bug
This commit is contained in:
@@ -23,6 +23,10 @@ jest.mock('react-i18next', () => ({
|
||||
|
||||
// Mock expo-router
|
||||
const mockPush = jest.fn()
|
||||
const mockUseFocusEffect = jest.fn((callback: () => void) => {
|
||||
// 立即执行 callback 来模拟页面获得焦点
|
||||
callback()
|
||||
})
|
||||
jest.mock('expo-router', () => ({
|
||||
useRouter: () => ({
|
||||
push: mockPush,
|
||||
@@ -30,6 +34,7 @@ jest.mock('expo-router', () => ({
|
||||
back: jest.fn(),
|
||||
}),
|
||||
useLocalSearchParams: () => ({}),
|
||||
useFocusEffect: (callback: () => void) => mockUseFocusEffect(callback),
|
||||
}))
|
||||
|
||||
// Mock hooks
|
||||
@@ -87,6 +92,7 @@ jest.mock('@/hooks/use-messages', () => ({
|
||||
messages: mockMessages,
|
||||
loading: false,
|
||||
loadingMore: false,
|
||||
refreshing: false,
|
||||
error: null,
|
||||
execute: mockExecute,
|
||||
refetch: mockRefetch,
|
||||
@@ -524,9 +530,10 @@ describe('MessageScreen', () => {
|
||||
})
|
||||
|
||||
describe('Initial Data Fetch', () => {
|
||||
it('should call execute on mount', () => {
|
||||
it('should call refetch on mount via useFocusEffect', () => {
|
||||
render(<MessageScreen />)
|
||||
expect(mockExecute).toHaveBeenCalled()
|
||||
// 现在使用 useFocusEffect + refetch 替代 useEffect + execute
|
||||
expect(mockRefetch).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should call announcement execute on mount', () => {
|
||||
@@ -534,4 +541,144 @@ describe('MessageScreen', () => {
|
||||
expect(mockAnnouncementExecute).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
describe('Pull-to-Refresh', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
const { useMessages } = require('@/hooks/use-messages')
|
||||
useMessages.mockReturnValue({
|
||||
messages: mockMessages,
|
||||
loading: false,
|
||||
loadingMore: false,
|
||||
refreshing: false,
|
||||
error: null,
|
||||
execute: mockExecute,
|
||||
refetch: mockRefetch,
|
||||
loadMore: mockLoadMore,
|
||||
hasMore: true,
|
||||
})
|
||||
|
||||
const { useAnnouncements } = require('@/hooks/use-announcements')
|
||||
useAnnouncements.mockReturnValue({
|
||||
announcements: mockAnnouncements,
|
||||
loading: false,
|
||||
error: null,
|
||||
execute: mockAnnouncementExecute,
|
||||
refetch: jest.fn(),
|
||||
loadMore: jest.fn(),
|
||||
hasMore: false,
|
||||
})
|
||||
})
|
||||
|
||||
it('should render FlatList with RefreshControl', () => {
|
||||
const { getByTestId } = render(<MessageScreen />)
|
||||
const flatList = getByTestId('message-list')
|
||||
expect(flatList.props.refreshControl).toBeTruthy()
|
||||
})
|
||||
|
||||
it('should call refetch when pull-to-refresh is triggered', async () => {
|
||||
const { getByTestId } = render(<MessageScreen />)
|
||||
const flatList = getByTestId('message-list')
|
||||
|
||||
// 触发 onRefresh
|
||||
const refreshControl = flatList.props.refreshControl
|
||||
refreshControl.props.onRefresh()
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockRefetch).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
it('should call executeAnnouncements when pull-to-refresh is triggered', async () => {
|
||||
const { getByTestId } = render(<MessageScreen />)
|
||||
const flatList = getByTestId('message-list')
|
||||
|
||||
// 触发 onRefresh
|
||||
const refreshControl = flatList.props.refreshControl
|
||||
refreshControl.props.onRefresh()
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockAnnouncementExecute).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
it('should show refreshing indicator when refreshing is true', () => {
|
||||
const { useMessages } = require('@/hooks/use-messages')
|
||||
useMessages.mockReturnValue({
|
||||
messages: mockMessages,
|
||||
loading: false,
|
||||
loadingMore: false,
|
||||
refreshing: true,
|
||||
error: null,
|
||||
execute: mockExecute,
|
||||
refetch: mockRefetch,
|
||||
loadMore: mockLoadMore,
|
||||
hasMore: true,
|
||||
})
|
||||
|
||||
const { getByTestId } = render(<MessageScreen />)
|
||||
const flatList = getByTestId('message-list')
|
||||
const refreshControl = flatList.props.refreshControl
|
||||
|
||||
expect(refreshControl.props.refreshing).toBe(true)
|
||||
})
|
||||
|
||||
it('should not show refreshing indicator when refreshing is false', () => {
|
||||
const { getByTestId } = render(<MessageScreen />)
|
||||
const flatList = getByTestId('message-list')
|
||||
const refreshControl = flatList.props.refreshControl
|
||||
|
||||
expect(refreshControl.props.refreshing).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Tab Focus Reload', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
const { useMessages } = require('@/hooks/use-messages')
|
||||
useMessages.mockReturnValue({
|
||||
messages: mockMessages,
|
||||
loading: false,
|
||||
loadingMore: false,
|
||||
refreshing: false,
|
||||
error: null,
|
||||
execute: mockExecute,
|
||||
refetch: mockRefetch,
|
||||
loadMore: mockLoadMore,
|
||||
hasMore: true,
|
||||
})
|
||||
|
||||
const { useAnnouncements } = require('@/hooks/use-announcements')
|
||||
useAnnouncements.mockReturnValue({
|
||||
announcements: mockAnnouncements,
|
||||
loading: false,
|
||||
error: null,
|
||||
execute: mockAnnouncementExecute,
|
||||
refetch: jest.fn(),
|
||||
loadMore: jest.fn(),
|
||||
hasMore: false,
|
||||
})
|
||||
})
|
||||
|
||||
it('should call refetch when tab gains focus', () => {
|
||||
render(<MessageScreen />)
|
||||
|
||||
// useFocusEffect 在 mock 中会立即执行 callback
|
||||
// 所以 refetch 应该被调用
|
||||
expect(mockRefetch).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should call executeAnnouncements when tab gains focus', () => {
|
||||
render(<MessageScreen />)
|
||||
|
||||
expect(mockAnnouncementExecute).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should use useFocusEffect hook', () => {
|
||||
render(<MessageScreen />)
|
||||
|
||||
// 验证 useFocusEffect 被调用
|
||||
expect(mockUseFocusEffect).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user