import {render, RenderResult, waitFor} from '@testing-library/react'
import {ErrorBoundary} from '../ErrorBoundary'
import {mock, MockProxy} from 'jest-mock-extended'
import {ILogger} from '../../logger/ILogger'
import {TFunction} from 'react-i18next'
import i18n from 'i18next'
import {I18nextProvider, initReactI18next} from 'react-i18next'
i18n.use(initReactI18next).init({
resources: {},
lng: 'en',
})
const mockTFunction: TFunction = label => label
const mockThrownError = new Error('some-error')
const ThrowingInRenderChild = () => {
throw mockThrownError
}
const MockProviders = (props: any) => (
{props.children}
)
describe('Given an ErrorBoundary component', () => {
let mockLogger: MockProxy
beforeEach(() => {
mockLogger = mock()
})
describe('when there is an error in a Child component', () => {
let renderResult: RenderResult
beforeEach(async () => {
renderResult = await waitFor(() =>
render(
,
),
)
})
it('should render the fallback ui', async () => {
expect(renderResult.getByText('errorBoundary.modal.header')).toBeTruthy()
})
it('should log error and component stack', async () => {
expect(mockLogger.error).toHaveBeenCalledTimes(1)
expect(mockLogger.error).toHaveBeenCalledWith(mockThrownError, {
componentStack: expect.any(String),
})
})
})
describe('when the component is mounted', () => {
let mockWindowObject: any
let eventHandlers: Record
beforeEach(() => {
eventHandlers = {}
mockWindowObject = {
addEventListener: jest
.fn()
.mockImplementation(
(name, callback) => (eventHandlers[name] = callback),
),
removeEventListener: jest.fn(),
}
render(
some content
,
)
})
describe('when an unhandledjerection event is fired', () => {
beforeEach(() => {
const mockError: Partial = {
reason: 'some-reason',
}
eventHandlers.unhandledrejection(mockError)
})
it('should log the error', () => {
expect(mockLogger.error).toHaveBeenCalledTimes(1)
expect(mockLogger.error).toHaveBeenCalledWith('some-reason')
})
})
describe('when an error event is fired', () => {
let mockError: Partial
describe('when the actual error is avilable', () => {
beforeEach(() => {
mockError = {
error: {
stack: 'some-stack',
},
}
eventHandlers.error(mockError)
})
it('should log the error', () => {
expect(mockLogger.error).toHaveBeenCalledTimes(1)
expect(mockLogger.error).toHaveBeenCalledWith(mockError.error)
})
})
describe('when the actual error is not avilable', () => {
beforeEach(() => {
mockError = {
error: undefined,
message: 'some-message',
}
eventHandlers.error(mockError)
})
it('should log the message', () => {
expect(mockLogger.error).toHaveBeenCalledTimes(1)
expect(mockLogger.error).toHaveBeenCalledWith(mockError.message)
})
})
})
})
})