diff options
Diffstat (limited to 'spec/frontend/cycle_analytics/path_navigation_spec.js')
-rw-r--r-- | spec/frontend/cycle_analytics/path_navigation_spec.js | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/spec/frontend/cycle_analytics/path_navigation_spec.js b/spec/frontend/cycle_analytics/path_navigation_spec.js new file mode 100644 index 00000000000..c6d72d3b571 --- /dev/null +++ b/spec/frontend/cycle_analytics/path_navigation_spec.js @@ -0,0 +1,148 @@ +import { GlPath, GlDeprecatedSkeletonLoading as GlSkeletonLoading } 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(GlSkeletonLoading).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(GlSkeletonLoading).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 }, + }); + }); + }); +}); |