2022-07-23 23:45:48 +05:30
|
|
|
import { GlPath, GlSkeletonLoader } from '@gitlab/ui';
|
2021-09-04 01:27:46 +05:30
|
|
|
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', () => {
|
2022-07-23 23:45:48 +05:30
|
|
|
expect(wrapper.find(GlSkeletonLoader).exists()).toBe(false);
|
2021-09-04 01:27:46 +05:30
|
|
|
});
|
|
|
|
|
|
|
|
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);
|
2022-08-13 15:12:31 +05:30
|
|
|
expect(result[index]).toContain(metric.toString());
|
2021-09-04 01:27:46 +05:30
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
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', () => {
|
2022-07-23 23:45:48 +05:30
|
|
|
expect(wrapper.find(GlSkeletonLoader).exists()).toBe(true);
|
2021-09-04 01:27:46 +05:30
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
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 },
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|