summaryrefslogtreecommitdiff
path: root/spec/frontend/commit/components/commit_box_pipeline_status_spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/commit/components/commit_box_pipeline_status_spec.js')
-rw-r--r--spec/frontend/commit/components/commit_box_pipeline_status_spec.js150
1 files changed, 150 insertions, 0 deletions
diff --git a/spec/frontend/commit/components/commit_box_pipeline_status_spec.js b/spec/frontend/commit/components/commit_box_pipeline_status_spec.js
new file mode 100644
index 00000000000..db7b7b45397
--- /dev/null
+++ b/spec/frontend/commit/components/commit_box_pipeline_status_spec.js
@@ -0,0 +1,150 @@
+import { GlLoadingIcon, GlLink } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import createFlash from '~/flash';
+import CiIcon from '~/vue_shared/components/ci_icon.vue';
+import CommitBoxPipelineStatus from '~/projects/commit_box/info/components/commit_box_pipeline_status.vue';
+import {
+ COMMIT_BOX_POLL_INTERVAL,
+ PIPELINE_STATUS_FETCH_ERROR,
+} from '~/projects/commit_box/info/constants';
+import getLatestPipelineStatusQuery from '~/projects/commit_box/info/graphql/queries/get_latest_pipeline_status.query.graphql';
+import * as graphQlUtils from '~/pipelines/components/graph/utils';
+import { mockPipelineStatusResponse } from '../mock_data';
+
+const mockProvide = {
+ fullPath: 'root/ci-project',
+ iid: '46',
+ graphqlResourceEtag: '/api/graphql:pipelines/id/320',
+};
+
+Vue.use(VueApollo);
+
+jest.mock('~/flash');
+
+describe('Commit box pipeline status', () => {
+ let wrapper;
+
+ const statusSuccessHandler = jest.fn().mockResolvedValue(mockPipelineStatusResponse);
+ const failedHandler = jest.fn().mockRejectedValue(new Error('GraphQL error'));
+
+ const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
+ const findStatusIcon = () => wrapper.findComponent(CiIcon);
+ const findPipelineLink = () => wrapper.findComponent(GlLink);
+
+ const advanceToNextFetch = () => {
+ jest.advanceTimersByTime(COMMIT_BOX_POLL_INTERVAL);
+ };
+
+ const createMockApolloProvider = (handler) => {
+ const requestHandlers = [[getLatestPipelineStatusQuery, handler]];
+
+ return createMockApollo(requestHandlers);
+ };
+
+ const createComponent = (handler = statusSuccessHandler) => {
+ wrapper = shallowMount(CommitBoxPipelineStatus, {
+ provide: {
+ ...mockProvide,
+ },
+ apolloProvider: createMockApolloProvider(handler),
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('loading state', () => {
+ it('should display loading state when loading', () => {
+ createComponent();
+
+ expect(findLoadingIcon().exists()).toBe(true);
+ expect(findStatusIcon().exists()).toBe(false);
+ });
+ });
+
+ describe('loaded state', () => {
+ beforeEach(async () => {
+ createComponent();
+
+ await waitForPromises();
+ });
+
+ it('should display pipeline status after the query is resolved successfully', async () => {
+ expect(findStatusIcon().exists()).toBe(true);
+
+ expect(findLoadingIcon().exists()).toBe(false);
+ expect(createFlash).toHaveBeenCalledTimes(0);
+ });
+
+ it('should link to the latest pipeline', () => {
+ const {
+ data: {
+ project: {
+ pipeline: {
+ detailedStatus: { detailsPath },
+ },
+ },
+ },
+ } = mockPipelineStatusResponse;
+
+ expect(findPipelineLink().attributes('href')).toBe(detailsPath);
+ });
+ });
+
+ describe('error state', () => {
+ it('createFlash should show if there is an error fetching the pipeline status', async () => {
+ createComponent(failedHandler);
+
+ await waitForPromises();
+
+ expect(createFlash).toHaveBeenCalledWith({
+ message: PIPELINE_STATUS_FETCH_ERROR,
+ });
+ });
+ });
+
+ describe('polling', () => {
+ it('polling interval is set for pipeline stages', () => {
+ createComponent();
+
+ const expectedInterval = wrapper.vm.$apollo.queries.pipelineStatus.options.pollInterval;
+
+ expect(expectedInterval).toBe(COMMIT_BOX_POLL_INTERVAL);
+ });
+
+ it('polls for pipeline status', async () => {
+ createComponent();
+
+ await waitForPromises();
+
+ expect(statusSuccessHandler).toHaveBeenCalledTimes(1);
+
+ advanceToNextFetch();
+ await waitForPromises();
+
+ expect(statusSuccessHandler).toHaveBeenCalledTimes(2);
+
+ advanceToNextFetch();
+ await waitForPromises();
+
+ expect(statusSuccessHandler).toHaveBeenCalledTimes(3);
+ });
+
+ it('toggles pipelineStatus polling with visibility check', async () => {
+ jest.spyOn(graphQlUtils, 'toggleQueryPollingByVisibility');
+
+ createComponent();
+
+ await waitForPromises();
+
+ expect(graphQlUtils.toggleQueryPollingByVisibility).toHaveBeenCalledWith(
+ wrapper.vm.$apollo.queries.pipelineStatus,
+ );
+ });
+ });
+});