Commit b8592751 authored by Sarah Groff Hennigh-Palermo's avatar Sarah Groff Hennigh-Palermo

Merge branch 'integrate-graphql-with-pipeline-status' into 'master'

Integrate new pipeline query for pipeline editor

See merge request gitlab-org/gitlab!54888
parents da037a99 2087e3e2
<script>
import { GlIcon, GlLink, GlLoadingIcon, GlSprintf } from '@gitlab/ui';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { truncateSha } from '~/lib/utils/text_utility';
import { s__ } from '~/locale';
import getCommitSha from '~/pipeline_editor/graphql/queries/client/commit_sha.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';
const POLL_INTERVAL = 10000;
......@@ -38,13 +40,11 @@ export default {
};
},
update: (data) => {
const { id, commitPath = '', shortSha = '', detailedStatus = {} } =
data.project?.pipeline || {};
const { id, commitPath = '', detailedStatus = {} } = data.project?.pipeline || {};
return {
id,
commitPath,
shortSha,
detailedStatus,
};
},
......@@ -61,24 +61,34 @@ export default {
},
computed: {
hasPipelineData() {
return Boolean(this.$apollo.queries.pipeline?.id);
return Boolean(this.pipeline?.id);
},
isQueryLoading() {
return this.$apollo.queries.pipeline.loading && !this.hasPipelineData;
pipelineId() {
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() {
return this.pipeline.detailedStatus;
},
pipelineId() {
return getIdFromGraphQLId(this.pipeline.id);
},
},
mounted() {
toggleQueryPollingByVisibility(this.$apollo.queries.pipeline, POLL_INTERVAL);
},
};
</script>
<template>
<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" />
<span data-testid="pipeline-loading-msg">{{ $options.i18n.fetchLoading }}</span>
</template>
......@@ -110,7 +120,7 @@ export default {
target="_blank"
data-testid="pipeline-commit"
>
{{ pipeline.shortSha }}
{{ shortSha }}
</gl-link>
</template>
</gl-sprintf>
......
query getPipeline($fullPath: ID!, $sha: String!) {
project(fullPath: $fullPath) @client {
project(fullPath: $fullPath) {
pipeline(sha: $sha) {
commitPath
id
iid
shortSha
status
detailedStatus {
detailsPath
......
......@@ -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: {
lintCI: (_, { endpoint, content, dry_run }) => {
......
......@@ -4,6 +4,7 @@ import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
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 { mockCommitSha, mockProjectPipeline, mockProjectFullPath } from '../../mock_data';
......@@ -19,32 +20,9 @@ describe('Pipeline Status', () => {
let mockApollo;
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 resolvers = {
Query: {
project: mockPipelineQuery,
},
};
mockApollo = createMockApollo([], resolvers);
const handlers = [[getPipelineQuery, mockPipelineQuery]];
mockApollo = createMockApollo(handlers);
wrapper = shallowMount(PipelineStatus, {
localVue,
......@@ -78,16 +56,17 @@ describe('Pipeline Status', () => {
wrapper = null;
});
describe('while querying', () => {
it('renders loading icon', () => {
createComponent({ isQueryLoading: true, hasPipeline: false });
describe('loading icon', () => {
it('renders while query is being fetched', () => {
createComponentWithApollo();
expect(findLoadingIcon().exists()).toBe(true);
expect(findPipelineLoadingMsg().text()).toBe(i18n.fetchLoading);
});
it('does not render loading icon if pipeline data is already set', () => {
createComponent({ isQueryLoading: true });
it('does not render if query is no longer loading', async () => {
createComponentWithApollo();
await waitForPromises();
expect(findLoadingIcon().exists()).toBe(false);
});
......@@ -96,7 +75,9 @@ describe('Pipeline Status', () => {
describe('when querying data', () => {
describe('when data is set', () => {
beforeEach(async () => {
mockPipelineQuery.mockResolvedValue(mockProjectPipeline);
mockPipelineQuery.mockResolvedValue({
data: { project: mockProjectPipeline },
});
createComponentWithApollo();
await waitForPromises();
......@@ -104,14 +85,10 @@ describe('Pipeline Status', () => {
it('query is called with correct variables', async () => {
expect(mockPipelineQuery).toHaveBeenCalledTimes(1);
expect(mockPipelineQuery).toHaveBeenCalledWith(
expect.anything(),
{
fullPath: mockProjectFullPath,
},
expect.anything(),
expect.anything(),
);
expect(mockPipelineQuery).toHaveBeenCalledWith({
fullPath: mockProjectFullPath,
sha: mockCommitSha,
});
});
it('does not render error', () => {
......
......@@ -46,24 +46,6 @@ describe('~/pipeline_editor/graphql/resolvers', () => {
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', () => {
......
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