2021-02-03 21:09:17 +00:00
|
|
|
import { shallowMount, createLocalVue } from '@vue/test-utils';
|
|
|
|
import { GlAlert, GlButton, GlLoadingIcon, GlTabs } from '@gitlab/ui';
|
2020-11-20 21:09:12 +00:00
|
|
|
import VueApollo from 'vue-apollo';
|
2021-02-01 15:08:56 +00:00
|
|
|
import waitForPromises from 'helpers/wait_for_promises';
|
2021-01-15 00:10:45 +00:00
|
|
|
import createMockApollo from 'helpers/mock_apollo_helper';
|
2021-02-03 21:09:17 +00:00
|
|
|
import TextEditor from '~/pipeline_editor/components/text_editor.vue';
|
2020-11-20 21:09:12 +00:00
|
|
|
|
2021-01-13 15:10:40 +00:00
|
|
|
import httpStatusCodes from '~/lib/utils/http_status';
|
2020-11-20 21:09:12 +00:00
|
|
|
import {
|
|
|
|
mockCiConfigPath,
|
2020-12-08 21:10:06 +00:00
|
|
|
mockCiConfigQueryResponse,
|
2020-11-20 21:09:12 +00:00
|
|
|
mockCiYml,
|
|
|
|
mockDefaultBranch,
|
2021-01-09 00:10:30 +00:00
|
|
|
mockProjectFullPath,
|
2020-11-20 21:09:12 +00:00
|
|
|
} from './mock_data';
|
2020-10-30 12:08:44 +00:00
|
|
|
|
2021-02-03 21:09:17 +00:00
|
|
|
import { COMMIT_SUCCESS, COMMIT_FAILURE, LOAD_FAILURE_UNKNOWN } from '~/pipeline_editor/constants';
|
|
|
|
import CommitForm from '~/pipeline_editor/components/commit/commit_form.vue';
|
|
|
|
import getCiConfigData from '~/pipeline_editor/graphql/queries/ci_config.graphql';
|
|
|
|
import PipelineEditorApp from '~/pipeline_editor/pipeline_editor_app.vue';
|
|
|
|
import PipelineEditorHome from '~/pipeline_editor/pipeline_editor_home.vue';
|
|
|
|
|
2020-11-20 21:09:12 +00:00
|
|
|
const localVue = createLocalVue();
|
|
|
|
localVue.use(VueApollo);
|
|
|
|
|
2020-12-23 06:10:22 +00:00
|
|
|
const MockEditorLite = {
|
|
|
|
template: '<div/>',
|
|
|
|
};
|
|
|
|
|
2021-01-09 00:10:30 +00:00
|
|
|
const mockProvide = {
|
2021-02-03 21:09:17 +00:00
|
|
|
ciConfigPath: mockCiConfigPath,
|
|
|
|
defaultBranch: mockDefaultBranch,
|
2021-01-09 00:10:30 +00:00
|
|
|
projectFullPath: mockProjectFullPath,
|
|
|
|
};
|
|
|
|
|
2021-02-03 21:09:17 +00:00
|
|
|
describe('Pipeline editor app component', () => {
|
2020-10-30 12:08:44 +00:00
|
|
|
let wrapper;
|
|
|
|
|
2020-11-20 21:09:12 +00:00
|
|
|
let mockApollo;
|
|
|
|
let mockBlobContentData;
|
2020-12-08 21:10:06 +00:00
|
|
|
let mockCiConfigData;
|
2020-11-20 21:09:12 +00:00
|
|
|
|
2021-02-03 21:09:17 +00:00
|
|
|
const createComponent = ({ blobLoading = false, options = {} } = {}) => {
|
|
|
|
wrapper = shallowMount(PipelineEditorApp, {
|
|
|
|
provide: mockProvide,
|
2020-10-30 21:08:52 +00:00
|
|
|
stubs: {
|
2020-11-03 15:09:05 +00:00
|
|
|
GlTabs,
|
2020-11-20 21:09:12 +00:00
|
|
|
GlButton,
|
|
|
|
CommitForm,
|
2020-12-23 06:10:22 +00:00
|
|
|
EditorLite: MockEditorLite,
|
2020-10-30 21:08:52 +00:00
|
|
|
},
|
|
|
|
mocks: {
|
|
|
|
$apollo: {
|
|
|
|
queries: {
|
2021-02-03 21:09:17 +00:00
|
|
|
initialCiFileContent: {
|
2020-12-16 15:10:18 +00:00
|
|
|
loading: blobLoading,
|
|
|
|
},
|
|
|
|
ciConfigData: {
|
2021-02-03 21:09:17 +00:00
|
|
|
loading: false,
|
2020-10-30 21:08:52 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2020-11-20 21:09:12 +00:00
|
|
|
...options,
|
2020-10-30 21:08:52 +00:00
|
|
|
});
|
2020-10-30 12:08:44 +00:00
|
|
|
};
|
|
|
|
|
2021-02-03 21:09:17 +00:00
|
|
|
const createComponentWithApollo = ({ props = {} } = {}) => {
|
2020-12-22 15:09:51 +00:00
|
|
|
const handlers = [[getCiConfigData, mockCiConfigData]];
|
2020-12-08 21:10:06 +00:00
|
|
|
const resolvers = {
|
2020-11-20 21:09:12 +00:00
|
|
|
Query: {
|
|
|
|
blobContent() {
|
|
|
|
return {
|
|
|
|
__typename: 'BlobContent',
|
|
|
|
rawData: mockBlobContentData(),
|
|
|
|
};
|
|
|
|
},
|
|
|
|
},
|
2020-12-08 21:10:06 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
mockApollo = createMockApollo(handlers, resolvers);
|
2020-11-20 21:09:12 +00:00
|
|
|
|
|
|
|
const options = {
|
|
|
|
localVue,
|
|
|
|
mocks: {},
|
|
|
|
apolloProvider: mockApollo,
|
|
|
|
};
|
|
|
|
|
2021-02-03 21:09:17 +00:00
|
|
|
createComponent({ props, options });
|
2020-11-20 21:09:12 +00:00
|
|
|
};
|
|
|
|
|
2021-02-03 21:09:17 +00:00
|
|
|
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
|
|
|
|
const findAlert = () => wrapper.findComponent(GlAlert);
|
|
|
|
const findEditorHome = () => wrapper.findComponent(PipelineEditorHome);
|
|
|
|
const findTextEditor = () => wrapper.findComponent(TextEditor);
|
2020-10-30 12:08:44 +00:00
|
|
|
|
2020-11-03 15:09:05 +00:00
|
|
|
beforeEach(() => {
|
2020-11-20 21:09:12 +00:00
|
|
|
mockBlobContentData = jest.fn();
|
2020-12-25 09:10:31 +00:00
|
|
|
mockCiConfigData = jest.fn();
|
2020-11-03 15:09:05 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(() => {
|
2020-11-20 21:09:12 +00:00
|
|
|
mockBlobContentData.mockReset();
|
2020-12-08 21:10:06 +00:00
|
|
|
mockCiConfigData.mockReset();
|
2020-11-20 21:09:12 +00:00
|
|
|
|
2020-11-03 15:09:05 +00:00
|
|
|
wrapper.destroy();
|
|
|
|
wrapper = null;
|
|
|
|
});
|
|
|
|
|
2020-12-16 15:10:18 +00:00
|
|
|
it('displays a loading icon if the blob query is loading', () => {
|
|
|
|
createComponent({ blobLoading: true });
|
2020-10-30 12:08:44 +00:00
|
|
|
|
2020-10-30 21:08:52 +00:00
|
|
|
expect(findLoadingIcon().exists()).toBe(true);
|
2020-11-20 21:09:12 +00:00
|
|
|
expect(findTextEditor().exists()).toBe(false);
|
2020-10-30 21:08:52 +00:00
|
|
|
});
|
|
|
|
|
2020-12-25 09:10:31 +00:00
|
|
|
describe('when queries are called', () => {
|
|
|
|
beforeEach(() => {
|
2020-11-20 21:09:12 +00:00
|
|
|
mockBlobContentData.mockResolvedValue(mockCiYml);
|
2020-12-25 09:10:31 +00:00
|
|
|
mockCiConfigData.mockResolvedValue(mockCiConfigQueryResponse);
|
|
|
|
});
|
|
|
|
|
2021-01-13 15:10:40 +00:00
|
|
|
describe('when file exists', () => {
|
|
|
|
beforeEach(async () => {
|
|
|
|
createComponentWithApollo();
|
2020-11-20 21:09:12 +00:00
|
|
|
|
2021-01-13 15:10:40 +00:00
|
|
|
await waitForPromises();
|
|
|
|
});
|
2020-11-20 21:09:12 +00:00
|
|
|
|
2021-02-03 21:09:17 +00:00
|
|
|
it('shows pipeline editor home component', () => {
|
|
|
|
expect(findEditorHome().exists()).toBe(true);
|
2021-01-13 15:10:40 +00:00
|
|
|
});
|
2020-10-30 21:08:52 +00:00
|
|
|
|
2021-02-03 21:09:17 +00:00
|
|
|
it('no error is shown when data is set', () => {
|
2021-01-13 15:10:40 +00:00
|
|
|
expect(findAlert().exists()).toBe(false);
|
|
|
|
});
|
2020-12-25 09:10:31 +00:00
|
|
|
|
2021-01-13 15:10:40 +00:00
|
|
|
it('ci config query is called with correct variables', async () => {
|
|
|
|
createComponentWithApollo();
|
2020-12-25 09:10:31 +00:00
|
|
|
|
2021-01-13 15:10:40 +00:00
|
|
|
await waitForPromises();
|
|
|
|
|
|
|
|
expect(mockCiConfigData).toHaveBeenCalledWith({
|
|
|
|
content: mockCiYml,
|
|
|
|
projectPath: mockProjectFullPath,
|
|
|
|
});
|
2020-12-25 09:10:31 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-01-13 15:10:40 +00:00
|
|
|
describe('when no file exists', () => {
|
2021-02-03 21:09:17 +00:00
|
|
|
const noFileAlertMsg =
|
2021-01-13 15:10:40 +00:00
|
|
|
'There is no .gitlab-ci.yml file in this repository, please add one and visit the Pipeline Editor again.';
|
|
|
|
|
2021-02-03 21:09:17 +00:00
|
|
|
it('shows a 404 error message and does not show editor home component', async () => {
|
2021-01-13 15:10:40 +00:00
|
|
|
mockBlobContentData.mockRejectedValueOnce({
|
|
|
|
response: {
|
|
|
|
status: httpStatusCodes.NOT_FOUND,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
createComponentWithApollo();
|
2020-11-20 21:09:12 +00:00
|
|
|
|
2021-01-13 15:10:40 +00:00
|
|
|
await waitForPromises();
|
2020-10-30 21:08:52 +00:00
|
|
|
|
2021-02-03 21:09:17 +00:00
|
|
|
expect(findAlert().text()).toBe(noFileAlertMsg);
|
|
|
|
expect(findEditorHome().exists()).toBe(false);
|
2020-10-30 21:08:52 +00:00
|
|
|
});
|
2020-11-20 21:09:12 +00:00
|
|
|
|
2021-02-03 21:09:17 +00:00
|
|
|
it('shows a 400 error message and does not show editor home component', async () => {
|
2021-01-13 15:10:40 +00:00
|
|
|
mockBlobContentData.mockRejectedValueOnce({
|
|
|
|
response: {
|
|
|
|
status: httpStatusCodes.BAD_REQUEST,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
createComponentWithApollo();
|
2020-11-20 21:09:12 +00:00
|
|
|
|
2021-01-13 15:10:40 +00:00
|
|
|
await waitForPromises();
|
2020-10-30 21:08:52 +00:00
|
|
|
|
2021-02-03 21:09:17 +00:00
|
|
|
expect(findAlert().text()).toBe(noFileAlertMsg);
|
|
|
|
expect(findEditorHome().exists()).toBe(false);
|
2021-01-13 15:10:40 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
it('shows a unkown error message', async () => {
|
|
|
|
mockBlobContentData.mockRejectedValueOnce(new Error('My error!'));
|
|
|
|
createComponentWithApollo();
|
|
|
|
await waitForPromises();
|
2020-10-30 21:08:52 +00:00
|
|
|
|
2021-02-03 21:09:17 +00:00
|
|
|
expect(findAlert().text()).toBe(wrapper.vm.$options.errorTexts[LOAD_FAILURE_UNKNOWN]);
|
|
|
|
expect(findEditorHome().exists()).toBe(true);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('when the user commits', () => {
|
|
|
|
const updateFailureMessage = 'The GitLab CI configuration could not be updated.';
|
|
|
|
|
|
|
|
describe('and the commit mutation succeeds', () => {
|
|
|
|
beforeEach(() => {
|
|
|
|
createComponent();
|
|
|
|
|
|
|
|
findEditorHome().vm.$emit('commit', { type: COMMIT_SUCCESS });
|
|
|
|
});
|
|
|
|
|
|
|
|
it('shows a confirmation message', () => {
|
|
|
|
expect(findAlert().text()).toBe(wrapper.vm.$options.successTexts[COMMIT_SUCCESS]);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
describe('and the commit mutation fails', () => {
|
|
|
|
const commitFailedReasons = ['Commit failed'];
|
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
createComponent();
|
|
|
|
|
|
|
|
findEditorHome().vm.$emit('showError', {
|
|
|
|
type: COMMIT_FAILURE,
|
|
|
|
reasons: commitFailedReasons,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('shows an error message', () => {
|
|
|
|
expect(findAlert().text()).toMatchInterpolatedText(
|
|
|
|
`${updateFailureMessage} ${commitFailedReasons[0]}`,
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
describe('when an unknown error occurs', () => {
|
|
|
|
const unknownReasons = ['Commit failed'];
|
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
createComponent();
|
|
|
|
|
|
|
|
findEditorHome().vm.$emit('showError', {
|
|
|
|
type: COMMIT_FAILURE,
|
|
|
|
reasons: unknownReasons,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('shows an error message', () => {
|
|
|
|
expect(findAlert().text()).toMatchInterpolatedText(
|
|
|
|
`${updateFailureMessage} ${unknownReasons[0]}`,
|
|
|
|
);
|
|
|
|
});
|
2021-01-13 15:10:40 +00:00
|
|
|
});
|
2020-10-30 21:08:52 +00:00
|
|
|
});
|
2020-10-30 12:08:44 +00:00
|
|
|
});
|
|
|
|
});
|