gitlab-org--gitlab-foss/spec/frontend/cycle_analytics/path_navigation_spec.js

148 lines
4.4 KiB
JavaScript

import { GlPath, GlSkeletonLoader } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import Component from '~/cycle_analytics/components/path_navigation.vue';
import { transformedProjectStagePathData, selectedStage } from './mock_data';
describe('Project PathNavigation', () => {
let wrapper = null;
let trackingSpy = null;
const createComponent = (props) => {
return extendedWrapper(
mount(Component, {
propsData: {
stages: transformedProjectStagePathData,
selectedStage,
loading: false,
...props,
},
}),
);
};
const findPathNavigation = () => {
return wrapper.findByTestId('gl-path-nav');
};
const findPathNavigationItems = () => {
return findPathNavigation().findAll('li');
};
const findPathNavigationTitles = () => {
return findPathNavigation()
.findAll('li button')
.wrappers.map((w) => w.html());
};
const clickItemAt = (index) => {
findPathNavigationItems().at(index).find('button').trigger('click');
};
const pathItemContent = () => findPathNavigationItems().wrappers.map(extendedWrapper);
const firstPopover = () => wrapper.findAllByTestId('stage-item-popover').at(0);
beforeEach(() => {
wrapper = createComponent();
trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
});
afterEach(() => {
unmockTracking();
wrapper.destroy();
wrapper = null;
});
describe('displays correctly', () => {
it('has the correct props', () => {
expect(wrapper.find(GlPath).props('items')).toMatchObject(transformedProjectStagePathData);
});
it('contains all the expected stages', () => {
const stageContent = findPathNavigationTitles();
transformedProjectStagePathData.forEach((stage, index) => {
expect(stageContent[index]).toContain(stage.title);
});
});
describe('loading', () => {
describe('is false', () => {
it('displays the gl-path component', () => {
expect(wrapper.find(GlPath).exists()).toBe(true);
});
it('hides the gl-skeleton-loading component', () => {
expect(wrapper.find(GlSkeletonLoader).exists()).toBe(false);
});
it('renders each stage', () => {
const result = findPathNavigationTitles();
expect(result.length).toBe(transformedProjectStagePathData.length);
});
it('renders each stage with its median', () => {
const result = findPathNavigationTitles();
transformedProjectStagePathData.forEach(({ title, metric }, index) => {
expect(result[index]).toContain(title);
expect(result[index]).toContain(metric);
});
});
describe('popovers', () => {
beforeEach(() => {
wrapper = createComponent({ stages: transformedProjectStagePathData });
});
it('renders popovers for all stages', () => {
pathItemContent().forEach((stage) => {
expect(stage.findByTestId('stage-item-popover').exists()).toBe(true);
});
});
it('shows the median stage time for the first stage item', () => {
expect(firstPopover().text()).toContain('Stage time (median)');
});
});
});
describe('is true', () => {
beforeEach(() => {
wrapper = createComponent({ loading: true });
});
it('hides the gl-path component', () => {
expect(wrapper.find(GlPath).exists()).toBe(false);
});
it('displays the gl-skeleton-loading component', () => {
expect(wrapper.find(GlSkeletonLoader).exists()).toBe(true);
});
});
});
});
describe('event handling', () => {
it('emits the selected event', () => {
expect(wrapper.emitted('selected')).toBeUndefined();
clickItemAt(0);
clickItemAt(1);
clickItemAt(2);
expect(wrapper.emitted().selected).toEqual([
[transformedProjectStagePathData[0]],
[transformedProjectStagePathData[1]],
[transformedProjectStagePathData[2]],
]);
});
it('sends tracking information', () => {
clickItemAt(0);
expect(trackingSpy).toHaveBeenCalledWith(undefined, 'click_path_navigation', {
extra: { stage_id: selectedStage.slug },
});
});
});
});