import { render } from '@testing-library/react-native'
import React from 'react'
import { Text } from 'react-native'
import { FailedResponse } from '../../../types/api_primitives'
import { Log } from '../../../utils/native_adapters/configuration'
import { ResponseError } from '../../../utils/response_error'
import { ErrorBoundary } from '../error_boundary'
function Boom({ thrown }: { thrown: unknown }): React.ReactElement {
throw thrown
}
describe('ErrorBoundary', () => {
let reportError: jest.SpyInstance
let consoleError: jest.SpyInstance
beforeEach(() => {
reportError = jest.spyOn(Log, 'reportError').mockImplementation(() => {})
consoleError = jest.spyOn(console, 'error').mockImplementation(() => {})
})
afterEach(() => {
reportError.mockRestore()
consoleError.mockRestore()
})
it('reports caught errors with the component stack and chat tags', () => {
const error = new TypeError('Invalid time value')
render(
)
expect(reportError).toHaveBeenCalledTimes(1)
const [reportedError, context] = reportError.mock.calls[0]
expect(reportedError).toBe(error)
expect(context).toMatchObject({
scope: 'screen',
screenName: 'ConversationScreen',
tags: { team: 'chat', package: 'chat-react-native' },
})
expect(typeof context.componentStack).toBe('string')
expect(context.componentStack.length).toBeGreaterThan(0)
})
it('does not report ResponseError — those are owned by the HTTP layer', () => {
const failure = {
status: 500,
statusText: 'Server Error',
errors: [],
} as unknown as FailedResponse
render(
)
expect(reportError).not.toHaveBeenCalled()
})
it('renders the provided fallback element when a child throws', () => {
const { getByText } = render(
custom fallback}>
)
expect(getByText('custom fallback')).toBeTruthy()
})
it('renders nothing when no fallback is provided', () => {
const { toJSON } = render(
)
expect(toJSON()).toBeNull()
})
it('calls a fallback render function with the caught error and a reset handler', () => {
const fallback = jest.fn().mockReturnValue(fn fallback)
const error = new Error('boom')
const { getByText } = render(
)
expect(getByText('fn fallback')).toBeTruthy()
expect(fallback).toHaveBeenCalledWith(error, expect.any(Function))
})
})