debian-mirror-gitlab/spec/javascripts/fly_out_nav_browser_spec.js

334 lines
9.3 KiB
JavaScript
Raw Normal View History

2020-07-28 23:09:34 +05:30
// this file can't be migrated to jest because it relies on the browser to perform integration tests:
// (specifically getClientBoundingRect and mouse movements)
// see: https://gitlab.com/groups/gitlab-org/-/epics/895#what-if-theres-a-karma-spec-which-is-simply-unmovable-to-jest-ie-it-is-dependent-on-a-running-browser-environment
2020-03-09 13:42:32 +05:30
import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
2017-09-10 17:25:29 +05:30
import {
calculateTop,
showSubLevelItems,
canShowSubItems,
canShowActiveSubItems,
mouseEnterTopItems,
mouseLeaveTopItem,
getOpenMenu,
setOpenMenu,
mousePos,
getHideSubItemsInterval,
documentMouseMove,
getHeaderHeight,
setSidebar,
subItemsMouseLeave,
} from '~/fly_out_nav';
2019-09-04 21:01:54 +05:30
import { SIDEBAR_COLLAPSED_CLASS } from '~/contextual_sidebar';
2017-09-10 17:25:29 +05:30
describe('Fly out sidebar navigation', () => {
let el;
let breakpointSize = 'lg';
beforeEach(() => {
el = document.createElement('div');
el.style.position = 'relative';
document.body.appendChild(el);
2020-03-09 13:42:32 +05:30
spyOn(GlBreakpointInstance, 'getBreakpointSize').and.callFake(() => breakpointSize);
2017-09-10 17:25:29 +05:30
setOpenMenu(null);
});
afterEach(() => {
document.body.innerHTML = '';
breakpointSize = 'lg';
mousePos.length = 0;
2018-03-17 18:26:18 +05:30
setSidebar(null);
2017-09-10 17:25:29 +05:30
});
describe('calculateTop', () => {
it('returns boundingRect top', () => {
const boundingRect = {
top: 100,
height: 100,
};
2018-12-13 13:39:08 +05:30
expect(calculateTop(boundingRect, 100)).toBe(100);
2017-09-10 17:25:29 +05:30
});
it('returns boundingRect - bottomOverflow', () => {
const boundingRect = {
top: window.innerHeight - 50,
height: 100,
};
2018-12-13 13:39:08 +05:30
expect(calculateTop(boundingRect, 100)).toBe(window.innerHeight - 50);
2017-09-10 17:25:29 +05:30
});
});
describe('getHideSubItemsInterval', () => {
beforeEach(() => {
2018-12-13 13:39:08 +05:30
el.innerHTML =
'<div class="sidebar-sub-level-items" style="position: fixed; top: 0; left: 100px; height: 150px;"></div>';
2017-09-10 17:25:29 +05:30
});
it('returns 0 if currentOpenMenu is nil', () => {
2018-12-13 13:39:08 +05:30
expect(getHideSubItemsInterval()).toBe(0);
2017-09-10 17:25:29 +05:30
});
2018-03-17 18:26:18 +05:30
it('returns 0 if mousePos is empty', () => {
2018-12-13 13:39:08 +05:30
expect(getHideSubItemsInterval()).toBe(0);
2018-03-17 18:26:18 +05:30
});
2017-09-10 17:25:29 +05:30
it('returns 0 when mouse above sub-items', () => {
showSubLevelItems(el);
documentMouseMove({
clientX: el.getBoundingClientRect().left,
clientY: el.getBoundingClientRect().top,
});
documentMouseMove({
clientX: el.getBoundingClientRect().left,
clientY: el.getBoundingClientRect().top - 50,
});
2018-12-13 13:39:08 +05:30
expect(getHideSubItemsInterval()).toBe(0);
2017-09-10 17:25:29 +05:30
});
it('returns 0 when mouse is below sub-items', () => {
const subItems = el.querySelector('.sidebar-sub-level-items');
showSubLevelItems(el);
documentMouseMove({
clientX: el.getBoundingClientRect().left,
clientY: el.getBoundingClientRect().top,
});
documentMouseMove({
clientX: el.getBoundingClientRect().left,
2018-12-13 13:39:08 +05:30
clientY: el.getBoundingClientRect().top - subItems.getBoundingClientRect().height + 50,
2017-09-10 17:25:29 +05:30
});
2018-12-13 13:39:08 +05:30
expect(getHideSubItemsInterval()).toBe(0);
2017-09-10 17:25:29 +05:30
});
it('returns 300 when mouse is moved towards sub-items', () => {
documentMouseMove({
clientX: el.getBoundingClientRect().left,
clientY: el.getBoundingClientRect().top,
});
showSubLevelItems(el);
documentMouseMove({
clientX: el.getBoundingClientRect().left + 20,
clientY: el.getBoundingClientRect().top + 10,
});
2018-12-13 13:39:08 +05:30
expect(getHideSubItemsInterval()).toBe(300);
2017-09-10 17:25:29 +05:30
});
});
describe('mouseLeaveTopItem', () => {
beforeEach(() => {
spyOn(el.classList, 'remove');
});
it('removes is-over class if currentOpenMenu is null', () => {
mouseLeaveTopItem(el);
2018-12-13 13:39:08 +05:30
expect(el.classList.remove).toHaveBeenCalledWith('is-over');
2017-09-10 17:25:29 +05:30
});
it('removes is-over class if currentOpenMenu is null & there are sub-items', () => {
el.innerHTML = '<div class="sidebar-sub-level-items" style="position: absolute;"></div>';
mouseLeaveTopItem(el);
2018-12-13 13:39:08 +05:30
expect(el.classList.remove).toHaveBeenCalledWith('is-over');
2017-09-10 17:25:29 +05:30
});
it('does not remove is-over class if currentOpenMenu is the passed in sub-items', () => {
el.innerHTML = '<div class="sidebar-sub-level-items" style="position: absolute;"></div>';
setOpenMenu(el.querySelector('.sidebar-sub-level-items'));
mouseLeaveTopItem(el);
2018-12-13 13:39:08 +05:30
expect(el.classList.remove).not.toHaveBeenCalled();
2017-09-10 17:25:29 +05:30
});
});
describe('mouseEnterTopItems', () => {
beforeEach(() => {
2018-12-13 13:39:08 +05:30
el.innerHTML =
'<div class="sidebar-sub-level-items" style="position: absolute; top: 0; left: 100px; height: 200px;"></div>';
2017-09-10 17:25:29 +05:30
});
2018-12-13 13:39:08 +05:30
it('shows sub-items after 0ms if no menu is open', done => {
2017-09-10 17:25:29 +05:30
mouseEnterTopItems(el);
2018-12-13 13:39:08 +05:30
expect(getHideSubItemsInterval()).toBe(0);
2017-09-10 17:25:29 +05:30
2018-03-17 18:26:18 +05:30
setTimeout(() => {
2018-12-13 13:39:08 +05:30
expect(el.querySelector('.sidebar-sub-level-items').style.display).toBe('block');
2017-09-10 17:25:29 +05:30
2018-03-17 18:26:18 +05:30
done();
});
2017-09-10 17:25:29 +05:30
});
2018-12-13 13:39:08 +05:30
it('shows sub-items after 300ms if a menu is currently open', done => {
2017-09-10 17:25:29 +05:30
documentMouseMove({
clientX: el.getBoundingClientRect().left,
clientY: el.getBoundingClientRect().top,
});
setOpenMenu(el.querySelector('.sidebar-sub-level-items'));
documentMouseMove({
clientX: el.getBoundingClientRect().left + 20,
clientY: el.getBoundingClientRect().top + 10,
});
2018-03-17 18:26:18 +05:30
mouseEnterTopItems(el, 0);
2017-09-10 17:25:29 +05:30
2018-12-13 13:39:08 +05:30
expect(getHideSubItemsInterval()).toBe(300);
2017-09-10 17:25:29 +05:30
2018-03-17 18:26:18 +05:30
setTimeout(() => {
2018-12-13 13:39:08 +05:30
expect(el.querySelector('.sidebar-sub-level-items').style.display).toBe('block');
2017-09-10 17:25:29 +05:30
2018-03-17 18:26:18 +05:30
done();
});
2017-09-10 17:25:29 +05:30
});
});
describe('showSubLevelItems', () => {
beforeEach(() => {
el.innerHTML = '<div class="sidebar-sub-level-items" style="position: absolute;"></div>';
});
it('adds is-over class to el', () => {
spyOn(el.classList, 'add');
showSubLevelItems(el);
2018-12-13 13:39:08 +05:30
expect(el.classList.add).toHaveBeenCalledWith('is-over');
2017-09-10 17:25:29 +05:30
});
it('does not show sub-items on mobile', () => {
breakpointSize = 'xs';
showSubLevelItems(el);
2018-12-13 13:39:08 +05:30
expect(el.querySelector('.sidebar-sub-level-items').style.display).not.toBe('block');
2017-09-10 17:25:29 +05:30
});
it('shows sub-items', () => {
showSubLevelItems(el);
2018-12-13 13:39:08 +05:30
expect(el.querySelector('.sidebar-sub-level-items').style.display).toBe('block');
2017-09-10 17:25:29 +05:30
});
2018-03-17 18:26:18 +05:30
it('shows collapsed only sub-items if icon only sidebar', () => {
const subItems = el.querySelector('.sidebar-sub-level-items');
const sidebar = document.createElement('div');
2019-09-04 21:01:54 +05:30
sidebar.classList.add(SIDEBAR_COLLAPSED_CLASS);
2018-03-17 18:26:18 +05:30
subItems.classList.add('is-fly-out-only');
setSidebar(sidebar);
showSubLevelItems(el);
2018-12-13 13:39:08 +05:30
expect(el.querySelector('.sidebar-sub-level-items').style.display).toBe('block');
2018-03-17 18:26:18 +05:30
});
it('does not show collapsed only sub-items if icon only sidebar', () => {
const subItems = el.querySelector('.sidebar-sub-level-items');
subItems.classList.add('is-fly-out-only');
showSubLevelItems(el);
2018-12-13 13:39:08 +05:30
expect(subItems.style.display).not.toBe('block');
2018-03-17 18:26:18 +05:30
});
2017-09-10 17:25:29 +05:30
it('sets transform of sub-items', () => {
2018-03-17 18:26:18 +05:30
const sidebar = document.createElement('div');
2017-09-10 17:25:29 +05:30
const subItems = el.querySelector('.sidebar-sub-level-items');
2018-03-17 18:26:18 +05:30
sidebar.style.width = '200px';
document.body.appendChild(sidebar);
setSidebar(sidebar);
2017-09-10 17:25:29 +05:30
showSubLevelItems(el);
2018-12-13 13:39:08 +05:30
expect(subItems.style.transform).toBe(
`translate3d(200px, ${Math.floor(el.getBoundingClientRect().top) -
getHeaderHeight()}px, 0px)`,
);
2017-09-10 17:25:29 +05:30
});
it('sets is-above when element is above', () => {
const subItems = el.querySelector('.sidebar-sub-level-items');
subItems.style.height = `${window.innerHeight + el.offsetHeight}px`;
el.style.top = `${window.innerHeight - el.offsetHeight}px`;
spyOn(subItems.classList, 'add');
showSubLevelItems(el);
2018-12-13 13:39:08 +05:30
expect(subItems.classList.add).toHaveBeenCalledWith('is-above');
2017-09-10 17:25:29 +05:30
});
});
describe('canShowSubItems', () => {
it('returns true if on desktop size', () => {
2018-12-13 13:39:08 +05:30
expect(canShowSubItems()).toBeTruthy();
2017-09-10 17:25:29 +05:30
});
it('returns false if on mobile size', () => {
breakpointSize = 'xs';
2018-12-13 13:39:08 +05:30
expect(canShowSubItems()).toBeFalsy();
2017-09-10 17:25:29 +05:30
});
});
describe('canShowActiveSubItems', () => {
it('returns true by default', () => {
2018-12-13 13:39:08 +05:30
expect(canShowActiveSubItems(el)).toBeTruthy();
2017-09-10 17:25:29 +05:30
});
it('returns false when active & expanded sidebar', () => {
const sidebar = document.createElement('div');
el.classList.add('active');
setSidebar(sidebar);
2018-12-13 13:39:08 +05:30
expect(canShowActiveSubItems(el)).toBeFalsy();
2017-09-10 17:25:29 +05:30
});
it('returns true when active & collapsed sidebar', () => {
const sidebar = document.createElement('div');
2019-09-04 21:01:54 +05:30
sidebar.classList.add(SIDEBAR_COLLAPSED_CLASS);
2017-09-10 17:25:29 +05:30
el.classList.add('active');
setSidebar(sidebar);
2018-12-13 13:39:08 +05:30
expect(canShowActiveSubItems(el)).toBeTruthy();
2017-09-10 17:25:29 +05:30
});
});
describe('subItemsMouseLeave', () => {
beforeEach(() => {
el.innerHTML = '<div class="sidebar-sub-level-items" style="position: absolute;"></div>';
setOpenMenu(el.querySelector('.sidebar-sub-level-items'));
});
it('hides subMenu if element is not hovered', () => {
subItemsMouseLeave(el);
2018-12-13 13:39:08 +05:30
expect(getOpenMenu()).toBeNull();
2017-09-10 17:25:29 +05:30
});
it('does not hide subMenu if element is hovered', () => {
el.classList.add('is-over');
subItemsMouseLeave(el);
2018-12-13 13:39:08 +05:30
expect(getOpenMenu()).not.toBeNull();
2017-09-10 17:25:29 +05:30
});
});
});