2020-06-23 00:09:42 +05:30
|
|
|
import { mount, shallowMount } from '@vue/test-utils';
|
|
|
|
import MockAdapter from 'axios-mock-adapter';
|
|
|
|
import axios from '~/lib/utils/axios_utils';
|
|
|
|
import waitForPromises from 'helpers/wait_for_promises';
|
2020-07-28 23:09:34 +05:30
|
|
|
import { GlAlert, GlEmptyState } from '@gitlab/ui';
|
2020-06-23 00:09:42 +05:30
|
|
|
import Dag from '~/pipelines/components/dag/dag.vue';
|
|
|
|
import DagGraph from '~/pipelines/components/dag/dag_graph.vue';
|
2020-07-28 23:09:34 +05:30
|
|
|
import DagAnnotations from '~/pipelines/components/dag/dag_annotations.vue';
|
2020-06-23 00:09:42 +05:30
|
|
|
|
|
|
|
import {
|
2020-07-28 23:09:34 +05:30
|
|
|
ADD_NOTE,
|
|
|
|
REMOVE_NOTE,
|
|
|
|
REPLACE_NOTES,
|
2020-06-23 00:09:42 +05:30
|
|
|
DEFAULT,
|
|
|
|
PARSE_FAILURE,
|
|
|
|
LOAD_FAILURE,
|
|
|
|
UNSUPPORTED_DATA,
|
|
|
|
} from '~/pipelines/components/dag//constants';
|
2020-07-28 23:09:34 +05:30
|
|
|
import {
|
|
|
|
mockBaseData,
|
|
|
|
tooSmallGraph,
|
|
|
|
unparseableGraph,
|
|
|
|
graphWithoutDependencies,
|
|
|
|
singleNote,
|
|
|
|
multiNote,
|
|
|
|
} from './mock_data';
|
2020-06-23 00:09:42 +05:30
|
|
|
|
|
|
|
describe('Pipeline DAG graph wrapper', () => {
|
|
|
|
let wrapper;
|
|
|
|
let mock;
|
|
|
|
const getAlert = () => wrapper.find(GlAlert);
|
|
|
|
const getAllAlerts = () => wrapper.findAll(GlAlert);
|
|
|
|
const getGraph = () => wrapper.find(DagGraph);
|
2020-07-28 23:09:34 +05:30
|
|
|
const getNotes = () => wrapper.find(DagAnnotations);
|
2020-06-23 00:09:42 +05:30
|
|
|
const getErrorText = type => wrapper.vm.$options.errorTexts[type];
|
2020-07-28 23:09:34 +05:30
|
|
|
const getEmptyState = () => wrapper.find(GlEmptyState);
|
2020-06-23 00:09:42 +05:30
|
|
|
|
|
|
|
const dataPath = '/root/test/pipelines/90/dag.json';
|
|
|
|
|
|
|
|
const createComponent = (propsData = {}, method = shallowMount) => {
|
|
|
|
if (wrapper?.destroy) {
|
|
|
|
wrapper.destroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
wrapper = method(Dag, {
|
2020-07-28 23:09:34 +05:30
|
|
|
propsData: {
|
|
|
|
emptySvgPath: '/my-svg',
|
|
|
|
dagDocPath: '/my-doc',
|
|
|
|
...propsData,
|
|
|
|
},
|
2020-06-23 00:09:42 +05:30
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
showFailureAlert: false,
|
|
|
|
};
|
|
|
|
},
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
mock = new MockAdapter(axios);
|
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(() => {
|
|
|
|
mock.restore();
|
|
|
|
wrapper.destroy();
|
|
|
|
wrapper = null;
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('when there is no dataUrl', () => {
|
|
|
|
beforeEach(() => {
|
|
|
|
createComponent({ graphUrl: undefined });
|
|
|
|
});
|
|
|
|
|
|
|
|
it('shows the DEFAULT alert and not the graph', () => {
|
|
|
|
expect(getAlert().exists()).toBe(true);
|
|
|
|
expect(getAlert().text()).toBe(getErrorText(DEFAULT));
|
|
|
|
expect(getGraph().exists()).toBe(false);
|
|
|
|
});
|
2020-07-28 23:09:34 +05:30
|
|
|
|
|
|
|
it('does not render the empty state', () => {
|
|
|
|
expect(getEmptyState().exists()).toBe(false);
|
|
|
|
});
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|
|
|
|
|
|
|
|
describe('when there is a dataUrl', () => {
|
|
|
|
describe('but the data fetch fails', () => {
|
2020-07-28 23:09:34 +05:30
|
|
|
beforeEach(async () => {
|
2020-06-23 00:09:42 +05:30
|
|
|
mock.onGet(dataPath).replyOnce(500);
|
|
|
|
createComponent({ graphUrl: dataPath });
|
2020-07-28 23:09:34 +05:30
|
|
|
|
|
|
|
await wrapper.vm.$nextTick();
|
|
|
|
|
|
|
|
return waitForPromises();
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|
|
|
|
|
|
|
|
it('shows the LOAD_FAILURE alert and not the graph', () => {
|
2020-07-28 23:09:34 +05:30
|
|
|
expect(getAlert().exists()).toBe(true);
|
|
|
|
expect(getAlert().text()).toBe(getErrorText(LOAD_FAILURE));
|
|
|
|
expect(getGraph().exists()).toBe(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('does not render the empty state', () => {
|
|
|
|
expect(getEmptyState().exists()).toBe(false);
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('the data fetch succeeds but the parse fails', () => {
|
2020-07-28 23:09:34 +05:30
|
|
|
beforeEach(async () => {
|
2020-06-23 00:09:42 +05:30
|
|
|
mock.onGet(dataPath).replyOnce(200, unparseableGraph);
|
|
|
|
createComponent({ graphUrl: dataPath });
|
2020-07-28 23:09:34 +05:30
|
|
|
|
|
|
|
await wrapper.vm.$nextTick();
|
|
|
|
|
|
|
|
return waitForPromises();
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|
|
|
|
|
|
|
|
it('shows the PARSE_FAILURE alert and not the graph', () => {
|
2020-07-28 23:09:34 +05:30
|
|
|
expect(getAlert().exists()).toBe(true);
|
|
|
|
expect(getAlert().text()).toBe(getErrorText(PARSE_FAILURE));
|
|
|
|
expect(getGraph().exists()).toBe(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('does not render the empty state', () => {
|
|
|
|
expect(getEmptyState().exists()).toBe(false);
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('and the data fetch and parse succeeds', () => {
|
2020-07-28 23:09:34 +05:30
|
|
|
beforeEach(async () => {
|
2020-06-23 00:09:42 +05:30
|
|
|
mock.onGet(dataPath).replyOnce(200, mockBaseData);
|
|
|
|
createComponent({ graphUrl: dataPath }, mount);
|
2020-07-28 23:09:34 +05:30
|
|
|
|
|
|
|
await wrapper.vm.$nextTick();
|
|
|
|
|
|
|
|
return waitForPromises();
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|
|
|
|
|
2020-07-28 23:09:34 +05:30
|
|
|
it('shows the graph and the beta alert', () => {
|
|
|
|
expect(getAllAlerts().length).toBe(1);
|
|
|
|
expect(getAlert().text()).toContain('This feature is currently in beta.');
|
|
|
|
expect(getGraph().exists()).toBe(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('does not render the empty state', () => {
|
|
|
|
expect(getEmptyState().exists()).toBe(false);
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('the data fetch and parse succeeds, but the resulting graph is too small', () => {
|
2020-07-28 23:09:34 +05:30
|
|
|
beforeEach(async () => {
|
2020-06-23 00:09:42 +05:30
|
|
|
mock.onGet(dataPath).replyOnce(200, tooSmallGraph);
|
|
|
|
createComponent({ graphUrl: dataPath });
|
2020-07-28 23:09:34 +05:30
|
|
|
|
|
|
|
await wrapper.vm.$nextTick();
|
|
|
|
|
|
|
|
return waitForPromises();
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|
|
|
|
|
|
|
|
it('shows the UNSUPPORTED_DATA alert and not the graph', () => {
|
2020-07-28 23:09:34 +05:30
|
|
|
expect(getAlert().exists()).toBe(true);
|
|
|
|
expect(getAlert().text()).toBe(getErrorText(UNSUPPORTED_DATA));
|
|
|
|
expect(getGraph().exists()).toBe(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('does not show the empty dag graph state', () => {
|
|
|
|
expect(getEmptyState().exists()).toBe(false);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('the data fetch succeeds but the returned data is empty', () => {
|
|
|
|
beforeEach(async () => {
|
|
|
|
mock.onGet(dataPath).replyOnce(200, graphWithoutDependencies);
|
|
|
|
createComponent({ graphUrl: dataPath }, mount);
|
|
|
|
|
|
|
|
await wrapper.vm.$nextTick();
|
|
|
|
|
|
|
|
return waitForPromises();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('does not render an error alert or the graph', () => {
|
|
|
|
expect(getAllAlerts().length).toBe(1);
|
|
|
|
expect(getAlert().text()).toContain('This feature is currently in beta.');
|
|
|
|
expect(getGraph().exists()).toBe(false);
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|
2020-07-28 23:09:34 +05:30
|
|
|
|
|
|
|
it('shows the empty dag graph state', () => {
|
|
|
|
expect(getEmptyState().exists()).toBe(true);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('annotations', () => {
|
|
|
|
beforeEach(async () => {
|
|
|
|
mock.onGet(dataPath).replyOnce(200, mockBaseData);
|
|
|
|
createComponent({ graphUrl: dataPath }, mount);
|
|
|
|
|
|
|
|
await wrapper.vm.$nextTick();
|
|
|
|
|
|
|
|
return waitForPromises();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('toggles on link mouseover and mouseout', async () => {
|
|
|
|
const currentNote = singleNote['dag-link103'];
|
|
|
|
|
|
|
|
expect(getNotes().exists()).toBe(false);
|
|
|
|
|
|
|
|
getGraph().vm.$emit('update-annotation', { type: ADD_NOTE, data: currentNote });
|
|
|
|
await wrapper.vm.$nextTick();
|
|
|
|
expect(getNotes().exists()).toBe(true);
|
|
|
|
|
|
|
|
getGraph().vm.$emit('update-annotation', { type: REMOVE_NOTE, data: currentNote });
|
|
|
|
await wrapper.vm.$nextTick();
|
|
|
|
expect(getNotes().exists()).toBe(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('toggles on node and link click', async () => {
|
|
|
|
expect(getNotes().exists()).toBe(false);
|
|
|
|
|
|
|
|
getGraph().vm.$emit('update-annotation', { type: REPLACE_NOTES, data: multiNote });
|
|
|
|
await wrapper.vm.$nextTick();
|
|
|
|
expect(getNotes().exists()).toBe(true);
|
|
|
|
|
|
|
|
getGraph().vm.$emit('update-annotation', { type: REPLACE_NOTES, data: {} });
|
|
|
|
await wrapper.vm.$nextTick();
|
|
|
|
expect(getNotes().exists()).toBe(false);
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|