Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/analytics/cycle_analytics/path_navigation_spec.js')
-rw-r--r--spec/frontend/analytics/cycle_analytics/path_navigation_spec.js150
1 files changed, 150 insertions, 0 deletions
diff --git a/spec/frontend/analytics/cycle_analytics/path_navigation_spec.js b/spec/frontend/analytics/cycle_analytics/path_navigation_spec.js
new file mode 100644
index 00000000000..107e62035c3
--- /dev/null
+++ b/spec/frontend/analytics/cycle_analytics/path_navigation_spec.js
@@ -0,0 +1,150 @@
+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 '~/analytics/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.findComponent(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.findComponent(GlPath).exists()).toBe(true);
+ });
+
+ it('hides the gl-skeleton-loading component', () => {
+ expect(wrapper.findComponent(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.toString());
+ });
+ });
+
+ 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.findComponent(GlPath).exists()).toBe(false);
+ });
+
+ it('displays the gl-skeleton-loading component', () => {
+ expect(wrapper.findComponent(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 },
+ });
+ });
+ });
+});