summaryrefslogtreecommitdiff
path: root/spec/frontend/pipeline_editor/pipeline_editor_app_spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/pipeline_editor/pipeline_editor_app_spec.js')
-rw-r--r--spec/frontend/pipeline_editor/pipeline_editor_app_spec.js589
1 files changed, 0 insertions, 589 deletions
diff --git a/spec/frontend/pipeline_editor/pipeline_editor_app_spec.js b/spec/frontend/pipeline_editor/pipeline_editor_app_spec.js
deleted file mode 100644
index 9fe1536d3f5..00000000000
--- a/spec/frontend/pipeline_editor/pipeline_editor_app_spec.js
+++ /dev/null
@@ -1,589 +0,0 @@
-import { GlAlert, GlButton, GlLoadingIcon } from '@gitlab/ui';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
-import VueApollo from 'vue-apollo';
-import createMockApollo from 'helpers/mock_apollo_helper';
-import setWindowLocation from 'helpers/set_window_location_helper';
-import waitForPromises from 'helpers/wait_for_promises';
-
-import { objectToQuery, redirectTo } from '~/lib/utils/url_utility';
-import { resolvers } from '~/pipeline_editor/graphql/resolvers';
-import PipelineEditorTabs from '~/pipeline_editor/components/pipeline_editor_tabs.vue';
-import PipelineEditorEmptyState from '~/pipeline_editor/components/ui/pipeline_editor_empty_state.vue';
-import PipelineEditorMessages from '~/pipeline_editor/components/ui/pipeline_editor_messages.vue';
-import PipelineEditorHeader from '~/pipeline_editor/components/header/pipeline_editor_header.vue';
-import ValidationSegment, {
- i18n as validationSegmenti18n,
-} from '~/pipeline_editor/components/header/validation_segment.vue';
-import {
- COMMIT_SUCCESS,
- COMMIT_SUCCESS_WITH_REDIRECT,
- COMMIT_FAILURE,
- EDITOR_APP_STATUS_LOADING,
-} from '~/pipeline_editor/constants';
-import getBlobContent from '~/pipeline_editor/graphql/queries/blob_content.query.graphql';
-import getCiConfigData from '~/pipeline_editor/graphql/queries/ci_config.query.graphql';
-import getTemplate from '~/pipeline_editor/graphql/queries/get_starter_template.query.graphql';
-import getLatestCommitShaQuery from '~/pipeline_editor/graphql/queries/latest_commit_sha.query.graphql';
-import getPipelineQuery from '~/pipeline_editor/graphql/queries/pipeline.query.graphql';
-import getCurrentBranch from '~/pipeline_editor/graphql/queries/client/current_branch.query.graphql';
-import getAppStatus from '~/pipeline_editor/graphql/queries/client/app_status.query.graphql';
-
-import PipelineEditorApp from '~/pipeline_editor/pipeline_editor_app.vue';
-import PipelineEditorHome from '~/pipeline_editor/pipeline_editor_home.vue';
-
-import {
- mockCiConfigPath,
- mockCiConfigQueryResponse,
- mockBlobContentQueryResponse,
- mockBlobContentQueryResponseNoCiFile,
- mockCiYml,
- mockCiTemplateQueryResponse,
- mockCommitSha,
- mockCommitShaResults,
- mockDefaultBranch,
- mockEmptyCommitShaResults,
- mockNewCommitShaResults,
- mockNewMergeRequestPath,
- mockProjectFullPath,
-} from './mock_data';
-
-jest.mock('~/lib/utils/url_utility', () => ({
- ...jest.requireActual('~/lib/utils/url_utility'),
- redirectTo: jest.fn(),
-}));
-
-const localVue = createLocalVue();
-localVue.use(VueApollo);
-
-const defaultProvide = {
- ciConfigPath: mockCiConfigPath,
- defaultBranch: mockDefaultBranch,
- newMergeRequestPath: mockNewMergeRequestPath,
- projectFullPath: mockProjectFullPath,
- usesExternalConfig: false,
-};
-
-describe('Pipeline editor app component', () => {
- let wrapper;
-
- let mockApollo;
- let mockBlobContentData;
- let mockCiConfigData;
- let mockGetTemplate;
- let mockLatestCommitShaQuery;
- let mockPipelineQuery;
-
- const createComponent = ({
- blobLoading = false,
- options = {},
- provide = {},
- stubs = {},
- } = {}) => {
- wrapper = shallowMount(PipelineEditorApp, {
- provide: { ...defaultProvide, ...provide },
- stubs,
- mocks: {
- $apollo: {
- queries: {
- initialCiFileContent: {
- loading: blobLoading,
- },
- },
- },
- },
- ...options,
- });
- };
-
- const createComponentWithApollo = async ({
- provide = {},
- stubs = {},
- withUndefinedBranch = false,
- } = {}) => {
- const handlers = [
- [getBlobContent, mockBlobContentData],
- [getCiConfigData, mockCiConfigData],
- [getTemplate, mockGetTemplate],
- [getLatestCommitShaQuery, mockLatestCommitShaQuery],
- [getPipelineQuery, mockPipelineQuery],
- ];
-
- mockApollo = createMockApollo(handlers, resolvers);
-
- if (!withUndefinedBranch) {
- mockApollo.clients.defaultClient.cache.writeQuery({
- query: getCurrentBranch,
- data: {
- workBranches: {
- __typename: 'BranchList',
- current: {
- __typename: 'WorkBranch',
- name: mockDefaultBranch,
- },
- },
- },
- });
- }
-
- mockApollo.clients.defaultClient.cache.writeQuery({
- query: getAppStatus,
- data: {
- app: {
- __typename: 'AppData',
- status: EDITOR_APP_STATUS_LOADING,
- },
- },
- });
-
- const options = {
- localVue,
- mocks: {},
- apolloProvider: mockApollo,
- };
-
- createComponent({ provide, stubs, options });
-
- return waitForPromises();
- };
-
- const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
- const findAlert = () => wrapper.findComponent(GlAlert);
- const findEditorHome = () => wrapper.findComponent(PipelineEditorHome);
- const findEmptyState = () => wrapper.findComponent(PipelineEditorEmptyState);
- const findEmptyStateButton = () => findEmptyState().findComponent(GlButton);
- const findValidationSegment = () => wrapper.findComponent(ValidationSegment);
-
- beforeEach(() => {
- mockBlobContentData = jest.fn();
- mockCiConfigData = jest.fn();
- mockGetTemplate = jest.fn();
- mockLatestCommitShaQuery = jest.fn();
- mockPipelineQuery = jest.fn();
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- describe('loading state', () => {
- it('displays a loading icon if the blob query is loading', () => {
- createComponent({ blobLoading: true });
-
- expect(findLoadingIcon().exists()).toBe(true);
- expect(findEditorHome().exists()).toBe(false);
- });
- });
-
- describe('skipping queries', () => {
- describe('when branchName is undefined', () => {
- beforeEach(async () => {
- await createComponentWithApollo({ withUndefinedBranch: true });
- });
-
- it('does not calls getBlobContent', () => {
- expect(mockBlobContentData).not.toHaveBeenCalled();
- });
- });
-
- describe('when branchName is defined', () => {
- beforeEach(async () => {
- await createComponentWithApollo();
- });
-
- it('calls getBlobContent', () => {
- expect(mockBlobContentData).toHaveBeenCalled();
- });
- });
-
- describe('when commit sha is undefined', () => {
- beforeEach(async () => {
- mockLatestCommitShaQuery.mockResolvedValue(undefined);
- await createComponentWithApollo();
- });
-
- it('calls getBlobContent', () => {
- expect(mockBlobContentData).toHaveBeenCalled();
- });
-
- it('does not call ciConfigData', () => {
- expect(mockCiConfigData).not.toHaveBeenCalled();
- });
- });
-
- describe('when commit sha is defined', () => {
- beforeEach(async () => {
- mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponse);
- mockLatestCommitShaQuery.mockResolvedValue(mockCommitShaResults);
- await createComponentWithApollo();
- });
-
- it('calls ciConfigData', () => {
- expect(mockCiConfigData).toHaveBeenCalled();
- });
- });
- });
-
- describe('when queries are called', () => {
- beforeEach(() => {
- mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponse);
- mockCiConfigData.mockResolvedValue(mockCiConfigQueryResponse);
- mockLatestCommitShaQuery.mockResolvedValue(mockCommitShaResults);
- });
-
- describe('when project uses an external CI config file', () => {
- beforeEach(async () => {
- await createComponentWithApollo({
- provide: {
- usesExternalConfig: true,
- },
- });
- });
-
- it('shows an empty state and does not show editor home component', () => {
- expect(findEmptyState().exists()).toBe(true);
- expect(findAlert().exists()).toBe(false);
- expect(findEditorHome().exists()).toBe(false);
- });
- });
-
- describe('when file exists', () => {
- beforeEach(async () => {
- await createComponentWithApollo();
-
- jest
- .spyOn(wrapper.vm.$apollo.queries.commitSha, 'startPolling')
- .mockImplementation(jest.fn());
- });
-
- it('shows pipeline editor home component', () => {
- expect(findEditorHome().exists()).toBe(true);
- });
-
- it('no error is shown when data is set', () => {
- expect(findAlert().exists()).toBe(false);
- });
-
- it('ci config query is called with correct variables', async () => {
- expect(mockCiConfigData).toHaveBeenCalledWith({
- content: mockCiYml,
- projectPath: mockProjectFullPath,
- sha: mockCommitSha,
- });
- });
-
- it('does not poll for the commit sha', () => {
- expect(wrapper.vm.$apollo.queries.commitSha.startPolling).toHaveBeenCalledTimes(0);
- });
- });
-
- describe('when no CI config file exists', () => {
- beforeEach(async () => {
- mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponseNoCiFile);
- await createComponentWithApollo({
- stubs: {
- PipelineEditorEmptyState,
- },
- });
-
- jest
- .spyOn(wrapper.vm.$apollo.queries.commitSha, 'startPolling')
- .mockImplementation(jest.fn());
- });
-
- it('shows an empty state and does not show editor home component', async () => {
- expect(findEmptyState().exists()).toBe(true);
- expect(findAlert().exists()).toBe(false);
- expect(findEditorHome().exists()).toBe(false);
- });
-
- it('does not poll for the commit sha', () => {
- expect(wrapper.vm.$apollo.queries.commitSha.startPolling).toHaveBeenCalledTimes(0);
- });
-
- describe('because of a fetching error', () => {
- it('shows a unkown error message', async () => {
- const loadUnknownFailureText = 'The CI configuration was not loaded, please try again.';
-
- mockBlobContentData.mockRejectedValueOnce();
- await createComponentWithApollo({
- stubs: {
- PipelineEditorMessages,
- },
- });
-
- expect(findEmptyState().exists()).toBe(false);
-
- expect(findAlert().text()).toBe(loadUnknownFailureText);
- expect(findEditorHome().exists()).toBe(true);
- });
- });
- });
-
- describe('with no CI config setup', () => {
- it('user can click on CTA button to get started', async () => {
- mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponseNoCiFile);
- mockLatestCommitShaQuery.mockResolvedValue(mockEmptyCommitShaResults);
-
- await createComponentWithApollo({
- stubs: {
- PipelineEditorHome,
- PipelineEditorEmptyState,
- },
- });
-
- expect(findEmptyState().exists()).toBe(true);
- expect(findEditorHome().exists()).toBe(false);
-
- await findEmptyStateButton().vm.$emit('click');
-
- expect(findEmptyState().exists()).toBe(false);
- expect(findEditorHome().exists()).toBe(true);
- });
- });
-
- describe('when the lint query returns a 500 error', () => {
- beforeEach(async () => {
- mockCiConfigData.mockRejectedValueOnce(new Error(500));
- await createComponentWithApollo({
- stubs: { PipelineEditorHome, PipelineEditorHeader, ValidationSegment },
- });
- });
-
- it('shows that the lint service is down', () => {
- expect(findValidationSegment().text()).toContain(
- validationSegmenti18n.unavailableValidation,
- );
- });
-
- it('does not report an error or scroll to the top', () => {
- expect(findAlert().exists()).toBe(false);
- expect(window.scrollTo).not.toHaveBeenCalled();
- });
- });
-
- describe('when the user commits', () => {
- const updateFailureMessage = 'The GitLab CI configuration could not be updated.';
- const updateSuccessMessage = 'Your changes have been successfully committed.';
-
- describe('and the commit mutation succeeds', () => {
- beforeEach(async () => {
- window.scrollTo = jest.fn();
- await createComponentWithApollo({ stubs: { PipelineEditorMessages } });
-
- findEditorHome().vm.$emit('commit', { type: COMMIT_SUCCESS });
- });
-
- it('shows a confirmation message', () => {
- expect(findAlert().text()).toBe(updateSuccessMessage);
- });
-
- it('scrolls to the top of the page to bring attention to the confirmation message', () => {
- expect(window.scrollTo).toHaveBeenCalledWith({ top: 0, behavior: 'smooth' });
- });
-
- it('polls for commit sha while pipeline data is not yet available for current branch', async () => {
- jest
- .spyOn(wrapper.vm.$apollo.queries.commitSha, 'startPolling')
- .mockImplementation(jest.fn());
-
- // simulate a commit to the current branch
- findEditorHome().vm.$emit('updateCommitSha');
- await waitForPromises();
-
- expect(wrapper.vm.$apollo.queries.commitSha.startPolling).toHaveBeenCalledTimes(1);
- });
-
- it('stops polling for commit sha when pipeline data is available for newly committed branch', async () => {
- jest
- .spyOn(wrapper.vm.$apollo.queries.commitSha, 'stopPolling')
- .mockImplementation(jest.fn());
-
- mockLatestCommitShaQuery.mockResolvedValue(mockCommitShaResults);
- await wrapper.vm.$apollo.queries.commitSha.refetch();
-
- expect(wrapper.vm.$apollo.queries.commitSha.stopPolling).toHaveBeenCalledTimes(1);
- });
-
- it('stops polling for commit sha when pipeline data is available for current branch', async () => {
- jest
- .spyOn(wrapper.vm.$apollo.queries.commitSha, 'stopPolling')
- .mockImplementation(jest.fn());
-
- mockLatestCommitShaQuery.mockResolvedValue(mockNewCommitShaResults);
- findEditorHome().vm.$emit('updateCommitSha');
- await waitForPromises();
-
- expect(wrapper.vm.$apollo.queries.commitSha.stopPolling).toHaveBeenCalledTimes(1);
- });
- });
-
- describe('when the commit succeeds with a redirect', () => {
- const newBranch = 'new-branch';
-
- beforeEach(async () => {
- await createComponentWithApollo({ stubs: { PipelineEditorMessages } });
-
- findEditorHome().vm.$emit('commit', {
- type: COMMIT_SUCCESS_WITH_REDIRECT,
- params: { sourceBranch: newBranch, targetBranch: mockDefaultBranch },
- });
- });
-
- it('redirects to the merge request page with source and target branches', () => {
- const branchesQuery = objectToQuery({
- 'merge_request[source_branch]': newBranch,
- 'merge_request[target_branch]': mockDefaultBranch,
- });
-
- expect(redirectTo).toHaveBeenCalledWith(`${mockNewMergeRequestPath}?${branchesQuery}`);
- });
- });
-
- describe('and the commit mutation fails', () => {
- const commitFailedReasons = ['Commit failed'];
-
- beforeEach(async () => {
- window.scrollTo = jest.fn();
- await createComponentWithApollo({ stubs: { PipelineEditorMessages } });
-
- findEditorHome().vm.$emit('showError', {
- type: COMMIT_FAILURE,
- reasons: commitFailedReasons,
- });
- });
-
- it('shows an error message', () => {
- expect(findAlert().text()).toMatchInterpolatedText(
- `${updateFailureMessage} ${commitFailedReasons[0]}`,
- );
- });
-
- it('scrolls to the top of the page to bring attention to the error message', () => {
- expect(window.scrollTo).toHaveBeenCalledWith({ top: 0, behavior: 'smooth' });
- });
- });
-
- describe('when an unknown error occurs', () => {
- const unknownReasons = ['Commit failed'];
-
- beforeEach(async () => {
- window.scrollTo = jest.fn();
- await createComponentWithApollo({ stubs: { PipelineEditorMessages } });
-
- findEditorHome().vm.$emit('showError', {
- type: COMMIT_FAILURE,
- reasons: unknownReasons,
- });
- });
-
- it('shows an error message', () => {
- expect(findAlert().text()).toMatchInterpolatedText(
- `${updateFailureMessage} ${unknownReasons[0]}`,
- );
- });
-
- it('scrolls to the top of the page to bring attention to the error message', () => {
- expect(window.scrollTo).toHaveBeenCalledWith({ top: 0, behavior: 'smooth' });
- });
- });
- });
- });
-
- describe('when refetching content', () => {
- beforeEach(() => {
- mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponse);
- mockCiConfigData.mockResolvedValue(mockCiConfigQueryResponse);
- mockLatestCommitShaQuery.mockResolvedValue(mockCommitShaResults);
- });
-
- it('refetches blob content', async () => {
- await createComponentWithApollo();
- jest
- .spyOn(wrapper.vm.$apollo.queries.initialCiFileContent, 'refetch')
- .mockImplementation(jest.fn());
-
- expect(wrapper.vm.$apollo.queries.initialCiFileContent.refetch).toHaveBeenCalledTimes(0);
-
- await wrapper.vm.refetchContent();
-
- expect(wrapper.vm.$apollo.queries.initialCiFileContent.refetch).toHaveBeenCalledTimes(1);
- });
-
- it('hides start screen when refetch fetches CI file', async () => {
- mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponseNoCiFile);
- await createComponentWithApollo();
-
- expect(findEmptyState().exists()).toBe(true);
- expect(findEditorHome().exists()).toBe(false);
-
- mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponse);
- await wrapper.vm.$apollo.queries.initialCiFileContent.refetch();
-
- expect(findEmptyState().exists()).toBe(false);
- expect(findEditorHome().exists()).toBe(true);
- });
- });
-
- describe('when a template parameter is present in the URL', () => {
- const originalLocation = window.location.href;
-
- beforeEach(() => {
- mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponse);
- mockCiConfigData.mockResolvedValue(mockCiConfigQueryResponse);
- mockLatestCommitShaQuery.mockResolvedValue(mockCommitShaResults);
- mockGetTemplate.mockResolvedValue(mockCiTemplateQueryResponse);
- setWindowLocation('?template=Android');
- });
-
- afterEach(() => {
- setWindowLocation(originalLocation);
- });
-
- it('renders the given template', async () => {
- await createComponentWithApollo({
- stubs: { PipelineEditorHome, PipelineEditorTabs },
- });
-
- expect(mockGetTemplate).toHaveBeenCalledWith({
- projectPath: mockProjectFullPath,
- templateName: 'Android',
- });
-
- expect(findEmptyState().exists()).toBe(false);
- expect(findEditorHome().exists()).toBe(true);
- });
- });
-
- describe('when add_new_config_file query param is present', () => {
- const originalLocation = window.location.href;
-
- beforeEach(() => {
- setWindowLocation('?add_new_config_file=true');
-
- mockCiConfigData.mockResolvedValue(mockCiConfigQueryResponse);
- });
-
- afterEach(() => {
- setWindowLocation(originalLocation);
- });
-
- describe('when CI config file does not exist', () => {
- beforeEach(async () => {
- mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponseNoCiFile);
- mockLatestCommitShaQuery.mockResolvedValue(mockEmptyCommitShaResults);
- mockGetTemplate.mockResolvedValue(mockCiTemplateQueryResponse);
-
- await createComponentWithApollo();
-
- jest
- .spyOn(wrapper.vm.$apollo.queries.commitSha, 'startPolling')
- .mockImplementation(jest.fn());
- });
-
- it('skips empty state and shows editor home component', () => {
- expect(findEmptyState().exists()).toBe(false);
- expect(findEditorHome().exists()).toBe(true);
- });
- });
- });
-});