wix-style-react
Version:
516 lines (457 loc) • 16.5 kB
JavaScript
import React from 'react';
import { mount } from 'enzyme';
import Sidebar from '../Sidebar';
import { sidebarSkins } from '../constants';
import { SidebarContext } from '../SidebarAPI';
import WixStyleReactProvider from '../../WixStyleReactProvider';
describe('SideBar', () => {
describe.each([true, false])(
'with collapsible inner menu : %p',
sidebarExperimentCollapsible => {
describe('General', () => {
it('should render when no children at all', () => {
const sidebar = mount(
<WixStyleReactProvider
features={{
sidebarExperimentCollapsible,
}}
>
<Sidebar />
</WixStyleReactProvider>,
);
expect(sidebar).toBeDefined();
expect(sidebar.exists()).toBe(true);
});
it('should render when only one simple children', () => {
const sidebar = mount(
<WixStyleReactProvider
features={{
sidebarExperimentCollapsible,
}}
>
<Sidebar>
<div data-hook="simple">123</div>
</Sidebar>
</WixStyleReactProvider>,
);
const simpleEl = sidebar.find(`[data-hook="simple"]`);
expect(simpleEl.text()).toEqual('123');
});
it('should render when more then one simple children', () => {
const sidebar = mount(
<WixStyleReactProvider
features={{
sidebarExperimentCollapsible,
}}
>
<Sidebar>
<div key="123" data-hook="simple1">
123
</div>
<div key="456" data-hook="simple2">
456
</div>
<div key="789" data-hook="simple3">
789
</div>
</Sidebar>
</WixStyleReactProvider>,
);
const el1 = sidebar.find(`[data-hook="simple1"]`);
expect(el1.text()).toEqual('123');
const el2 = sidebar.find(`[data-hook="simple2"]`);
expect(el2.text()).toEqual('456');
const el3 = sidebar.find(`[data-hook="simple3"]`);
expect(el3.text()).toEqual('789');
});
it('should support nullable children', () => {
const sidebar = mount(
<Sidebar>
<div data-hook="simple">123</div>
{null}
</Sidebar>,
);
expect(sidebar).toBeDefined();
expect(sidebar.exists()).toBe(true);
});
it('should render accept children changes ', () => {
const sidebar = mount(
<WixStyleReactProvider
features={{
sidebarExperimentCollapsible,
}}
>
<Sidebar />
</WixStyleReactProvider>,
);
let el1 = sidebar.find(`[data-hook="simple"]`);
expect(el1.exists()).toBe(false);
sidebar.setProps({
children: (
<div key={'simple'} data-hook="simple">
123
</div>
),
});
el1 = sidebar.find(`[data-hook="simple"]`);
expect(el1.text()).toEqual('123');
});
it('should return the right skin', () => {
const skin = sidebarSkins.light;
let currentSkin;
mount(
<WixStyleReactProvider
features={{
sidebarExperimentCollapsible,
}}
>
<Sidebar skin={skin}>
<SidebarContext.Consumer>
{context => (currentSkin = context.getSkin())}
</SidebarContext.Consumer>
</Sidebar>
</WixStyleReactProvider>,
);
expect(currentSkin).toBe(skin);
});
it('should update selected state of selected item', async () => {
let selected;
const sidebar = mount(
<WixStyleReactProvider
features={{
sidebarExperimentCollapsible,
}}
>
<Sidebar selectedKey={'first-item'}>
<SidebarContext.Consumer>
{context => {
selected = context.getSelectedKey();
}}
</SidebarContext.Consumer>
<Sidebar.Item
key={'first-item'}
itemKey={'first-item'}
dataHook="first-item"
>
<div>First</div>
</Sidebar.Item>
<Sidebar.Item
key={'second-item'}
itemKey={'second-item'}
dataHook="second-item"
>
<div>Second</div>
</Sidebar.Item>
</Sidebar>
</WixStyleReactProvider>,
);
expect(selected).toBe('first-item');
const el = sidebar.find('SidebarItem').at(1);
el.simulate('click');
expect(selected).toBe('second-item');
});
it('should correctly update itself when props update', () => {
const newChildren = (
<div key="456" data-hook="simple2">
456
</div>
);
const sidebar = mount(
<Sidebar selectedKey="123">
<div key="123" data-hook="simple1">
123
</div>
</Sidebar>,
{
wrappingComponent: WixStyleReactProvider,
wrappingComponentProps: {
features: { sidebarExperimentCollapsible },
},
},
);
expect(sidebar.find(`[data-hook="simple1"]`).exists()).toBeTruthy();
sidebar.setProps({ selectedKey: '456', children: newChildren });
expect(sidebar.find(`[data-hook="simple2"]`).exists()).toBeTruthy();
expect(sidebar.find(`[data-hook="simple1"]`).exists()).toBeFalsy();
});
});
describe('Inner Menu', () => {
it('should not change second level itemKeys if specified', async () => {
const sidebar = mount(
<Sidebar selectedKey={'inner1'}>
<Sidebar.Item
key={'first-item'}
itemKey={'first-item'}
dataHook="first-item"
>
<div>First</div>
</Sidebar.Item>
<Sidebar.Item
itemKey={'main-item'}
innerMenu={[
<Sidebar.Item
key={'inner1'}
itemKey={'inner-item-1'}
dataHook="inner1"
>
<div>456</div>
</Sidebar.Item>,
<Sidebar.Item
key={'inner2'}
itemKey={'inner-item-2'}
dataHook="inner2"
>
<div>789</div>
</Sidebar.Item>,
]}
></Sidebar.Item>
</Sidebar>,
);
const el = sidebar.find('SidebarItem').at(1);
el.simulate('click');
const el1 = sidebar.find('SidebarItem').at(2);
expect(el1.prop('itemKey')).toEqual('inner-item-1');
const el2 = sidebar.find('SidebarItem').at(3);
expect(el2.prop('itemKey')).toEqual('inner-item-2');
});
it('should add second level itemKeys if not specified', () => {
const sidebar = mount(
<WixStyleReactProvider
features={{
sidebarExperimentCollapsible,
}}
>
<Sidebar selectedKey={'first-item'}>
<Sidebar.Item
key="main"
itemKey={'main-item'}
innerMenu={[
<Sidebar.Item
key={'first-item'}
itemKey={'first-item'}
dataHook="first-item"
>
<div>First</div>
</Sidebar.Item>,
<Sidebar.Item key={'inner1'} dataHook="inner1">
<div>456</div>
</Sidebar.Item>,
<Sidebar.Item key={'inner2'} dataHook="inner2">
<div>789</div>
</Sidebar.Item>,
]}
></Sidebar.Item>
</Sidebar>
</WixStyleReactProvider>,
);
const el1 = sidebar.find('SidebarItem').at(2);
expect(el1.prop('itemKey')).toEqual('main-item1');
const el2 = sidebar.find('SidebarItem').at(3);
expect(el2.prop('itemKey')).toEqual('main-item2');
});
});
},
);
describe('when collapsible menu', () => {
const renderSidebar = selectedKey => (
<WixStyleReactProvider
features={{
sidebarExperimentCollapsible: true,
}}
>
<Sidebar selectedKey={selectedKey}>
<Sidebar.Item
key={'first-item'}
itemKey={'first-item'}
dataHook="first-item"
>
<div>First</div>
</Sidebar.Item>
<Sidebar.Item
itemKey={'first-menu'}
dataHook="first-menu"
innerMenu={[
<Sidebar.Item
key={'inner-item-1'}
itemKey={'inner-item-1'}
dataHook="inner-item-1"
>
<div>Inner1</div>
</Sidebar.Item>,
<Sidebar.Item
key={'inner-item-2'}
itemKey={'inner-item-2'}
dataHook="inner-item-2"
>
<div>Inner2</div>
</Sidebar.Item>,
]}
></Sidebar.Item>
<Sidebar.Item
itemKey={'second-menu'}
dataHook="second-menu"
innerMenu={[
<Sidebar.Item
key={'inner-item-3'}
itemKey={'inner-item-3'}
dataHook="inner-item-3"
>
<div>Inner3</div>
</Sidebar.Item>,
<Sidebar.Item
key={'inner-item-4'}
itemKey={'inner-item-4'}
dataHook="inner-item-4"
>
<div>Inner4</div>
</Sidebar.Item>,
]}
></Sidebar.Item>
</Sidebar>
</WixStyleReactProvider>
);
const clickAt = (sidebar, index) =>
sidebar.find('SidebarItem').at(index).simulate('click');
const isMenuClosed = sidebar => {
const closedMenu = sidebar.find(`[data-hook="closed-inner-menu"]`);
const closedChildrenContainer = sidebar.find(
`[data-hook="closed-inner-menu-children"]`,
);
return (
(closedMenu.getDOMNode().className.includes('closedInnerMenu') ||
closedMenu.getDOMNode().className.includes('closingInnerMenu')) &&
closedChildrenContainer
.getDOMNode()
.className.includes('innerMenuWrapperOutOfPlace')
);
};
const isMenuOpenWithoutDelay = sidebar => {
const openMenu = sidebar.find(`[data-hook="open-inner-menu"]`);
const openChildrenContainer = sidebar.find(
`[data-hook="open-inner-menu-children"]`,
);
return (
openMenu.getDOMNode().className.includes('openingInnerMenu') &&
!openMenu.getDOMNode().className.includes('AfterClosingOther') &&
openChildrenContainer
.getDOMNode()
.className.includes('innerMenuWrapperInToPlace') &&
!openChildrenContainer
.getDOMNode()
.className.includes('AfterClosingOther')
);
};
const isMenuOpenWithDelay = sidebar => {
const openMenu = sidebar.find(`[data-hook="open-inner-menu"]`);
const openChildrenContainer = sidebar.find(
`[data-hook="open-inner-menu-children"]`,
);
return (
openMenu
.getDOMNode()
.className.includes('openingInnerMenuAfterClosingOther') &&
openChildrenContainer
.getDOMNode()
.className.includes('innerMenuWrapperInToPlaceAfterClosingOther')
);
};
const isMenuOpenWithoutAnimation = sidebar => {
const openMenu = sidebar.find(`[data-hook="open-inner-menu"]`);
const openChildrenContainer = sidebar.find(
`[data-hook="open-inner-menu-children"]`,
);
return (
openMenu.getDOMNode().className.includes('openInnerMenu') &&
openChildrenContainer.getDOMNode().className.includes('')
);
};
const getClosedMenuItemsTexts = sidebar =>
sidebar
.find(`[data-hook="closed-inner-menu-children"]`)
.children()
.at(0)
.children()
.map(child => child.text());
const getOpenMenuItemsText = sidebar =>
sidebar
.find(`[data-hook="open-inner-menu-children"]`)
.children()
.at(0)
.children()
.at(0)
.children()
.at(0)
.children()
.map(child => child.text());
describe('when clicking another item with no sub items', () => {
it('shuold collapse menu with animated closing', () => {
const sidebar = mount(renderSidebar('inner-item-1'));
clickAt(sidebar, 0);
expect(isMenuClosed(sidebar)).toBe(true);
});
it('should render correct inner items in closing inner menu', async () => {
const sidebar = mount(renderSidebar('inner-item-1'));
clickAt(sidebar, 0);
expect(getClosedMenuItemsTexts(sidebar)).toEqual(['Inner1', 'Inner2']);
});
});
describe('collapse currently open menu by clicking it', () => {
it('should render correct inner items in closing inner menu', () => {
const sidebar = mount(renderSidebar('inner-item-1'));
clickAt(sidebar, 1);
expect(getClosedMenuItemsTexts(sidebar)).toEqual(['Inner1', 'Inner2']);
});
it('should render inner menu with closing animation', () => {
const sidebar = mount(renderSidebar('inner-item-1'));
clickAt(sidebar, 1);
expect(isMenuClosed(sidebar)).toBe(true);
});
});
describe('expand a menu by clicking it', () => {
it('should render inner menu with opening animation', () => {
const sidebar = mount(renderSidebar('first-item'));
clickAt(sidebar, 1);
expect(isMenuOpenWithoutDelay(sidebar)).toBe(true);
});
it('should render correct inner items in open menu', () => {
const sidebar = mount(renderSidebar('first-item'));
clickAt(sidebar, 1);
expect(getOpenMenuItemsText(sidebar)).toEqual(['Inner1', 'Inner2']);
});
});
describe('click a sibling item inside a currently expaned menu', () => {
it('should not re-animate opening menu', async () => {
const sidebar = mount(renderSidebar('inner-item-1'));
clickAt(sidebar, 3);
expect(isMenuOpenWithoutAnimation(sidebar)).toBe(true);
});
it('should render correct inner items in open menu', async () => {
const sidebar = mount(renderSidebar('inner-item-1'));
clickAt(sidebar, 3);
expect(getOpenMenuItemsText(sidebar)).toEqual(['Inner1', 'Inner2']);
});
});
describe('collapse an expanded menu when another menu is expanded', () => {
it('should animate closing the currently open menu', () => {
const sidebar = mount(renderSidebar('inner-item-1'));
clickAt(sidebar, 4);
expect(isMenuClosed(sidebar)).toBe(true);
});
it('should animate opening the clicked menu with delay', () => {
const sidebar = mount(renderSidebar('inner-item-1'));
clickAt(sidebar, 4);
expect(isMenuOpenWithDelay(sidebar)).toBe(true);
});
it('should render correct inner items in closed menu', () => {
const sidebar = mount(renderSidebar('inner-item-1'));
clickAt(sidebar, 4);
expect(getClosedMenuItemsTexts(sidebar)).toEqual(['Inner1', 'Inner2']);
});
it('should render correct inner items in open menu', () => {
const sidebar = mount(renderSidebar('inner-item-1'));
clickAt(sidebar, 4);
expect(getOpenMenuItemsText(sidebar)).toEqual(['Inner3', 'Inner4']);
});
});
});
});