import * as React from 'react'; import { domEvent, nextFrame, mountWithProvider } from 'test/utils'; import { Portal } from 'src/components/Portal/Portal'; import { PortalInner } from 'src/components/Portal/PortalInner'; import { act } from 'react-dom/test-utils'; describe('Portal', () => { const testPortalInnerIsOpen = (rootWrapper, visible: boolean) => { expect(rootWrapper.find(PortalInner).length).toBe(visible ? 1 : 0); }; const testPortalOpenState = (rootWrapper, content: React.ReactNode, isOpen: boolean) => { const portalIsOpen = isOpen; testPortalInnerIsOpen(rootWrapper, portalIsOpen); expect(rootWrapper.contains(content)).toBe(portalIsOpen); }; it('translates open prop to state', () => { const content =

; const wrapper = mountWithProvider(} />); testPortalOpenState(wrapper, content, false); const openPortalWrapper = mountWithProvider(} open />); testPortalOpenState(openPortalWrapper, content, true); }); describe('click', () => { it('opens the portal on trigger click when true', () => { const wrapper = mountWithProvider(} trigger={} />); testPortalInnerIsOpen(wrapper, false); wrapper.find('button').simulate('click'); testPortalInnerIsOpen(wrapper, true); }); it('closes the portal on click when set', () => { const wrapper = mountWithProvider(} defaultOpen trigger={} />); testPortalInnerIsOpen(wrapper, true); wrapper.find('button').simulate('click'); testPortalInnerIsOpen(wrapper, false); }); }); describe('document click', () => { it('closes the portal', async () => { const wrapper = mountWithProvider(} defaultOpen />); testPortalInnerIsOpen(wrapper, true); await nextFrame(); act(() => { domEvent.click(document.body); }); wrapper.update(); testPortalInnerIsOpen(wrapper, false); }); it('does not close on click inside', () => { const wrapper = mountWithProvider(} defaultOpen />); testPortalInnerIsOpen(wrapper, true); domEvent.click('#inner'); wrapper.update(); testPortalInnerIsOpen(wrapper, true); }); }); describe('onMount', () => { it('called when portal opens', () => { const onMount = jest.fn(); const wrapper = mountWithProvider(} onMount={onMount} />); wrapper.setProps({ open: true } as any); expect(onMount).toHaveBeenCalledTimes(1); }); }); describe('onUnmount', () => { it('is called when portal closes', () => { const onUnmount = jest.fn(); const wrapper = mountWithProvider(} onUnmount={onUnmount} open />); wrapper.setProps({ open: false } as any); expect(onUnmount).toHaveBeenCalledTimes(1); }); it('is called only once when portal closes and then is unmounted', () => { const onUnmount = jest.fn(); const wrapper = mountWithProvider(} onUnmount={onUnmount} open />); wrapper.setProps({ open: false } as any); wrapper.unmount(); expect(onUnmount).toHaveBeenCalledTimes(1); }); it('is called only once when directly unmounting', () => { const onUnmount = jest.fn(); const wrapper = mountWithProvider(} onUnmount={onUnmount} open />); wrapper.unmount(); expect(onUnmount).toHaveBeenCalledTimes(1); }); }); describe('triggerRef', () => { it('maintains ref on the trigger', () => { const triggerRef = jest.fn(); const mountNode = document.createElement('div'); document.body.appendChild(mountNode); const wrapper = mountWithProvider( } trigger={} />); expect(wrapper.find('button').length).toBe(1); expect(wrapper.text()).toEqual(text); }); }); });