/* eslint-disable no-console */ import * as React from 'react' import { render } from '@testing-library/react' import { __POSTHOG_ERROR_MESSAGES, PostHogErrorBoundary } from '../PostHogErrorBoundary' import posthog from 'posthog-js' import { setDefaultPostHogInstance } from '../../context/posthog-default' describe('PostHogErrorBoundary component', () => { beforeEach(() => { setDefaultPostHogInstance(posthog) }) afterEach(() => { setDefaultPostHogInstance(undefined) }) mockFunction(console, 'error') mockFunction(console, 'warn') mockFunction(posthog, 'captureException') const renderWithError = (props: any) => render() const renderWithoutError = (props?: any) => render() it('should call captureException with error message', () => { const { container } = renderWithError({ message: 'Test error', fallback:
}) expect(posthog.captureException).toHaveBeenCalledWith(new Error('Test error'), undefined) expect(container.innerHTML).toBe('
') expect(console.error).toHaveBeenCalledTimes(1) expect((console.error as any).mock.calls[0][1].message).toEqual('Test error') }) it('should warn user when fallback is null', () => { const { container } = renderWithError({ fallback: null }) expect(posthog.captureException).toHaveBeenCalledWith(new Error('Error'), undefined) expect(container.innerHTML).toBe('') expect(console.warn).toHaveBeenCalledWith(__POSTHOG_ERROR_MESSAGES.INVALID_FALLBACK) }) it('should warn user when fallback is a string', () => { const { container } = renderWithError({ fallback: 'hello' }) expect(posthog.captureException).toHaveBeenCalledWith(new Error('Error'), undefined) expect(container.innerHTML).toBe('') expect(console.warn).toHaveBeenCalledWith(__POSTHOG_ERROR_MESSAGES.INVALID_FALLBACK) }) it('should add additional properties before sending event (as object)', () => { const props = { team_id: '1234' } renderWithError({ message: 'Kaboom', additionalProperties: props }) expect(posthog.captureException).toHaveBeenCalledWith(new Error('Kaboom'), props) }) it('should add additional properties before sending event (as function)', () => { const props = { team_id: '1234' } renderWithError({ message: 'Kaboom', additionalProperties: (err: Error) => { expect(err.message).toBe('Kaboom') return props }, }) expect(posthog.captureException).toHaveBeenCalledWith(new Error('Kaboom'), props) }) it('should render children without errors', () => { const { container } = renderWithoutError() expect(container.innerHTML).toBe('
Amazing content
') }) }) describe('captureException processing', () => { beforeEach(() => { setDefaultPostHogInstance(posthog) }) afterEach(() => { setDefaultPostHogInstance(undefined) }) mockFunction(console, 'error') mockFunction(console, 'warn') mockFunction(posthog, 'capture') const renderWithError = (props: any) => render() it('should call capture with a stacktrace', () => { renderWithError({ message: 'Kaboom', fallback:
, additionalProperties: {} }) const captureCalls = (posthog.capture as jest.Mock).mock.calls expect(captureCalls.length).toBe(1) const exceptionList = captureCalls[0][1].$exception_list expect(exceptionList.length).toBe(1) const stacktrace = exceptionList[0].stacktrace expect(stacktrace.frames.length).toBeGreaterThan(20) }) }) function mockFunction(object: any, funcName: string) { const originalFunc = object[funcName] beforeEach(() => { object[funcName] = jest.fn() }) afterEach(() => { object[funcName] = originalFunc }) } function ComponentWithError({ message }: { message: string }): React.ReactElement { throw new Error(message) } function RenderWithError({ message = 'Error', fallback, additionalProperties }: any) { return ( ) } function RenderWithoutError({ additionalProperties }: any) { return ( } additionalProperties={additionalProperties}>
Amazing content
) }