Commit 2087e3e2 authored by Mireya Andres's avatar Mireya Andres Committed by Sarah Groff Hennigh-Palermo

Integrate new pipeline query for pipeline editor

This integrates the new backend query for fetching the pipeline status
using the commit sha instead of the pipeline iid.

This was previously implemented under a disabled feature flag
(`pipeline_status_for_pipeline_editor`) using a client resolver.
parent 60444b92
<script> <script>
import { GlIcon, GlLink, GlLoadingIcon, GlSprintf } from '@gitlab/ui'; import { GlIcon, GlLink, GlLoadingIcon, GlSprintf } from '@gitlab/ui';
import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { truncateSha } from '~/lib/utils/text_utility';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import getCommitSha from '~/pipeline_editor/graphql/queries/client/commit_sha.graphql'; import getCommitSha from '~/pipeline_editor/graphql/queries/client/commit_sha.graphql';
import getPipelineQuery from '~/pipeline_editor/graphql/queries/client/pipeline.graphql'; import getPipelineQuery from '~/pipeline_editor/graphql/queries/client/pipeline.graphql';
import { toggleQueryPollingByVisibility } from '~/pipelines/components/graph/utils';
import CiIcon from '~/vue_shared/components/ci_icon.vue'; import CiIcon from '~/vue_shared/components/ci_icon.vue';
const POLL_INTERVAL = 10000; const POLL_INTERVAL = 10000;
...@@ -38,13 +40,11 @@ export default { ...@@ -38,13 +40,11 @@ export default {
}; };
}, },
update: (data) => { update: (data) => {
const { id, commitPath = '', shortSha = '', detailedStatus = {} } = const { id, commitPath = '', detailedStatus = {} } = data.project?.pipeline || {};
data.project?.pipeline || {};
return { return {
id, id,
commitPath, commitPath,
shortSha,
detailedStatus, detailedStatus,
}; };
}, },
...@@ -61,24 +61,34 @@ export default { ...@@ -61,24 +61,34 @@ export default {
}, },
computed: { computed: {
hasPipelineData() { hasPipelineData() {
return Boolean(this.$apollo.queries.pipeline?.id); return Boolean(this.pipeline?.id);
}, },
isQueryLoading() { pipelineId() {
return this.$apollo.queries.pipeline.loading && !this.hasPipelineData; return getIdFromGraphQLId(this.pipeline.id);
},
showLoadingState() {
// the query is set to poll regularly, so if there is no pipeline data
// (e.g. pipeline is null during fetch when the pipeline hasn't been
// triggered yet), we can just show the loading state until the pipeline
// details are ready to be fetched
return this.$apollo.queries.pipeline.loading || (!this.hasPipelineData && !this.hasError);
},
shortSha() {
return truncateSha(this.commitSha);
}, },
status() { status() {
return this.pipeline.detailedStatus; return this.pipeline.detailedStatus;
}, },
pipelineId() {
return getIdFromGraphQLId(this.pipeline.id);
}, },
mounted() {
toggleQueryPollingByVisibility(this.$apollo.queries.pipeline, POLL_INTERVAL);
}, },
}; };
</script> </script>
<template> <template>
<div class="gl-white-space-nowrap gl-max-w-full"> <div class="gl-white-space-nowrap gl-max-w-full">
<template v-if="isQueryLoading"> <template v-if="showLoadingState">
<gl-loading-icon class="gl-mr-auto gl-display-inline-block" size="sm" /> <gl-loading-icon class="gl-mr-auto gl-display-inline-block" size="sm" />
<span data-testid="pipeline-loading-msg">{{ $options.i18n.fetchLoading }}</span> <span data-testid="pipeline-loading-msg">{{ $options.i18n.fetchLoading }}</span>
</template> </template>
...@@ -110,7 +120,7 @@ export default { ...@@ -110,7 +120,7 @@ export default {
target="_blank" target="_blank"
data-testid="pipeline-commit" data-testid="pipeline-commit"
> >
{{ pipeline.shortSha }} {{ shortSha }}
</gl-link> </gl-link>
</template> </template>
</gl-sprintf> </gl-sprintf>
......
query getPipeline($fullPath: ID!, $sha: String!) { query getPipeline($fullPath: ID!, $sha: String!) {
project(fullPath: $fullPath) @client { project(fullPath: $fullPath) {
pipeline(sha: $sha) { pipeline(sha: $sha) {
commitPath commitPath
id id
iid iid
shortSha
status status
detailedStatus { detailedStatus {
detailsPath detailsPath
......
...@@ -11,29 +11,6 @@ export const resolvers = { ...@@ -11,29 +11,6 @@ export const resolvers = {
}), }),
}; };
}, },
/* eslint-disable @gitlab/require-i18n-strings */
project() {
return {
__typename: 'Project',
pipeline: {
__typename: 'Pipeline',
commitPath: `/-/commit/aabbccdd`,
id: 'gid://gitlab/Ci::Pipeline/118',
iid: '28',
shortSha: 'aabbccdd',
status: 'SUCCESS',
detailedStatus: {
__typename: 'DetailedStatus',
detailsPath: '/root/sample-ci-project/-/pipelines/118"',
group: 'success',
icon: 'status_success',
text: 'passed',
},
},
};
},
/* eslint-enable @gitlab/require-i18n-strings */
}, },
Mutation: { Mutation: {
lintCI: (_, { endpoint, content, dry_run }) => { lintCI: (_, { endpoint, content, dry_run }) => {
......
...@@ -4,6 +4,7 @@ import VueApollo from 'vue-apollo'; ...@@ -4,6 +4,7 @@ import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper'; import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import PipelineStatus, { i18n } from '~/pipeline_editor/components/header/pipeline_status.vue'; import PipelineStatus, { i18n } from '~/pipeline_editor/components/header/pipeline_status.vue';
import getPipelineQuery from '~/pipeline_editor/graphql/queries/client/pipeline.graphql';
import CiIcon from '~/vue_shared/components/ci_icon.vue'; import CiIcon from '~/vue_shared/components/ci_icon.vue';
import { mockCommitSha, mockProjectPipeline, mockProjectFullPath } from '../../mock_data'; import { mockCommitSha, mockProjectPipeline, mockProjectFullPath } from '../../mock_data';
...@@ -19,32 +20,9 @@ describe('Pipeline Status', () => { ...@@ -19,32 +20,9 @@ describe('Pipeline Status', () => {
let mockApollo; let mockApollo;
let mockPipelineQuery; let mockPipelineQuery;
const createComponent = ({ hasPipeline = true, isQueryLoading = false }) => {
const pipeline = hasPipeline
? { loading: isQueryLoading, ...mockProjectPipeline.pipeline }
: { loading: isQueryLoading };
wrapper = shallowMount(PipelineStatus, {
provide: mockProvide,
stubs: { GlLink, GlSprintf },
data: () => (hasPipeline ? { pipeline } : {}),
mocks: {
$apollo: {
queries: {
pipeline,
},
},
},
});
};
const createComponentWithApollo = () => { const createComponentWithApollo = () => {
const resolvers = { const handlers = [[getPipelineQuery, mockPipelineQuery]];
Query: { mockApollo = createMockApollo(handlers);
project: mockPipelineQuery,
},
};
mockApollo = createMockApollo([], resolvers);
wrapper = shallowMount(PipelineStatus, { wrapper = shallowMount(PipelineStatus, {
localVue, localVue,
...@@ -78,16 +56,17 @@ describe('Pipeline Status', () => { ...@@ -78,16 +56,17 @@ describe('Pipeline Status', () => {
wrapper = null; wrapper = null;
}); });
describe('while querying', () => { describe('loading icon', () => {
it('renders loading icon', () => { it('renders while query is being fetched', () => {
createComponent({ isQueryLoading: true, hasPipeline: false }); createComponentWithApollo();
expect(findLoadingIcon().exists()).toBe(true); expect(findLoadingIcon().exists()).toBe(true);
expect(findPipelineLoadingMsg().text()).toBe(i18n.fetchLoading); expect(findPipelineLoadingMsg().text()).toBe(i18n.fetchLoading);
}); });
it('does not render loading icon if pipeline data is already set', () => { it('does not render if query is no longer loading', async () => {
createComponent({ isQueryLoading: true }); createComponentWithApollo();
await waitForPromises();
expect(findLoadingIcon().exists()).toBe(false); expect(findLoadingIcon().exists()).toBe(false);
}); });
...@@ -96,7 +75,9 @@ describe('Pipeline Status', () => { ...@@ -96,7 +75,9 @@ describe('Pipeline Status', () => {
describe('when querying data', () => { describe('when querying data', () => {
describe('when data is set', () => { describe('when data is set', () => {
beforeEach(async () => { beforeEach(async () => {
mockPipelineQuery.mockResolvedValue(mockProjectPipeline); mockPipelineQuery.mockResolvedValue({
data: { project: mockProjectPipeline },
});
createComponentWithApollo(); createComponentWithApollo();
await waitForPromises(); await waitForPromises();
...@@ -104,14 +85,10 @@ describe('Pipeline Status', () => { ...@@ -104,14 +85,10 @@ describe('Pipeline Status', () => {
it('query is called with correct variables', async () => { it('query is called with correct variables', async () => {
expect(mockPipelineQuery).toHaveBeenCalledTimes(1); expect(mockPipelineQuery).toHaveBeenCalledTimes(1);
expect(mockPipelineQuery).toHaveBeenCalledWith( expect(mockPipelineQuery).toHaveBeenCalledWith({
expect.anything(),
{
fullPath: mockProjectFullPath, fullPath: mockProjectFullPath,
}, sha: mockCommitSha,
expect.anything(), });
expect.anything(),
);
}); });
it('does not render error', () => { it('does not render error', () => {
......
...@@ -46,24 +46,6 @@ describe('~/pipeline_editor/graphql/resolvers', () => { ...@@ -46,24 +46,6 @@ describe('~/pipeline_editor/graphql/resolvers', () => {
await expect(result.rawData).resolves.toBe(mockCiYml); await expect(result.rawData).resolves.toBe(mockCiYml);
}); });
}); });
describe('pipeline', () => {
it('resolves pipeline data with type names', async () => {
const result = await resolvers.Query.project(null);
// eslint-disable-next-line no-underscore-dangle
expect(result.__typename).toBe('Project');
});
it('resolves pipeline data with necessary data', async () => {
const result = await resolvers.Query.project(null);
const pipelineKeys = Object.keys(result.pipeline);
const statusKeys = Object.keys(result.pipeline.detailedStatus);
expect(pipelineKeys).toContain('id', 'commitPath', 'detailedStatus', 'shortSha');
expect(statusKeys).toContain('detailsPath', 'text');
});
});
}); });
describe('Mutation', () => { describe('Mutation', () => {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment