UNPKG

metadata-based-explorer1

Version:
374 lines (317 loc) 12.8 kB
/* eslint-disable react/button-has-type */ import React from 'react'; import sinon from 'sinon'; import Tooltip from '../Tooltip'; const sandbox = sinon.sandbox.create(); describe('components/tooltip/Tooltip', () => { const getWrapper = props => shallow( <Tooltip text="hi" {...props}> <div>Hello</div> </Tooltip>, ); afterEach(() => { sandbox.verifyAndRestore(); }); describe('render()', () => { test('should render with close button if isShown and showCloseButton are true', () => { expect( getWrapper({ isShown: true, showCloseButton: true, }), ).toMatchSnapshot(); }); test('should not render the close button if wasClosedByUser state is true', () => { const wrapper = getWrapper({ isShown: true, showCloseButton: true, }); wrapper.setState({ wasClosedByUser: true }); expect(wrapper).toMatchSnapshot(); }); test('should not render with close button if showCloseButton is false', () => { expect( getWrapper({ isShown: true, showCloseButton: false, }), ).toMatchSnapshot(); }); test('should not render with close button if isShown is false', () => { const wrapper = getWrapper({ isShown: false, showCloseButton: true, }); wrapper.setState({ isShown: true }); expect(wrapper).toMatchSnapshot(); }); test('should render correctly with callout theme', () => { expect( getWrapper({ isShown: true, theme: 'callout', }), ).toMatchSnapshot(); }); test('should render default component', () => { const wrapper = shallow( <Tooltip text="hi"> <button /> </Tooltip>, ); const component = wrapper.children(); expect(wrapper.is('TetherComponent')).toBe(true); expect(wrapper.prop('attachment')).toEqual('bottom center'); expect(wrapper.prop('constraints')).toEqual([ { to: 'window', attachment: 'together', }, ]); expect(wrapper.prop('enabled')).toBe(false); expect(wrapper.prop('targetAttachment')).toEqual('top center'); expect(component.is('button')).toBe(true); expect(component.prop('onBlur')).toBeTruthy(); expect(component.prop('onFocus')).toBeTruthy(); expect(component.prop('onKeyDown')).toBeTruthy(); expect(component.prop('onMouseEnter')).toBeTruthy(); expect(component.prop('onMouseLeave')).toBeTruthy(); expect(component.prop('tabIndex')).toEqual('0'); }); test('should not add tabindex if isTabbable is false', () => { const wrapper = shallow( <Tooltip isShown isTabbable={false} text="hi"> <button /> </Tooltip>, ); const component = wrapper.find('button'); expect(component.prop('tabIndex')).toBeFalsy(); }); test('should show tooltip when isShown state is true', () => { const wrapper = shallow( <Tooltip text="hi"> <button /> </Tooltip>, ); wrapper.setState({ isShown: true }); const component = wrapper.childAt(0); const tooltip = wrapper.childAt(1); expect(wrapper.prop('enabled')).toBe(true); expect(tooltip.is('div')).toBe(true); expect(tooltip.hasClass('tooltip')).toBe(true); expect(component.prop('aria-describedby')).toEqual(tooltip.prop('id')); expect(tooltip.text()).toEqual('hi'); }); test('should render tooltip class when specified', () => { const wrapper = shallow( <Tooltip className="testing" isShown text="hi"> <button /> </Tooltip>, ); expect(wrapper.find('[role="tooltip"]').hasClass('testing')).toBe(true); }); test('should constrain to scroll parent when specified', () => { const wrapper = shallow( <Tooltip constrainToScrollParent text="hi"> <button /> </Tooltip>, ); expect(wrapper.prop('constraints')).toEqual([ { to: 'scrollParent', attachment: 'together', }, { to: 'window', attachment: 'together', }, ]); }); test('should render correct attachments when position is specified', () => { const wrapper = shallow( <Tooltip position="middle-right" text="hi"> <button /> </Tooltip>, ); expect(wrapper.prop('attachment')).toEqual('middle left'); expect(wrapper.prop('targetAttachment')).toEqual('middle right'); }); test('should render with a specific body element', () => { const bodyEl = document.createElement('div'); const wrapper = shallow( <Tooltip bodyElement={bodyEl} text="hi"> <button /> </Tooltip>, ); expect(wrapper.prop('bodyElement')).toEqual(bodyEl); }); test('should render TetherComponent in the body if invalid body element is specified', () => { const wrapper = shallow( <Tooltip bodyElement="foo" text="hi"> <button /> </Tooltip>, ); expect(wrapper.prop('bodyElement')).toEqual(document.body); }); test('should show tooltip when isShown prop is true', () => { const wrapper = shallow( <Tooltip isShown text="hi"> <button /> </Tooltip>, ); const component = wrapper.childAt(0); const tooltip = wrapper.childAt(1); expect(wrapper.prop('enabled')).toBe(true); expect(component.prop('onBlur')).toBeFalsy(); expect(component.prop('onFocus')).toBeFalsy(); expect(component.prop('onKeyDown')).toBeFalsy(); expect(component.prop('onMouseEnter')).toBeFalsy(); expect(component.prop('onMouseLeave')).toBeFalsy(); expect(component.prop('tabIndex')).toBeFalsy(); expect(tooltip.is('div')).toBe(true); expect(tooltip.hasClass('tooltip')).toBe(true); expect(component.prop('aria-describedby')).toEqual(tooltip.prop('id')); expect(tooltip.text()).toEqual('hi'); }); test('should render error class when theme is error', () => { const wrapper = shallow( <Tooltip isShown text="hi" theme="error"> <button /> </Tooltip>, ); expect(wrapper.find('[role="tooltip"]').hasClass('is-error')).toBe(true); }); test('should render children only when tooltip is disabled', () => { expect( getWrapper({ isDisabled: true, }), ).toMatchSnapshot(); }); test('should render children wrapped in tether when tooltip has text missing', () => { expect( getWrapper({ text: null, }), ).toMatchSnapshot(); }); }); describe('closeTooltip()', () => { test('should update the wasClosedByUser state', () => { const wrapper = shallow( <Tooltip text="hi"> <button /> </Tooltip>, ); expect(wrapper.state('wasClosedByUser')).toBe(false); wrapper.instance().closeTooltip(); expect(wrapper.state('wasClosedByUser')).toBe(true); }); test('should call onDismiss if provided', () => { const onDismissMock = jest.fn(); const wrapper = shallow( <Tooltip text="hi" onDismiss={onDismissMock}> <button /> </Tooltip>, ); wrapper.instance().closeTooltip(); expect(onDismissMock).toHaveBeenCalled(); }); }); describe('handleMouseEnter()', () => { test('should correctly handle mouseenter events', () => { const onMouseEnter = sinon.spy(); const wrapper = shallow( <Tooltip text="hi"> <button onMouseEnter={onMouseEnter} /> </Tooltip>, ); wrapper.find('button').simulate('mouseenter'); expect(wrapper.state('isShown')).toBe(true); expect(onMouseEnter.calledOnce).toBe(true); }); }); describe('handleMouseLeave()', () => { test('should correctly handle mouseleave events', () => { const onMouseLeave = sinon.spy(); const wrapper = shallow( <Tooltip text="hi"> <button onMouseLeave={onMouseLeave} /> </Tooltip>, ); wrapper.setState({ isShown: true }); wrapper.find('button').simulate('mouseleave'); expect(wrapper.state('isShown')).toBe(false); expect(onMouseLeave.calledOnce).toBe(true); }); }); describe('handleFocus()', () => { test('should correctly handle focus events', () => { const onFocus = sinon.spy(); const wrapper = shallow( <Tooltip text="hi"> <button onFocus={onFocus} /> </Tooltip>, ); wrapper.find('button').simulate('focus'); expect(wrapper.state('isShown')).toBe(true); expect(onFocus.calledOnce).toBe(true); }); }); describe('handleBlur()', () => { test('should correctly handle blur events', () => { const onBlur = sinon.spy(); const wrapper = shallow( <Tooltip text="hi"> <button onBlur={onBlur} /> </Tooltip>, ); wrapper.setState({ isShown: true }); wrapper.find('button').simulate('blur'); expect(wrapper.state('isShown')).toBe(false); expect(onBlur.calledOnce).toBe(true); }); }); describe('handleKeyDown()', () => { test('should update isShown state only when escape key is pressed', () => { const wrapper = shallow( <Tooltip text="hi"> <button /> </Tooltip>, ); wrapper.setState({ isShown: true }); wrapper.find('button').simulate('keydown', { key: 'Escape' }); expect(wrapper.state('isShown')).toBe(false); }); test('should not update isShown state only when some other key is pressed', () => { const wrapper = shallow( <Tooltip text="hi"> <button /> </Tooltip>, ); wrapper.setState({ isShown: true }); wrapper.find('button').simulate('keydown', { key: 'Space' }); expect(wrapper.state('isShown')).toBe(true); }); test('should call keydown handler of component when specified', () => { const onKeyDown = sinon.spy(); const wrapper = shallow( <Tooltip text="hi"> <button onKeyDown={onKeyDown} /> </Tooltip>, ); wrapper.find('button').simulate('keydown', { key: 'Escape' }); expect(onKeyDown.calledOnce).toBe(true); }); }); describe('position instance method', () => { test.each([true, false])(`should only position the tether when shown`, isShown => { const positionTetherMock = jest.fn(); const wrapper = getWrapper({ isShown }); wrapper.instance().tetherRef = { current: { position: positionTetherMock } }; wrapper.instance().position(); expect(positionTetherMock).toHaveBeenCalledTimes(isShown ? 1 : 0); }); }); });