import _, { forEach, has } from 'lodash'; import React from 'react'; import { mount, shallow } from 'enzyme'; import { common } from '../../util/generic-tests'; import SidePanel from './SidePanel'; import Overlay from '../Overlay/Overlay'; import DragCaptureZone from '../DragCaptureZone/DragCaptureZone'; describe('SidePanel', () => { common(SidePanel); describe('pass throughs', () => { let wrapper: any; const defaultProps = SidePanel.defaultProps; beforeEach(() => { const props = { ...defaultProps, className: 'wut', isModal: false, isExpanded: false, isAnimated: false, isResizeDisabled: true, position: 'left' as any, preventBodyScroll: true, topOffset: 10, width: 1000, minWidth: 500, maxWidth: 2000, style: { marginRight: 10 }, initialState: { test: true }, callbackId: 1, 'data-testid': 10, Header: (
Rich content
), }; wrapper = shallow(); }); afterEach(() => { wrapper.unmount(); }); it('passes through props not defined in `propTypes` to the root element.', () => { const rootProps = wrapper.find('.lucid-SidePanel').props(); // Note: 'className', 'style' and 'isAnimated' are plucked from the pass through object // but still appear becuase they are also directly passed to the root `Overlay` element as a prop. // 'isShown' appears because it is calculated based on the 'isExpanded' prop. // The root `Overlay` element is not a DOM element so 'callbackId', if it exists, is also passed through. forEach( [ 'className', 'isShown', 'onEscape', 'isAnimated', 'style', 'isModal', 'data-testid', 'callbackId', 'children', ], (prop) => { expect(has(rootProps, prop)).toBe(true); } ); expect(wrapper.first().prop(['className'])).toContain('wut'); expect(wrapper.first().prop(['isShown'])).toBe(false); // set based on isExpaneded expect(wrapper.first().prop(['isAnimated'])).toBe(false); expect(wrapper.first().prop(['isModal'])).toBe(false); expect(wrapper.first().prop(['style'])).toMatchObject({ marginRight: 10, }); expect(wrapper.first().prop(['data-testid'])).toBe(10); expect(wrapper.first().prop(['callbackId'])).toBe(1); }); it('omits the props defined in `propTypes` from the root element, plus, in addition, `initialState`.', () => { const rootProps = wrapper.find('.lucid-SidePanel').props(); forEach( [ 'Header', 'isExpanded', 'isResizeDisabled', 'onCollapse', 'onResize', 'position', 'preventBodyScroll', 'width', 'minWidth', 'maxWidth', 'topOffset', 'initialState', ], (prop) => { expect(has(rootProps, prop)).toBe(false); } ); }); }); describe('Events', () => { describe('onCollapse', () => { it('should be called when Overlay background is clicked', () => { const onCollapse = jest.fn(); const wrapper = shallow(); const overlayWrapper = wrapper.find(Overlay); const mockEvent: any = new Event('click'); overlayWrapper.prop('onBackgroundClick')({ event: mockEvent, props: overlayWrapper.props(), }); expect(onCollapse).toHaveBeenCalled(); }); it('should be called when Escape key is pressed', () => { const onCollapse = jest.fn(); const wrapper = shallow(); const overlayWrapper = wrapper.find(Overlay); const mockEvent: any = new Event('keypress'); overlayWrapper.prop('onEscape')({ event: mockEvent, props: overlayWrapper.props(), }); expect(onCollapse).toHaveBeenCalled(); }); it('should be called when the close icon is clicked', () => { const onCollapse = jest.fn(); const wrapper = shallow( ); const crossIconWrapper = wrapper.find( '.lucid-SidePanel-header-closer-button' ); crossIconWrapper.simulate('click', { event: 'abc' }); expect(onCollapse).toHaveBeenCalled(); }); }); describe('onResize', () => { it('should be called when the resizer stops being dragged', () => { const onResize = jest.fn(); const wrapper = shallow(); const dragCaptureZoneWrapper = wrapper.find(DragCaptureZone); const mockEvent = new Event('mouseup'); dragCaptureZoneWrapper.prop('onDragEnd')( { dx: 100, dy: 0, pageX: 100, pageY: 0, } as any, { event: mockEvent, props: dragCaptureZoneWrapper.props(), } as any ); expect(onResize).toHaveBeenCalled(); }); }); }); describe('preventBodyScroll', () => { it('should hide the body overflow to prevent scrolling', () => { mount(); expect(document.body.style.overflow).toEqual('hidden'); }); it('should hide the body overflow to prevent scrolling', () => { const wrapper = mount(); wrapper.unmount(); expect(document.body.style.overflow).toEqual(''); }); }); describe('position', () => { it('should match snapshot and apply the appropriate class', () => { const wrapper = shallow(); expect( wrapper .find('.lucid-SidePanel') .hasClass('lucid-SidePanel-position-left') ).toEqual(true); expect(wrapper).toMatchSnapshot(); }); it('should match snapshot and apply the appropriate class', () => { const wrapper = shallow(); expect( wrapper .find('.lucid-SidePanel') .hasClass('lucid-SidePanel-position-right') ).toEqual(true); expect(wrapper).toMatchSnapshot(); }); }); describe('isResizeDisabled', () => { it('should match snapshot', () => { const wrapper = shallow(); expect(wrapper).toMatchSnapshot(); }); }); describe('isAnimated', () => { it('should match snapshot and apply the appropriate class', () => { const wrapper = shallow(); expect( wrapper.find('.lucid-SidePanel').hasClass('lucid-SidePanel-is-animated') ).toEqual(true); expect(wrapper).toMatchSnapshot(); }); }); describe('isExpanded', () => { it('should match snapshot and apply the appropriate class', () => { const wrapper = shallow(); wrapper.setState({ isExpanded: true }); expect(wrapper).toMatchSnapshot(); expect( wrapper.find('.lucid-SidePanel').hasClass('lucid-SidePanel-is-expanded') ).toEqual(true); }); }); describe('width', () => { it('should match snapshot', () => { const wrapper = shallow(); expect(wrapper).toMatchSnapshot(); }); }); describe('Header', () => { it('should match snapshot', () => { const wrapper = shallow(); expect(wrapper).toMatchSnapshot(); }); }); });