import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { render } from '@testing-library/react-native' import React from 'react' import { buildTestQueryClient } from '../../../__utils__/query_client' import { ChatProvider } from '../../../contexts/chat_context' import { useConversationMessage } from '../../../hooks/use_conversation_message' import type { MessageResource } from '../../../types/resources/message' import type { PersonResource } from '../../../types/resources/person' import { ReplyShadowMessage } from '../reply_shadow_message' jest.mock('../../../hooks/use_conversation_message') jest.mock('@react-navigation/native', () => ({ useNavigation: () => ({ navigate: jest.fn() }), })) const mockedUseConversationMessage = useConversationMessage as jest.MockedFunction< typeof useConversationMessage > const author = { id: 1, type: 'Person', name: 'A', avatar: null } as unknown as PersonResource const root = (text: string): MessageResource => ({ type: 'Message', id: 'rootA', text, html: '', createdAt: '2026-01-01T00:00:00Z', deletedAt: null, textEditedAt: null, mine: false, attachments: [], author, reactionCounts: [], replyCount: 1, replyRootId: 'rootA', messageType: 'message', }) as MessageResource let queryClient: QueryClient const hookResult = (overrides: { message?: MessageResource; isError?: boolean }) => ({ message: undefined, isError: false, isLoading: false, ...overrides }) as ReturnType< typeof useConversationMessage > const Wrapper = ({ children }: { children: React.ReactNode }) => ( {}, theme: { theme: { colors: { interaction: 'rgb(0, 0, 255)' } } }, }} > {children} ) const renderShadow = (replyRoot: MessageResource | null) => render( , { wrapper: Wrapper } ) beforeEach(() => { queryClient = buildTestQueryClient() mockedUseConversationMessage.mockReturnValue(hookResult({})) }) afterEach(() => { queryClient.clear() jest.clearAllMocks() }) describe('ReplyShadowMessage', () => { it('renders the inline root without enabling the root fetch', () => { const view = renderShadow(root('inline root')) expect(view.getByText('inline root')).toBeTruthy() expect(mockedUseConversationMessage).toHaveBeenCalledWith( expect.objectContaining({ enabled: false }) ) }) it('falls back to fetching the root when none is inline', () => { mockedUseConversationMessage.mockReturnValue(hookResult({ message: root('fetched root') })) const view = renderShadow(null) expect(view.getByText('fetched root')).toBeTruthy() expect(mockedUseConversationMessage).toHaveBeenCalledWith( expect.objectContaining({ messageId: 'rootA', enabled: true }) ) }) it('shows the deleted placeholder when the fallback fetch finds nothing', () => { mockedUseConversationMessage.mockReturnValue(hookResult({ isError: true })) const view = renderShadow(null) expect(view.getByText('Message deleted')).toBeTruthy() }) })