149 lines
4.5 KiB
JavaScript
149 lines
4.5 KiB
JavaScript
import { shallowMount, mount } from '@vue/test-utils';
|
|
import { nextTick } from 'vue';
|
|
import TopNavDropdownMenu from '~/nav/components/top_nav_dropdown_menu.vue';
|
|
import TopNavMenuItem from '~/nav/components/top_nav_menu_item.vue';
|
|
import TopNavMenuSections from '~/nav/components/top_nav_menu_sections.vue';
|
|
import KeepAliveSlots from '~/vue_shared/components/keep_alive_slots.vue';
|
|
import { TEST_NAV_DATA } from '../mock_data';
|
|
|
|
describe('~/nav/components/top_nav_dropdown_menu.vue', () => {
|
|
let wrapper;
|
|
|
|
const createComponent = (props = {}, mountFn = shallowMount) => {
|
|
wrapper = mountFn(TopNavDropdownMenu, {
|
|
propsData: {
|
|
primary: TEST_NAV_DATA.primary,
|
|
secondary: TEST_NAV_DATA.secondary,
|
|
views: TEST_NAV_DATA.views,
|
|
...props,
|
|
},
|
|
stubs: {
|
|
// Stub the keep-alive-slots so we don't render frequent items which uses a store
|
|
KeepAliveSlots: true,
|
|
},
|
|
});
|
|
};
|
|
|
|
const findMenuItems = () => wrapper.findAllComponents(TopNavMenuItem);
|
|
const findMenuSections = () => wrapper.findComponent(TopNavMenuSections);
|
|
const findMenuSidebar = () => wrapper.find('[data-testid="menu-sidebar"]');
|
|
const findMenuSubview = () => wrapper.findComponent(KeepAliveSlots);
|
|
const hasFullWidthMenuSidebar = () => findMenuSidebar().classes('gl-w-full');
|
|
|
|
const withActiveIndex = (menuItems, activeIndex) =>
|
|
menuItems.map((x, idx) => ({
|
|
...x,
|
|
active: idx === activeIndex,
|
|
}));
|
|
|
|
afterEach(() => {
|
|
wrapper.destroy();
|
|
});
|
|
|
|
beforeEach(() => {
|
|
jest.spyOn(console, 'error').mockImplementation();
|
|
});
|
|
|
|
describe('default', () => {
|
|
beforeEach(() => {
|
|
createComponent();
|
|
});
|
|
|
|
it('renders menu sections', () => {
|
|
expect(findMenuSections().props()).toEqual({
|
|
sections: [
|
|
{ id: 'primary', menuItems: TEST_NAV_DATA.primary },
|
|
{ id: 'secondary', menuItems: TEST_NAV_DATA.secondary },
|
|
],
|
|
withTopBorder: false,
|
|
});
|
|
});
|
|
|
|
it('has full width menu sidebar', () => {
|
|
expect(hasFullWidthMenuSidebar()).toBe(true);
|
|
});
|
|
|
|
it('renders hidden subview with no slot key', () => {
|
|
const subview = findMenuSubview();
|
|
|
|
expect(subview.isVisible()).toBe(false);
|
|
expect(subview.props()).toEqual({ slotKey: '' });
|
|
});
|
|
});
|
|
|
|
describe('with pre-initialized active view', () => {
|
|
beforeEach(() => {
|
|
// We opt for a small integration test, to make sure the event is handled correctly
|
|
// as it would in prod.
|
|
createComponent(
|
|
{
|
|
primary: withActiveIndex(TEST_NAV_DATA.primary, 1),
|
|
},
|
|
mount,
|
|
);
|
|
});
|
|
|
|
it('renders menu sections', () => {
|
|
expect(findMenuSections().props('sections')).toStrictEqual([
|
|
{ id: 'primary', menuItems: withActiveIndex(TEST_NAV_DATA.primary, 1) },
|
|
{ id: 'secondary', menuItems: TEST_NAV_DATA.secondary },
|
|
]);
|
|
});
|
|
|
|
it('does not have full width menu sidebar', () => {
|
|
expect(hasFullWidthMenuSidebar()).toBe(false);
|
|
});
|
|
|
|
it('renders visible subview with slot key', () => {
|
|
const subview = findMenuSubview();
|
|
|
|
expect(subview.isVisible()).toBe(true);
|
|
expect(subview.props('slotKey')).toBe(TEST_NAV_DATA.primary[1].view);
|
|
});
|
|
|
|
it('does not change view if non-view menu item is clicked', async () => {
|
|
const secondaryLink = findMenuItems().at(TEST_NAV_DATA.primary.length);
|
|
|
|
// Ensure this doesn't have a view
|
|
expect(secondaryLink.props('menuItem').view).toBeUndefined();
|
|
|
|
secondaryLink.vm.$emit('click');
|
|
|
|
await nextTick();
|
|
|
|
expect(findMenuSubview().props('slotKey')).toBe(TEST_NAV_DATA.primary[1].view);
|
|
});
|
|
|
|
describe('when menu item is clicked', () => {
|
|
let primaryLink;
|
|
|
|
beforeEach(async () => {
|
|
primaryLink = findMenuItems().at(0);
|
|
primaryLink.vm.$emit('click');
|
|
await nextTick();
|
|
});
|
|
|
|
it('clicked on link with view', () => {
|
|
expect(primaryLink.props('menuItem').view).toBe(TEST_NAV_DATA.views.projects.namespace);
|
|
});
|
|
|
|
it('changes active view', () => {
|
|
expect(findMenuSubview().props('slotKey')).toBe(TEST_NAV_DATA.primary[0].view);
|
|
});
|
|
|
|
it('changes active status on menu item', () => {
|
|
expect(findMenuSections().props('sections')).toStrictEqual([
|
|
{
|
|
id: 'primary',
|
|
menuItems: withActiveIndex(TEST_NAV_DATA.primary, 0),
|
|
},
|
|
{
|
|
id: 'secondary',
|
|
menuItems: withActiveIndex(TEST_NAV_DATA.secondary, -1),
|
|
},
|
|
]);
|
|
});
|
|
});
|
|
});
|
|
});
|