import Plugin from '../'
import Client from '@bugsnag/core/client'
import TestRenderer from 'react-test-renderer'
import * as React from 'react'
import { NavigationContainer, NavigationContainerRef } from '@react-navigation/native'
jest.mock('@react-navigation/native')
afterEach(() => jest.clearAllMocks())
describe('plugin: react navigation', () => {
it('should pass through props and ref to the underlying NavigationContainer', done => {
const c = new Client({ apiKey: 'aaaa-aaaa-aaaa-aaaa', plugins: [new Plugin()] })
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const BugsnagNavigationContainer = c.getPlugin('reactNavigation')!.createNavigationContainer(NavigationContainer)
expect(BugsnagNavigationContainer).toBeTruthy()
const onReady = jest.fn()
const onStateChange = jest.fn()
let ref
const App = () => {
ref = React.useRef(null)
return (
Testing 123
)
}
const MockedNavigationContainerRender = (NavigationContainer as any).render as jest.MockedFunction>
TestRenderer.create()
expect(MockedNavigationContainerRender).toBeCalledTimes(1)
const navigationProps = MockedNavigationContainerRender.mock.calls[0][0]
const navigationRef = MockedNavigationContainerRender.mock.calls[0][1]
navigationProps.onReady()
expect(onReady).toBeCalledTimes(1)
navigationProps.onStateChange()
expect(onStateChange).toBeCalledTimes(1)
expect(navigationRef).toBe(ref)
done()
})
it('should update context when the screen changes', () => {
const c = new Client({ apiKey: 'aaaa-aaaa-aaaa-aaaa', plugins: [new Plugin()] })
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const BugsnagNavigationContainer = c.getPlugin('reactNavigation')!.createNavigationContainer(NavigationContainer)
let ref
let currentRouteName = 'home'
const App = () => {
ref = React.useRef({
getCurrentRoute: () => {
return { name: currentRouteName }
}
})
return (
}>
Testing 123
)
}
const MockedNavigationContainerRender = (NavigationContainer as any).render as jest.MockedFunction>
TestRenderer.create()
expect(MockedNavigationContainerRender).toBeCalledTimes(1)
expect(c.getContext()).toBeUndefined()
const navigationProps = MockedNavigationContainerRender.mock.calls[0][0]
navigationProps.onReady()
expect(c.getContext()).toBe('home')
navigationProps.onStateChange()
expect(c.getContext()).toBe('home')
currentRouteName = 'details'
navigationProps.onStateChange()
expect(c.getContext()).toBe('details')
})
it('should leave breacrumbs when the screen changes', () => {
const c = new Client({ apiKey: 'aaaa-aaaa-aaaa-aaaa', plugins: [new Plugin()] })
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const BugsnagNavigationContainer = c.getPlugin('reactNavigation')!.createNavigationContainer(NavigationContainer)
let ref
let currentRouteName = 'home'
const App = () => {
ref = React.useRef({
getCurrentRoute: () => {
return { name: currentRouteName }
}
})
return (
}>
Testing 123
)
}
const MockedNavigationContainerRender = (NavigationContainer as any).render as jest.MockedFunction>
TestRenderer.create()
expect(MockedNavigationContainerRender).toBeCalledTimes(1)
expect(c._breadcrumbs.length).toBe(0)
const navigationProps = MockedNavigationContainerRender.mock.calls[0][0]
navigationProps.onReady()
currentRouteName = 'details'
navigationProps.onStateChange()
currentRouteName = 'settings'
navigationProps.onStateChange()
currentRouteName = 'details'
navigationProps.onStateChange()
expect(c._breadcrumbs.length).toBe(4)
expect(c._breadcrumbs[0].message).toBe('React Navigation onReady')
expect(c._breadcrumbs[0].metadata.to).toBe('home')
expect(c._breadcrumbs[1].message).toBe('React Navigation onStateChange')
expect(c._breadcrumbs[1].metadata.from).toBe('home')
expect(c._breadcrumbs[1].metadata.to).toBe('details')
expect(c._breadcrumbs[2].message).toBe('React Navigation onStateChange')
expect(c._breadcrumbs[2].metadata.from).toBe('details')
expect(c._breadcrumbs[2].metadata.to).toBe('settings')
expect(c._breadcrumbs[3].message).toBe('React Navigation onStateChange')
expect(c._breadcrumbs[3].metadata.from).toBe('settings')
expect(c._breadcrumbs[3].metadata.to).toBe('details')
})
it('should leave no breacrumbs when navigation breadcrumbs are disabled', () => {
const c = new Client({ apiKey: 'aaaa-aaaa-aaaa-aaaa', plugins: [new Plugin()], enabledBreadcrumbTypes: [] })
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const BugsnagNavigationContainer = c.getPlugin('reactNavigation')!.createNavigationContainer(NavigationContainer)
let ref
let currentRouteName = 'home'
const App = () => {
ref = React.useRef({
getCurrentRoute: () => {
return { name: currentRouteName }
}
})
return (
}>
Testing 123
)
}
const MockedNavigationContainerRender = (NavigationContainer as any).render as jest.MockedFunction>
TestRenderer.create()
expect(MockedNavigationContainerRender).toBeCalledTimes(1)
expect(c._breadcrumbs.length).toBe(0)
const navigationProps = MockedNavigationContainerRender.mock.calls[0][0]
navigationProps.onReady()
currentRouteName = 'details'
navigationProps.onStateChange()
currentRouteName = 'settings'
navigationProps.onStateChange()
currentRouteName = 'details'
navigationProps.onStateChange()
expect(c._breadcrumbs.length).toBe(0)
})
})