react-native-navigation
Version:
React Native Navigation - truly native navigation for iOS and Android
391 lines (390 loc) • 13.4 kB
JavaScript
"use strict";
import * as React from 'react';
import { render } from '@testing-library/react-native';
import { ComponentEventsObserver } from "./ComponentEventsObserver.js";
import { NativeEventsReceiver } from "../adapters/NativeEventsReceiver.mock.js";
import { Store } from "../components/Store.js";
import { jsx as _jsx } from "react/jsx-runtime";
describe('ComponentEventsObserver', () => {
const mockEventsReceiver = new NativeEventsReceiver();
const mockStore = new Store();
const willAppearFn = jest.fn();
const didAppearFn = jest.fn();
const didDisappearFn = jest.fn();
const didMountFn = jest.fn();
const willUnmountFn = jest.fn();
const navigationButtonPressedFn = jest.fn();
const searchBarUpdatedFn = jest.fn();
const searchBarCancelPressedFn = jest.fn();
const previewCompletedFn = jest.fn();
const screenPoppedFn = jest.fn();
let subscription;
let uut;
class SimpleScreen extends React.Component {
render() {
return 'Hello';
}
}
class UnboundScreen extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
didMountFn();
}
componentWillUnmount() {
willUnmountFn();
}
componentWillAppear() {
willAppearFn();
}
componentDidAppear() {
didAppearFn();
}
componentDidDisappear() {
didDisappearFn();
}
navigationButtonPressed(event) {
navigationButtonPressedFn(event);
}
searchBarUpdated(event) {
searchBarUpdatedFn(event);
}
searchBarCancelPressed(event) {
searchBarCancelPressedFn(event);
}
previewCompleted(event) {
previewCompletedFn(event);
}
screenPopped(event) {
screenPoppedFn(event);
}
render() {
return 'Hello';
}
}
class BoundScreen extends React.Component {
constructor(props) {
super(props);
subscription = uut.bindComponent(this);
}
componentDidMount() {
didMountFn();
}
componentWillUnmount() {
willUnmountFn();
}
componentWillAppear(event) {
willAppearFn(event);
}
componentDidAppear(event) {
didAppearFn(event);
}
componentDidDisappear() {
didDisappearFn();
}
navigationButtonPressed(event) {
navigationButtonPressedFn(event);
}
searchBarUpdated(event) {
searchBarUpdatedFn(event);
}
searchBarCancelPressed(event) {
searchBarCancelPressedFn(event);
}
previewCompleted(event) {
previewCompletedFn(event);
}
screenPopped(event) {
screenPoppedFn(event);
}
render() {
return 'Hello';
}
}
beforeEach(() => {
jest.clearAllMocks();
uut = new ComponentEventsObserver(mockEventsReceiver, mockStore);
});
it(`bindComponent expects a component with componentId`, () => {
const screen1 = render(/*#__PURE__*/_jsx(SimpleScreen, {}));
const instance1 = screen1.UNSAFE_getByType(SimpleScreen).instance;
expect(() => uut.bindComponent(instance1)).toThrow('');
const screen2 = render(/*#__PURE__*/_jsx(SimpleScreen, {
componentId: 123
}));
const instance2 = screen2.UNSAFE_getByType(SimpleScreen).instance;
expect(() => uut.bindComponent(instance2)).toThrow('');
});
it(`bindComponent accepts an optional componentId`, () => {
const screen = render(/*#__PURE__*/_jsx(UnboundScreen, {}));
const instance = screen.UNSAFE_getByType(UnboundScreen).instance;
uut.bindComponent(instance, 'myCompId');
expect(screen.toJSON()).toBeDefined();
expect(didAppearFn).not.toHaveBeenCalled();
uut.notifyComponentDidAppear({
componentId: 'myCompId',
componentName: 'doesnt matter',
componentType: 'Component'
});
expect(didAppearFn).toHaveBeenCalledTimes(1);
});
it(`bindComponent should use optional componentId if component has a componentId in props`, () => {
const screen = render(/*#__PURE__*/_jsx(UnboundScreen, {
componentId: 'doNotUseThisId'
}));
const instance = screen.UNSAFE_getByType(UnboundScreen).instance;
uut.bindComponent(instance, 'myCompId');
expect(screen.toJSON()).toBeDefined();
uut.notifyComponentDidAppear({
componentId: 'dontUseThisId',
componentName: 'doesnt matter',
componentType: 'Component'
});
expect(didAppearFn).not.toHaveBeenCalled();
uut.notifyComponentDidAppear({
componentId: 'myCompId',
componentName: 'doesnt matter',
componentType: 'Component'
});
expect(didAppearFn).toHaveBeenCalledTimes(1);
});
it(`bindComponent notifies listeners by componentId on events`, () => {
const screen = render(/*#__PURE__*/_jsx(BoundScreen, {
componentId: 'myCompId'
}));
expect(screen.toJSON()).toBeDefined();
expect(didMountFn).toHaveBeenCalledTimes(1);
expect(didAppearFn).not.toHaveBeenCalled();
expect(didDisappearFn).not.toHaveBeenCalled();
expect(willUnmountFn).not.toHaveBeenCalled();
uut.notifyComponentDidAppear({
componentId: 'myCompId',
componentName: 'doesnt matter',
componentType: 'Component'
});
expect(didAppearFn).toHaveBeenCalledTimes(1);
uut.notifyComponentDidDisappear({
componentId: 'myCompId',
componentName: 'doesnt matter',
componentType: 'Component'
});
expect(didDisappearFn).toHaveBeenCalledTimes(1);
uut.notifyNavigationButtonPressed({
componentId: 'myCompId',
buttonId: 'myButtonId'
});
expect(navigationButtonPressedFn).toHaveBeenCalledTimes(1);
expect(navigationButtonPressedFn).toHaveBeenCalledWith({
buttonId: 'myButtonId',
componentId: 'myCompId'
});
uut.notifySearchBarUpdated({
componentId: 'myCompId',
text: 'theText',
isFocused: true
});
expect(searchBarUpdatedFn).toHaveBeenCalledTimes(1);
expect(searchBarUpdatedFn).toHaveBeenCalledWith({
componentId: 'myCompId',
text: 'theText',
isFocused: true
});
uut.notifySearchBarCancelPressed({
componentId: 'myCompId'
});
expect(searchBarCancelPressedFn).toHaveBeenCalledTimes(1);
expect(searchBarCancelPressedFn).toHaveBeenCalledWith({
componentId: 'myCompId'
});
uut.notifyPreviewCompleted({
componentId: 'myCompId'
});
expect(previewCompletedFn).toHaveBeenCalledTimes(1);
expect(previewCompletedFn).toHaveBeenCalledWith({
componentId: 'myCompId'
});
uut.notifyScreenPopped({
componentId: 'myCompId'
});
expect(screenPoppedFn).toHaveBeenCalledTimes(1);
expect(screenPoppedFn).toHaveBeenLastCalledWith({
componentId: 'myCompId'
});
screen.unmount();
expect(willUnmountFn).toHaveBeenCalledTimes(1);
});
it(`registerComponentListener accepts listener object`, () => {
const screen = render(/*#__PURE__*/_jsx(UnboundScreen, {}));
const didAppearListenerFn = jest.fn();
uut.registerComponentListener({
componentDidAppear: didAppearListenerFn
}, 'myCompId');
expect(screen.toJSON()).toBeDefined();
expect(didAppearListenerFn).not.toHaveBeenCalled();
uut.notifyComponentDidAppear({
componentId: 'myCompId',
componentName: 'doesnt matter',
componentType: 'Component'
});
expect(didAppearListenerFn).toHaveBeenCalledTimes(1);
});
it(`componentDidAppear should receive component props from store`, () => {
const event = {
componentId: 'myCompId',
componentType: 'Component',
passProps: {
propA: 'propA'
},
componentName: 'doesnt matter'
};
render(/*#__PURE__*/_jsx(BoundScreen, {
componentId: event.componentId
}));
mockStore.updateProps(event.componentId, event.passProps);
expect(didAppearFn).not.toHaveBeenCalled();
uut.notifyComponentDidAppear({
componentId: 'myCompId',
componentName: 'doesnt matter',
componentType: 'Component'
});
expect(didAppearFn).toHaveBeenCalledTimes(1);
expect(didAppearFn).toHaveBeenCalledWith(event);
});
it(`componentWillAppear should receive component props from store`, () => {
const event = {
componentId: 'myCompId',
componentType: 'Component',
passProps: {
propA: 'propA'
},
componentName: 'doesnt matter'
};
render(/*#__PURE__*/_jsx(BoundScreen, {
componentId: event.componentId
}));
mockStore.updateProps(event.componentId, event.passProps);
expect(willAppearFn).not.toHaveBeenCalled();
uut.notifyComponentWillAppear({
componentId: 'myCompId',
componentName: 'doesnt matter',
componentType: 'Component'
});
expect(willAppearFn).toHaveBeenCalledTimes(1);
expect(willAppearFn).toHaveBeenCalledWith(event);
});
it(`doesnt call other componentIds`, () => {
render(/*#__PURE__*/_jsx(BoundScreen, {
componentId: 'myCompId'
}));
uut.notifyComponentDidAppear({
componentId: 'other',
componentName: 'doesnt matter',
componentType: 'Component'
});
expect(didAppearFn).not.toHaveBeenCalled();
});
it(`doesnt call unimplemented methods`, () => {
const screen = render(/*#__PURE__*/_jsx(SimpleScreen, {
componentId: 'myCompId'
}));
const instance = screen.UNSAFE_getByType(SimpleScreen).instance;
expect(instance.componentDidAppear).toBeUndefined();
uut.bindComponent(instance);
uut.notifyComponentDidAppear({
componentId: 'myCompId',
componentName: 'doesnt matter',
componentType: 'Component'
});
});
it(`returns unregister fn`, () => {
render(/*#__PURE__*/_jsx(BoundScreen, {
componentId: '123'
}));
uut.notifyComponentDidAppear({
componentId: '123',
componentName: 'doesnt matter',
componentType: 'Component'
});
expect(didAppearFn).toHaveBeenCalledTimes(1);
subscription.remove();
uut.notifyComponentDidAppear({
componentId: '123',
componentName: 'doesnt matter',
componentType: 'Component'
});
expect(didAppearFn).toHaveBeenCalledTimes(1);
});
it(`removeAllListenersForComponentId`, () => {
render(/*#__PURE__*/_jsx(BoundScreen, {
componentId: '123'
}));
render(/*#__PURE__*/_jsx(BoundScreen, {
componentId: '123'
}));
uut.unmounted('123');
uut.notifyComponentDidAppear({
componentId: '123',
componentName: 'doesnt matter',
componentType: 'Component'
});
expect(didAppearFn).not.toHaveBeenCalled();
});
it(`supports multiple listeners with same componentId`, () => {
const screen1 = render(/*#__PURE__*/_jsx(SimpleScreen, {
componentId: 'myCompId'
}));
const screen2 = render(/*#__PURE__*/_jsx(SimpleScreen, {
componentId: 'myCompId'
}));
const instance1 = screen1.UNSAFE_getByType(SimpleScreen).instance;
const instance2 = screen2.UNSAFE_getByType(SimpleScreen).instance;
instance1.componentDidAppear = jest.fn();
instance2.componentDidAppear = jest.fn();
const result1 = uut.bindComponent(instance1);
const result2 = uut.bindComponent(instance2);
expect(result1).not.toEqual(result2);
uut.notifyComponentDidAppear({
componentId: 'myCompId',
componentName: 'doesnt matter',
componentType: 'Component'
});
expect(instance1.componentDidAppear).toHaveBeenCalledTimes(1);
expect(instance2.componentDidAppear).toHaveBeenCalledTimes(1);
result2.remove();
uut.notifyComponentDidAppear({
componentId: 'myCompId',
componentName: 'doesnt matter',
componentType: 'Component'
});
expect(instance1.componentDidAppear).toHaveBeenCalledTimes(2);
expect(instance2.componentDidAppear).toHaveBeenCalledTimes(1);
result1.remove();
uut.notifyComponentDidAppear({
componentId: 'myCompId',
componentName: 'doesnt matter',
componentType: 'Component'
});
expect(instance1.componentDidAppear).toHaveBeenCalledTimes(2);
expect(instance2.componentDidAppear).toHaveBeenCalledTimes(1);
});
it(`register for all native component events notifies self on events, once`, () => {
expect(mockEventsReceiver.registerComponentDidAppearListener).not.toHaveBeenCalled();
expect(mockEventsReceiver.registerComponentDidDisappearListener).not.toHaveBeenCalled();
expect(mockEventsReceiver.registerNavigationButtonPressedListener).not.toHaveBeenCalled();
expect(mockEventsReceiver.registerSearchBarUpdatedListener).not.toHaveBeenCalled();
expect(mockEventsReceiver.registerSearchBarCancelPressedListener).not.toHaveBeenCalled();
expect(mockEventsReceiver.registerPreviewCompletedListener).not.toHaveBeenCalled();
uut.registerOnceForAllComponentEvents();
uut.registerOnceForAllComponentEvents();
uut.registerOnceForAllComponentEvents();
uut.registerOnceForAllComponentEvents();
expect(mockEventsReceiver.registerComponentDidAppearListener).toHaveBeenCalledTimes(1);
expect(mockEventsReceiver.registerComponentDidDisappearListener).toHaveBeenCalledTimes(1);
expect(mockEventsReceiver.registerNavigationButtonPressedListener).toHaveBeenCalledTimes(1);
expect(mockEventsReceiver.registerSearchBarUpdatedListener).toHaveBeenCalledTimes(1);
expect(mockEventsReceiver.registerSearchBarCancelPressedListener).toHaveBeenCalledTimes(1);
expect(mockEventsReceiver.registerPreviewCompletedListener).toHaveBeenCalledTimes(1);
});
});
//# sourceMappingURL=ComponentEventsObserver.test.js.map