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/pipelines/graph/graph_component_wrapper_spec.js')
-rw-r--r--spec/frontend/pipelines/graph/graph_component_wrapper_spec.js172
1 files changed, 164 insertions, 8 deletions
diff --git a/spec/frontend/pipelines/graph/graph_component_wrapper_spec.js b/spec/frontend/pipelines/graph/graph_component_wrapper_spec.js
index 44d8e467f51..8c469966be4 100644
--- a/spec/frontend/pipelines/graph/graph_component_wrapper_spec.js
+++ b/spec/frontend/pipelines/graph/graph_component_wrapper_spec.js
@@ -1,11 +1,21 @@
import { GlAlert, GlLoadingIcon } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
+import { mount, shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
+import { useLocalStorageSpy } from 'helpers/local_storage_helper';
import createMockApollo from 'helpers/mock_apollo_helper';
import getPipelineDetails from 'shared_queries/pipelines/get_pipeline_details.query.graphql';
+import {
+ IID_FAILURE,
+ LAYER_VIEW,
+ STAGE_VIEW,
+ VIEW_TYPE_KEY,
+} from '~/pipelines/components/graph/constants';
import PipelineGraph from '~/pipelines/components/graph/graph_component.vue';
import PipelineGraphWrapper from '~/pipelines/components/graph/graph_component_wrapper.vue';
+import GraphViewSelector from '~/pipelines/components/graph/graph_view_selector.vue';
+import StageColumnComponent from '~/pipelines/components/graph/stage_column_component.vue';
+import * as parsingUtils from '~/pipelines/components/parsing_utils';
import { mockPipelineResponse } from './mock_data';
const defaultProvide = {
@@ -17,20 +27,28 @@ const defaultProvide = {
describe('Pipeline graph wrapper', () => {
Vue.use(VueApollo);
+ useLocalStorageSpy();
let wrapper;
const getAlert = () => wrapper.find(GlAlert);
const getLoadingIcon = () => wrapper.find(GlLoadingIcon);
const getGraph = () => wrapper.find(PipelineGraph);
+ const getStageColumnTitle = () => wrapper.find('[data-testid="stage-column-title"]');
+ const getAllStageColumnGroupsInColumn = () =>
+ wrapper.find(StageColumnComponent).findAll('[data-testid="stage-column-group"]');
+ const getViewSelector = () => wrapper.find(GraphViewSelector);
const createComponent = ({
apolloProvider,
data = {},
- provide = defaultProvide,
+ provide = {},
mountFn = shallowMount,
} = {}) => {
wrapper = mountFn(PipelineGraphWrapper, {
- provide,
+ provide: {
+ ...defaultProvide,
+ ...provide,
+ },
apolloProvider,
data() {
return {
@@ -40,13 +58,15 @@ describe('Pipeline graph wrapper', () => {
});
};
- const createComponentWithApollo = (
+ const createComponentWithApollo = ({
getPipelineDetailsHandler = jest.fn().mockResolvedValue(mockPipelineResponse),
- ) => {
+ mountFn = shallowMount,
+ provide = {},
+ } = {}) => {
const requestHandlers = [[getPipelineDetails, getPipelineDetailsHandler]];
const apolloProvider = createMockApollo(requestHandlers);
- createComponent({ apolloProvider });
+ createComponent({ apolloProvider, provide, mountFn });
};
afterEach(() => {
@@ -100,7 +120,9 @@ describe('Pipeline graph wrapper', () => {
describe('when there is an error', () => {
beforeEach(async () => {
- createComponentWithApollo(jest.fn().mockRejectedValue(new Error('GraphQL error')));
+ createComponentWithApollo({
+ getPipelineDetailsHandler: jest.fn().mockRejectedValue(new Error('GraphQL error')),
+ });
jest.runOnlyPendingTimers();
await wrapper.vm.$nextTick();
});
@@ -118,6 +140,31 @@ describe('Pipeline graph wrapper', () => {
});
});
+ describe('when there is no pipeline iid available', () => {
+ beforeEach(async () => {
+ createComponentWithApollo({
+ provide: {
+ pipelineIid: '',
+ },
+ });
+ jest.runOnlyPendingTimers();
+ await wrapper.vm.$nextTick();
+ });
+
+ it('does not display the loading icon', () => {
+ expect(getLoadingIcon().exists()).toBe(false);
+ });
+
+ it('displays the no iid alert', () => {
+ expect(getAlert().exists()).toBe(true);
+ expect(getAlert().text()).toBe(wrapper.vm.$options.errorTexts[IID_FAILURE]);
+ });
+
+ it('does not display the graph', () => {
+ expect(getGraph().exists()).toBe(false);
+ });
+ });
+
describe('when refresh action is emitted', () => {
beforeEach(async () => {
createComponentWithApollo();
@@ -154,7 +201,7 @@ describe('Pipeline graph wrapper', () => {
.mockResolvedValueOnce(mockPipelineResponse)
.mockResolvedValueOnce(errorData);
- createComponentWithApollo(failSucceedFail);
+ createComponentWithApollo({ getPipelineDetailsHandler: failSucceedFail });
await wrapper.vm.$nextTick();
});
@@ -174,4 +221,113 @@ describe('Pipeline graph wrapper', () => {
expect(getGraph().exists()).toBe(true);
});
});
+
+ describe('view dropdown', () => {
+ describe('when pipelineGraphLayersView feature flag is off', () => {
+ beforeEach(async () => {
+ createComponentWithApollo();
+ jest.runOnlyPendingTimers();
+ await wrapper.vm.$nextTick();
+ });
+
+ it('does not appear', () => {
+ expect(getViewSelector().exists()).toBe(false);
+ });
+ });
+
+ describe('when pipelineGraphLayersView feature flag is on', () => {
+ let layersFn;
+ beforeEach(async () => {
+ layersFn = jest.spyOn(parsingUtils, 'listByLayers');
+ createComponentWithApollo({
+ provide: {
+ glFeatures: {
+ pipelineGraphLayersView: true,
+ },
+ },
+ mountFn: mount,
+ });
+
+ jest.runOnlyPendingTimers();
+ await wrapper.vm.$nextTick();
+ });
+
+ it('appears when pipeline uses needs', () => {
+ expect(getViewSelector().exists()).toBe(true);
+ });
+
+ it('switches between views', async () => {
+ const groupsInFirstColumn =
+ mockPipelineResponse.data.project.pipeline.stages.nodes[0].groups.nodes.length;
+ expect(getAllStageColumnGroupsInColumn()).toHaveLength(groupsInFirstColumn);
+ expect(getStageColumnTitle().text()).toBe('Build');
+ await getViewSelector().vm.$emit('updateViewType', LAYER_VIEW);
+ expect(getAllStageColumnGroupsInColumn()).toHaveLength(groupsInFirstColumn + 1);
+ expect(getStageColumnTitle().text()).toBe('');
+ });
+
+ it('saves the view type to local storage', async () => {
+ await getViewSelector().vm.$emit('updateViewType', LAYER_VIEW);
+ expect(localStorage.setItem.mock.calls).toEqual([[VIEW_TYPE_KEY, LAYER_VIEW]]);
+ });
+
+ it('calls listByLayers only once no matter how many times view is switched', async () => {
+ expect(layersFn).not.toHaveBeenCalled();
+ await getViewSelector().vm.$emit('updateViewType', LAYER_VIEW);
+ expect(layersFn).toHaveBeenCalledTimes(1);
+ await getViewSelector().vm.$emit('updateViewType', STAGE_VIEW);
+ await getViewSelector().vm.$emit('updateViewType', LAYER_VIEW);
+ await getViewSelector().vm.$emit('updateViewType', STAGE_VIEW);
+ expect(layersFn).toHaveBeenCalledTimes(1);
+ });
+ });
+
+ describe('when feature flag is on and local storage is set', () => {
+ beforeEach(async () => {
+ localStorage.setItem(VIEW_TYPE_KEY, LAYER_VIEW);
+
+ createComponentWithApollo({
+ provide: {
+ glFeatures: {
+ pipelineGraphLayersView: true,
+ },
+ },
+ mountFn: mount,
+ });
+
+ jest.runOnlyPendingTimers();
+ await wrapper.vm.$nextTick();
+ });
+
+ it('reads the view type from localStorage when available', () => {
+ expect(wrapper.find('[data-testid="pipeline-view-selector"] code').text()).toContain(
+ 'needs:',
+ );
+ });
+ });
+
+ describe('when feature flag is on but pipeline does not use needs', () => {
+ beforeEach(async () => {
+ const nonNeedsResponse = { ...mockPipelineResponse };
+ nonNeedsResponse.data.project.pipeline.usesNeeds = false;
+
+ createComponentWithApollo({
+ provide: {
+ glFeatures: {
+ pipelineGraphLayersView: true,
+ },
+ },
+ mountFn: mount,
+ getPipelineDetailsHandler: jest.fn().mockResolvedValue(nonNeedsResponse),
+ });
+
+ jest.runOnlyPendingTimers();
+ await wrapper.vm.$nextTick();
+ });
+
+ it('does not appear when pipeline does not use needs', () => {
+ expect(getViewSelector().exists()).toBe(false);
+ });
+ });
+ });
});