Files
expo-popcore-app/hooks/use-announcement-actions.test.ts
imeepos 6c17d720ca feat: add announcement action hooks with TDD
Add useAnnouncementActions hook for marking announcements as read and useAnnouncementUnreadCount hook for fetching unread announcement count. Both hooks follow TDD principles with complete test coverage.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 14:53:03 +08:00

98 lines
2.9 KiB
TypeScript

import { renderHook, act } from '@testing-library/react-native'
import { useAnnouncementActions } from './use-announcement-actions'
import { root } from '@repo/core'
import { AnnouncementController } from '@repo/sdk'
jest.mock('@repo/core', () => ({
root: {
get: jest.fn(),
},
}))
describe('useAnnouncementActions', () => {
beforeEach(() => {
jest.clearAllMocks()
})
afterEach(() => {
jest.restoreAllMocks()
})
describe('initial state', () => {
it('should return initial state', () => {
const mockAnnouncementController = {
markRead: jest.fn(),
}
;(root.get as jest.Mock).mockReturnValue(mockAnnouncementController)
const { result } = renderHook(() => useAnnouncementActions())
expect(result.current.markReadLoading).toBe(false)
expect(result.current.markReadError).toBeNull()
})
})
describe('markRead', () => {
it('should mark announcement as read successfully', async () => {
const mockAnnouncementController = {
markRead: jest.fn().mockResolvedValue({ message: 'success' }),
}
;(root.get as jest.Mock).mockReturnValue(mockAnnouncementController)
const { result } = renderHook(() => useAnnouncementActions())
await act(async () => {
await result.current.markRead('announcement-1')
})
expect(mockAnnouncementController.markRead).toHaveBeenCalledWith({ id: 'announcement-1' })
expect(result.current.markReadLoading).toBe(false)
expect(result.current.markReadError).toBeNull()
})
it('should handle markRead error', async () => {
const mockError = new Error('Failed to mark as read')
const mockAnnouncementController = {
markRead: jest.fn().mockRejectedValue(mockError),
}
;(root.get as jest.Mock).mockReturnValue(mockAnnouncementController)
const { result } = renderHook(() => useAnnouncementActions())
await act(async () => {
await result.current.markRead('announcement-1')
})
expect(result.current.markReadError).toEqual(mockError)
expect(result.current.markReadLoading).toBe(false)
})
it('should set loading state during markRead', async () => {
let resolveFetch: (value: any) => void
const fetchPromise = new Promise((resolve) => {
resolveFetch = resolve
})
const mockAnnouncementController = {
markRead: jest.fn().mockReturnValue(fetchPromise),
}
;(root.get as jest.Mock).mockReturnValue(mockAnnouncementController)
const { result } = renderHook(() => useAnnouncementActions())
act(() => {
result.current.markRead('announcement-1')
})
expect(result.current.markReadLoading).toBe(true)
await act(async () => {
resolveFetch!({ message: 'success' })
await fetchPromise
})
expect(result.current.markReadLoading).toBe(false)
})
})
})