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>
This commit is contained in:
imeepos
2026-01-21 14:53:03 +08:00
parent 83c3183be8
commit 6c17d720ca
4 changed files with 255 additions and 0 deletions

View File

@@ -0,0 +1,101 @@
import { renderHook, act } from '@testing-library/react-native'
import { useAnnouncementUnreadCount } from './use-announcement-unread-count'
import { root } from '@repo/core'
import { AnnouncementController } from '@repo/sdk'
jest.mock('@repo/core', () => ({
root: {
get: jest.fn(),
},
}))
describe('useAnnouncementUnreadCount', () => {
beforeEach(() => {
jest.clearAllMocks()
})
afterEach(() => {
jest.restoreAllMocks()
})
describe('initial state', () => {
it('should return initial state', () => {
const mockAnnouncementController = {
getUnreadCount: jest.fn(),
}
;(root.get as jest.Mock).mockReturnValue(mockAnnouncementController)
const { result } = renderHook(() => useAnnouncementUnreadCount())
expect(result.current.data).toBeUndefined()
expect(result.current.loading).toBe(false)
expect(result.current.error).toBeNull()
})
})
describe('refetch', () => {
it('should fetch unread count successfully', async () => {
const mockData = { count: 5 }
const mockAnnouncementController = {
getUnreadCount: jest.fn().mockResolvedValue(mockData),
}
;(root.get as jest.Mock).mockReturnValue(mockAnnouncementController)
const { result } = renderHook(() => useAnnouncementUnreadCount())
await act(async () => {
await result.current.refetch()
})
expect(mockAnnouncementController.getUnreadCount).toHaveBeenCalled()
expect(result.current.data).toEqual(mockData)
expect(result.current.loading).toBe(false)
expect(result.current.error).toBeNull()
})
it('should handle fetch error', async () => {
const mockError = new Error('Failed to fetch unread count')
const mockAnnouncementController = {
getUnreadCount: jest.fn().mockRejectedValue(mockError),
}
;(root.get as jest.Mock).mockReturnValue(mockAnnouncementController)
const { result } = renderHook(() => useAnnouncementUnreadCount())
await act(async () => {
await result.current.refetch()
})
expect(result.current.error).toEqual(mockError)
expect(result.current.data).toBeUndefined()
expect(result.current.loading).toBe(false)
})
it('should set loading state during fetch', async () => {
let resolveFetch: (value: any) => void
const fetchPromise = new Promise((resolve) => {
resolveFetch = resolve
})
const mockAnnouncementController = {
getUnreadCount: jest.fn().mockReturnValue(fetchPromise),
}
;(root.get as jest.Mock).mockReturnValue(mockAnnouncementController)
const { result } = renderHook(() => useAnnouncementUnreadCount())
act(() => {
result.current.refetch()
})
expect(result.current.loading).toBe(true)
await act(async () => {
resolveFetch!({ count: 3 })
await fetchPromise
})
expect(result.current.loading).toBe(false)
})
})
})