Commit 860aa1a0 authored by Andrew Fontaine's avatar Andrew Fontaine

Merge branch '328481-pipelines-artifact-download-part-2' into 'master'

Part 2 - Artifact download migration to graphql

See merge request gitlab-org/gitlab!61169
parents e158b122 656335f5
query securityReportDownloadPaths(
$projectPath: ID!
$iid: String!
$reportTypes: [SecurityReportTypeEnum!]
) {
project(fullPath: $projectPath) {
mergeRequest(iid: $iid) {
headPipeline {
id
jobs(securityReportTypes: $reportTypes) {
nodes {
name
artifacts {
nodes {
downloadPath
fileType
}
}
}
}
}
}
}
}
......@@ -13,7 +13,7 @@ import {
REPORT_TYPE_SECRET_DETECTION,
reportTypeToSecurityReportTypeEnum,
} from './constants';
import securityReportDownloadPathsQuery from './queries/security_report_download_paths.query.graphql';
import securityReportMergeRequestDownloadPathsQuery from './queries/security_report_merge_request_download_paths.query.graphql';
import store from './store';
import { MODULE_SAST, MODULE_SECRET_DETECTION } from './store/constants';
import { extractSecurityReportArtifactsFromMergeRequest } from './utils';
......@@ -86,7 +86,7 @@ export default {
},
apollo: {
reportArtifacts: {
query: securityReportDownloadPathsQuery,
query: securityReportMergeRequestDownloadPathsQuery,
variables() {
return {
projectPath: this.targetProjectFullPath,
......
......@@ -48,7 +48,7 @@ export default {
/>
<div class="gl-display-flex ml-lg-auto p-2">
<slot name="buttons"></slot>
<div class="pl-md-6">
<div class="pl-md-6 gl-pt-1">
<gl-toggle v-model="hideDismissed" :label="$options.i18n.toggleLabel" />
</div>
</div>
......
<script>
import { GlButton, GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { s__ } from '~/locale';
export default {
i18n: {
FUZZING_ARTIFACTS: s__('SecurityReports|Fuzzing artifacts'),
},
components: {
GlButton,
GlDropdown,
GlDropdownItem,
},
props: {
jobs: {
type: Array,
required: true,
},
projectId: {
type: Number,
required: true,
},
},
computed: {
hasDropdown() {
return this.jobs.length > 1;
},
},
methods: {
artifactDownloadUrl(job) {
return `/api/v4/projects/${this.projectId}/jobs/artifacts/${
job.ref
}/download?job=${encodeURIComponent(job.name)}`;
},
},
};
</script>
<template>
<div>
<slot name="label"></slot>
<gl-dropdown
v-if="hasDropdown"
class="d-block mt-1"
:text="$options.i18n.FUZZING_ARTIFACTS"
category="secondary"
size="small"
>
<gl-dropdown-item v-for="job in jobs" :key="job.id" :href="artifactDownloadUrl(job)">{{
job.name
}}</gl-dropdown-item>
</gl-dropdown>
<gl-button
v-else
class="d-block mt-1"
category="secondary"
size="small"
:href="artifactDownloadUrl(jobs[0])"
>
{{ $options.i18n.FUZZING_ARTIFACTS }}
</gl-button>
</div>
</template>
......@@ -89,6 +89,8 @@ export default {
:vulnerabilities-endpoint="vulnerabilitiesEndpoint"
:lock-to-project="{ id: projectId }"
:pipeline-id="pipeline.id"
:pipeline-iid="pipeline.iid"
:project-full-path="projectFullPath"
:loading-error-illustrations="loadingErrorIllustrations"
:security-report-summary="securityReportSummary"
>
......
<script>
import { mapActions, mapState, mapGetters } from 'vuex';
import PipelineArtifactDownload from 'ee/vue_shared/security_reports/components/artifact_downloads/pipeline_artifact_download.vue';
import IssueModal from 'ee/vue_shared/security_reports/components/modal.vue';
import { securityReportTypeEnumToReportType } from 'ee/vue_shared/security_reports/constants';
import { vulnerabilityModalMixin } from 'ee/vue_shared/security_reports/mixins/vulnerability_modal_mixin';
import Filters from './filters.vue';
import FuzzingArtifactsDownload from './fuzzing_artifacts_download.vue';
import LoadingError from './loading_error.vue';
import SecurityDashboardLayout from './security_dashboard_layout.vue';
import SecurityDashboardTable from './security_dashboard_table.vue';
......@@ -14,8 +15,8 @@ export default {
IssueModal,
SecurityDashboardLayout,
SecurityDashboardTable,
FuzzingArtifactsDownload,
LoadingError,
PipelineArtifactDownload,
},
mixins: [vulnerabilityModalMixin('vulnerabilities')],
props: {
......@@ -23,11 +24,20 @@ export default {
type: String,
required: true,
},
projectFullPath: {
type: String,
required: true,
},
pipelineId: {
type: Number,
required: false,
default: null,
},
pipelineIid: {
type: Number,
required: false,
default: null,
},
loadingErrorIllustrations: {
type: Object,
required: false,
......@@ -46,7 +56,9 @@ export default {
...mapState('pipelineJobs', ['projectId']),
...mapState('filters', ['filters']),
...mapGetters('vulnerabilities', ['loadingVulnerabilitiesFailedWithRecognizedErrorCode']),
...mapGetters('pipelineJobs', ['hasFuzzingArtifacts', 'fuzzingJobsWithArtifact']),
shouldShowDownloadGuidance() {
return this.projectFullPath && this.pipelineIid;
},
canCreateIssue() {
const path = this.vulnerability.create_vulnerability_feedback_issue_path;
return Boolean(path);
......@@ -83,6 +95,9 @@ export default {
...mapActions('pipelineJobs', ['fetchPipelineJobs']),
...mapActions('filters', ['lockFilter', 'setHideDismissedToggleInitialState']),
},
reportTypes: {
COVERAGE_FUZZING: [securityReportTypeEnumToReportType.COVERAGE_FUZZING],
},
};
</script>
......@@ -97,12 +112,17 @@ export default {
<security-dashboard-layout>
<template #header>
<filters>
<template v-if="hasFuzzingArtifacts" #buttons>
<fuzzing-artifacts-download :jobs="fuzzingJobsWithArtifact" :project-id="projectId">
<template v-if="shouldShowDownloadGuidance" #buttons>
<pipeline-artifact-download
class="gl-display-flex gl-flex-direction-column gl-align-self-center"
:report-types="$options.reportTypes.COVERAGE_FUZZING"
:target-project-full-path="projectFullPath"
:pipeline-iid="pipelineIid"
>
<template #label>
<strong>{{ s__('SecurityReports|Download Report') }}</strong>
<strong class="gl-mb-2">{{ s__('SecurityReports|Coverage fuzzing') }}</strong>
</template>
</fuzzing-artifacts-download>
</pipeline-artifact-download>
</template>
</filters>
</template>
......
<script>
import { reportTypeToSecurityReportTypeEnum } from 'ee/vue_shared/security_reports/constants';
import createFlash from '~/flash';
import { s__ } from '~/locale';
import SecurityReportDownloadDropdown from '~/vue_shared/security_reports/components/security_report_download_dropdown.vue';
import securityReportDownloadPathsQuery from '~/vue_shared/security_reports/queries/security_report_download_paths.query.graphql';
import { extractSecurityReportArtifactsFromMergeRequest } from '~/vue_shared/security_reports/utils';
export default {
components: {
SecurityReportDownloadDropdown,
},
props: {
reportTypes: {
type: Array,
required: true,
validator: (reportType) => {
return reportType.every((report) => reportTypeToSecurityReportTypeEnum[report]);
},
},
targetProjectFullPath: {
type: String,
required: true,
},
mrIid: {
type: Number,
required: true,
},
},
data() {
return {
reportArtifacts: [],
};
},
apollo: {
reportArtifacts: {
query: securityReportDownloadPathsQuery,
variables() {
return {
projectPath: this.targetProjectFullPath,
iid: String(this.mrIid),
reportTypes: this.reportTypes.map(
(reportType) => reportTypeToSecurityReportTypeEnum[reportType],
),
};
},
update(data) {
return extractSecurityReportArtifactsFromMergeRequest(this.reportTypes, data);
},
error(error) {
this.showError(error);
},
},
},
computed: {
isLoadingReportArtifacts() {
return this.$apollo.queries.reportArtifacts.loading;
},
},
methods: {
showError(error) {
createFlash({
message: this.$options.i18n.apiError,
captureError: true,
error,
});
},
},
i18n: {
apiError: s__(
'SecurityReports|Failed to get security report information. Please reload the page or try again later.',
),
},
};
</script>
<template>
<security-report-download-dropdown
:artifacts="reportArtifacts"
:loading="isLoadingReportArtifacts"
/>
</template>
......@@ -3,7 +3,7 @@ import { reportTypeToSecurityReportTypeEnum } from 'ee/vue_shared/security_repor
import createFlash from '~/flash';
import { s__ } from '~/locale';
import SecurityReportDownloadDropdown from '~/vue_shared/security_reports/components/security_report_download_dropdown.vue';
import securityReportDownloadPathsQuery from '~/vue_shared/security_reports/queries/security_report_mr_download_paths.query.graphql';
import securityReportMergeRequestDownloadPathsQuery from '~/vue_shared/security_reports/queries/security_report_merge_request_download_paths.query.graphql';
import { extractSecurityReportArtifactsFromMergeRequest } from '~/vue_shared/security_reports/utils';
export default {
......@@ -34,7 +34,7 @@ export default {
},
apollo: {
reportArtifacts: {
query: securityReportDownloadPathsQuery,
query: securityReportMergeRequestDownloadPathsQuery,
variables() {
return {
projectPath: this.targetProjectFullPath,
......
......@@ -3,7 +3,7 @@ import { reportTypeToSecurityReportTypeEnum } from 'ee/vue_shared/security_repor
import createFlash from '~/flash';
import { s__ } from '~/locale';
import SecurityReportDownloadDropdown from '~/vue_shared/security_reports/components/security_report_download_dropdown.vue';
import securityReportDownloadPathsQuery from '~/vue_shared/security_reports/queries/security_report_pipeline_download_paths.query.graphql';
import securityReportPipelineDownloadPathsQuery from '~/vue_shared/security_reports/queries/security_report_pipeline_download_paths.query.graphql';
import { extractSecurityReportArtifactsFromPipeline } from '~/vue_shared/security_reports/utils';
export default {
......@@ -34,11 +34,11 @@ export default {
},
apollo: {
reportArtifacts: {
query: securityReportDownloadPathsQuery,
query: securityReportPipelineDownloadPathsQuery,
variables() {
return {
projectPath: this.targetProjectFullPath,
iid: String(this.mrIid),
iid: String(this.pipelineIid),
reportTypes: this.reportTypes.map(
(reportType) => reportTypeToSecurityReportTypeEnum[reportType],
),
......@@ -75,8 +75,11 @@ export default {
</script>
<template>
<security-report-download-dropdown
:artifacts="reportArtifacts"
:loading="isLoadingReportArtifacts"
/>
<div>
<slot name="label"></slot>
<security-report-download-dropdown
:artifacts="reportArtifacts"
:loading="isLoadingReportArtifacts"
/>
</div>
</template>
......@@ -3,7 +3,6 @@ import { GlButton, GlSprintf, GlLink, GlModalDirective } from '@gitlab/ui';
import { once } from 'lodash';
import { mapActions, mapState, mapGetters } from 'vuex';
import { componentNames } from 'ee/reports/components/issue_body';
import FuzzingArtifactsDownload from 'ee/security_dashboard/components/fuzzing_artifacts_download.vue';
import { fetchPolicies } from '~/lib/graphql';
import { mrStates } from '~/mr_popover/constants';
import GroupedIssuesList from '~/reports/components/grouped_issues_list.vue';
......@@ -12,7 +11,7 @@ import SummaryRow from '~/reports/components/summary_row.vue';
import { LOADING } from '~/reports/constants';
import Tracking from '~/tracking';
import SecuritySummary from '~/vue_shared/security_reports/components/security_summary.vue';
import ArtifactDownload from './components/artifact_download.vue';
import MrArtifactDownload from './components/artifact_downloads/merge_request_artifact_download.vue';
import DastModal from './components/dast_modal.vue';
import IssueModal from './components/modal.vue';
import { securityReportTypeEnumToReportType } from './constants';
......@@ -34,7 +33,7 @@ import {
export default {
store: createStore(),
components: {
ArtifactDownload,
MrArtifactDownload,
GroupedIssuesList,
ReportSection,
SummaryRow,
......@@ -44,7 +43,6 @@ export default {
GlLink,
DastModal,
GlButton,
FuzzingArtifactsDownload,
},
directives: {
'gl-modal': GlModalDirective,
......@@ -277,7 +275,6 @@ export default {
'secretDetectionStatusIcon',
]),
...mapGetters(MODULE_API_FUZZING, ['groupedApiFuzzingText', 'apiFuzzingStatusIcon']),
...mapGetters('pipelineJobs', ['hasFuzzingArtifacts', 'fuzzingJobsWithArtifact']),
securityTab() {
return `${this.pipelinePath}/security`;
},
......@@ -447,7 +444,10 @@ export default {
},
},
summarySlots: ['success', 'error', 'loading'],
reportTypes: securityReportTypeEnumToReportType,
reportTypes: {
API_FUZZING: [securityReportTypeEnumToReportType.API_FUZZING],
COVERAGE_FUZZING: [securityReportTypeEnumToReportType.COVERAGE_FUZZING],
},
};
</script>
<template>
......@@ -651,10 +651,11 @@ export default {
<template #summary>
<security-summary :message="groupedCoverageFuzzingText" />
</template>
<fuzzing-artifacts-download
v-if="hasFuzzingArtifacts"
:jobs="fuzzingJobsWithArtifact"
:project-id="projectId"
<mr-artifact-download
v-if="shouldShowDownloadGuidance"
:report-types="$options.reportTypes.COVERAGE_FUZZING"
:target-project-full-path="targetProjectFullPath"
:mr-iid="mrIid"
/>
</summary-row>
......@@ -680,9 +681,9 @@ export default {
<security-summary :message="groupedApiFuzzingText" />
</template>
<artifact-download
<mr-artifact-download
v-if="shouldShowDownloadGuidance"
:report-types="[$options.reportTypes.API_FUZZING]"
:report-types="$options.reportTypes.API_FUZZING"
:target-project-full-path="targetProjectFullPath"
:mr-iid="mrIid"
/>
......
---
title: Artifact download migration to graphql
merge_request: 61169
author:
type: changed
import { GlButton, GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import FuzzingArtifactsDownload from 'ee/security_dashboard/components/fuzzing_artifacts_download.vue';
import createStore from 'ee/security_dashboard/store';
const localVue = createLocalVue();
localVue.use(Vuex);
describe('Filter component', () => {
const projectId = 1;
const jobs = [
{ ref: 'main', name: 'fuzz' },
{ ref: 'main', name: 'fuzz 2' },
];
let wrapper;
let store;
const createWrapper = (props = {}) => {
wrapper = shallowMount(FuzzingArtifactsDownload, {
localVue,
store,
propsData: {
projectId,
...props,
},
});
};
beforeEach(() => {
store = createStore();
});
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
describe('with one fuzzing job with artifacts', () => {
beforeEach(() => {
createWrapper({ jobs: [jobs[0]] });
});
it('should render a download button', () => {
expect(wrapper.find(GlButton).exists()).toBe(true);
expect(wrapper.find(GlDropdown).exists()).toBe(false);
});
it('should render with href set to the correct filepath', () => {
const href = `/api/v4/projects/${projectId}/jobs/artifacts/${
jobs[0].ref
}/download?job=${encodeURIComponent(jobs[0].name)}`;
expect(wrapper.find(GlButton).attributes('href')).toBe(href);
});
});
describe('with several fuzzing jobs with artifacts', () => {
beforeEach(() => {
createWrapper({ jobs });
});
it('should render a dropdown button with several items', () => {
expect(wrapper.find(GlButton).exists()).toBe(false);
expect(wrapper.find(GlDropdown).exists()).toBe(true);
expect(wrapper.findAll(GlDropdownItem).length).toBe(2);
});
it('should render with href set to the correct filepath for every element', () => {
const wrapperArray = wrapper.findAll(GlDropdownItem);
wrapperArray.wrappers.forEach((_, index) => {
const href = `/api/v4/projects/${projectId}/jobs/artifacts/${
jobs[index].ref
}/download?job=${encodeURIComponent(jobs[index].name)}`;
expect(wrapperArray.at(index).attributes().href).toBe(href);
});
});
});
});
......@@ -52,6 +52,7 @@ describe('Security Dashboard component', () => {
},
propsData: {
dashboardDocumentation: '',
projectFullPath: '/path',
vulnerabilitiesEndpoint,
pipelineId,
...props,
......
// import createState from 'ee/security_dashboard/store/modules/pipeline_jobs/state';
import { FUZZING_STAGE } from 'ee/security_dashboard/store/modules/pipeline_jobs/constants';
import * as getters from 'ee/security_dashboard/store/modules/pipeline_jobs/getters';
describe('pipeline jobs module getters', () => {
describe('hasFuzzingArtifacts', () => {
it('should return true when the pipeline has at least one fuzzing job with at least one artifact', () => {
const pipelineJobs = [{ stage: FUZZING_STAGE, artifacts: [{}] }];
const state = { pipelineJobs };
const result = getters.hasFuzzingArtifacts(state);
expect(result).toBe(true);
});
it('should return true when the pipeline has many jobs and at least one fuzzing job with at least one artifact', () => {
const pipelineJobs = [
{ stage: 'other', artifacts: [] },
{ stage: FUZZING_STAGE, artifacts: [{}] },
];
const state = { pipelineJobs };
const result = getters.hasFuzzingArtifacts(state);
expect(result).toBe(true);
});
it('should return false when the pipeline has a fuzzing job with 0 artifacts', () => {
const pipelineJobs = [{ stage: FUZZING_STAGE, artifacts: [] }];
const state = { pipelineJobs };
const result = getters.hasFuzzingArtifacts(state);
expect(result).toBe(false);
});
it('should return false when the pipeline has no fuzzing job with 0 artifacts', () => {
const pipelineJobs = [{ stage: 'other', artifacts: [] }];
const state = { pipelineJobs };
const result = getters.hasFuzzingArtifacts(state);
expect(result).toBe(false);
});
it('should return false when the pipeline has no fuzzing job with 1 artifacts', () => {
const pipelineJobs = [{ stage: 'other', artifacts: [{}] }];
const state = { pipelineJobs };
const result = getters.hasFuzzingArtifacts(state);
expect(result).toBe(false);
});
it('should return false when the pipeline has many jobs and at least one fuzzing job with no fuzzing artifact', () => {
const pipelineJobs = [
{ stage: 'other', artifacts: [] },
{ stage: FUZZING_STAGE, artifacts: [] },
];
const state = { pipelineJobs };
const result = getters.hasFuzzingArtifacts(state);
expect(result).toBe(false);
});
});
describe('fuzzingJobsWithArtifact', () => {
it('should return a fuzzing job when the pipeline has at least one fuzzing job with at least one artifact', () => {
const pipelineJobs = [{ stage: FUZZING_STAGE, artifacts: [{}] }];
const state = { pipelineJobs };
const result = getters.fuzzingJobsWithArtifact(state);
expect(result).toEqual(pipelineJobs);
});
it('should return a fuzzing job when the pipeline has many jobs and at least one fuzzing job with at least one artifact', () => {
const pipelineJobs = [
{ stage: 'other', artifacts: [] },
{ stage: FUZZING_STAGE, artifacts: [{}] },
];
const state = { pipelineJobs };
const result = getters.fuzzingJobsWithArtifact(state);
expect(result).toEqual([pipelineJobs[1]]);
});
it('should not return a fuzzing job when the pipeline has a fuzzing job with 0 artifacts', () => {
const pipelineJobs = [{ stage: FUZZING_STAGE, artifacts: [] }];
const state = { pipelineJobs };
const result = getters.fuzzingJobsWithArtifact(state);
expect(result).toEqual([]);
});
it('should not return a fuzzing job when the pipeline has no fuzzing job with 0 artifacts', () => {
const pipelineJobs = [{ stage: 'other', artifacts: [] }];
const state = { pipelineJobs };
const result = getters.fuzzingJobsWithArtifact(state);
expect(result).toEqual([]);
});
it('should not return a fuzzing job when the pipeline has no fuzzing job with 1 artifacts', () => {
const pipelineJobs = [{ stage: 'other', artifacts: [{}] }];
const state = { pipelineJobs };
const result = getters.fuzzingJobsWithArtifact(state);
expect(result).toEqual([]);
});
it('should not return a fuzzing job when the pipeline has many jobs and at least one fuzzing job with no fuzzing artifact', () => {
const pipelineJobs = [
{ stage: 'other', artifacts: [] },
{ stage: FUZZING_STAGE, artifacts: [] },
];
const state = { pipelineJobs };
const result = getters.fuzzingJobsWithArtifact(state);
expect(result).toEqual([]);
});
});
});
......@@ -29,7 +29,7 @@ import { SUCCESS } from '~/vue_merge_request_widget/components/deployment/consta
// Force Jest to transpile and cache
// eslint-disable-next-line no-unused-vars
import _Deployment from '~/vue_merge_request_widget/components/deployment/deployment.vue';
import securityReportMergeRequestDownloadPathsQuery from '~/vue_shared/security_reports/queries/security_report_mr_download_paths.query.graphql';
import securityReportMergeRequestDownloadPathsQuery from '~/vue_shared/security_reports/queries/security_report_merge_request_download_paths.query.graphql';
import mockData, {
baseBrowserPerformance,
......
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import Component from 'ee/vue_shared/security_reports/components/artifact_download.vue';
import {
REPORT_TYPE_SAST,
REPORT_TYPE_SECRET_DETECTION,
} from 'ee/vue_shared/security_reports/constants';
import createMockApollo from 'helpers/mock_apollo_helper';
import {
expectedDownloadDropdownProps,
securityReportDownloadPathsQueryResponse,
} from 'jest/vue_shared/security_reports/mock_data';
import createFlash from '~/flash';
import SecurityReportDownloadDropdown from '~/vue_shared/security_reports/components/security_report_download_dropdown.vue';
import securityReportDownloadPathsQuery from '~/vue_shared/security_reports/queries/security_report_download_paths.query.graphql';
jest.mock('~/flash');
describe('Artifact Download', () => {
let wrapper;
const defaultProps = {
reportTypes: [REPORT_TYPE_SAST, REPORT_TYPE_SECRET_DETECTION],
targetProjectFullPath: '/path',
mrIid: 123,
};
const createWrapper = ({ propsData, options }) => {
wrapper = shallowMount(Component, {
stubs: {
SecurityReportDownloadDropdown,
},
propsData: {
...defaultProps,
...propsData,
},
...options,
});
};
const pendingHandler = () => new Promise(() => {});
const successHandler = () => Promise.resolve({ data: securityReportDownloadPathsQueryResponse });
const failureHandler = () => Promise.resolve({ errors: [{ message: 'some error' }] });
const createMockApolloProvider = (handler) => {
Vue.use(VueApollo);
const requestHandlers = [[securityReportDownloadPathsQuery, handler]];
return createMockApollo(requestHandlers);
};
const findDownloadDropdown = () => wrapper.find(SecurityReportDownloadDropdown);
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
describe('given the query is loading', () => {
beforeEach(() => {
createWrapper({
options: {
apolloProvider: createMockApolloProvider(pendingHandler),
},
});
});
it('loading is true', () => {
expect(findDownloadDropdown().props('loading')).toBe(true);
});
});
describe('given the query loads successfully', () => {
beforeEach(() => {
createWrapper({
options: {
apolloProvider: createMockApolloProvider(successHandler),
},
});
});
it('renders the download dropdown', () => {
expect(findDownloadDropdown().props()).toEqual(expectedDownloadDropdownProps);
});
});
describe('given the query fails', () => {
beforeEach(() => {
createWrapper({
options: {
apolloProvider: createMockApolloProvider(failureHandler),
},
});
});
it('calls createFlash correctly', () => {
expect(createFlash).toHaveBeenCalledWith({
message: Component.i18n.apiError,
captureError: true,
error: expect.any(Error),
});
});
it('renders nothing', () => {
expect(findDownloadDropdown().props('artifacts')).toEqual([]);
});
});
});
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import Component from 'ee/vue_shared/security_reports/components/artifact_downloads/mr_artifact_download.vue';
import Component from 'ee/vue_shared/security_reports/components/artifact_downloads/merge_request_artifact_download.vue';
import {
REPORT_TYPE_SAST,
REPORT_TYPE_SECRET_DETECTION,
......@@ -13,7 +13,7 @@ import {
} from 'jest/vue_shared/security_reports/mock_data';
import createFlash from '~/flash';
import SecurityReportDownloadDropdown from '~/vue_shared/security_reports/components/security_report_download_dropdown.vue';
import securityReportMergeRequestDownloadPathsQuery from '~/vue_shared/security_reports/queries/security_report_mr_download_paths.query.graphql';
import securityReportMergeRequestDownloadPathsQuery from '~/vue_shared/security_reports/queries/security_report_merge_request_download_paths.query.graphql';
jest.mock('~/flash');
......
......@@ -28867,6 +28867,9 @@ msgstr ""
msgid "SecurityReports|Configure security testing"
msgstr ""
msgid "SecurityReports|Coverage fuzzing"
msgstr ""
msgid "SecurityReports|Create Jira issue"
msgstr ""
......@@ -28885,9 +28888,6 @@ msgstr ""
msgid "SecurityReports|Download %{artifactName}"
msgstr ""
msgid "SecurityReports|Download Report"
msgstr ""
msgid "SecurityReports|Download results"
msgstr ""
......@@ -28909,9 +28909,6 @@ msgstr ""
msgid "SecurityReports|Failed to get security report information. Please reload the page or try again later."
msgstr ""
msgid "SecurityReports|Fuzzing artifacts"
msgstr ""
msgid "SecurityReports|Hide dismissed"
msgstr ""
......
......@@ -3,7 +3,7 @@ import MockAdapter from 'axios-mock-adapter';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import { securityReportDownloadPathsQueryResponse } from 'jest/vue_shared/security_reports/mock_data';
import { securityReportMergeRequestDownloadPathsQueryResponse } from 'jest/vue_shared/security_reports/mock_data';
import axios from '~/lib/utils/axios_utils';
import { setFaviconOverlay } from '~/lib/utils/favicon';
import notify from '~/lib/utils/notify';
......@@ -12,7 +12,7 @@ import { SUCCESS } from '~/vue_merge_request_widget/components/deployment/consta
import eventHub from '~/vue_merge_request_widget/event_hub';
import MrWidgetOptions from '~/vue_merge_request_widget/mr_widget_options.vue';
import { stateKey } from '~/vue_merge_request_widget/stores/state_maps';
import securityReportDownloadPathsQuery from '~/vue_shared/security_reports/queries/security_report_download_paths.query.graphql';
import securityReportMergeRequestDownloadPathsQuery from '~/vue_shared/security_reports/queries/security_report_merge_request_download_paths.query.graphql';
import { faviconDataUrl, overlayDataUrl } from '../lib/utils/mock_data';
import mockData from './mock_data';
......@@ -830,8 +830,8 @@ describe('MrWidgetOptions', () => {
return createComponent(mrData, {
apolloProvider: createMockApollo([
[
securityReportDownloadPathsQuery,
async () => ({ data: securityReportDownloadPathsQueryResponse }),
securityReportMergeRequestDownloadPathsQuery,
async () => ({ data: securityReportMergeRequestDownloadPathsQueryResponse }),
],
]),
});
......
......@@ -322,7 +322,7 @@ export const secretScanningDiffSuccessMock = {
head_report_created_at: '2020-01-10T10:00:00.000Z',
};
export const securityReportDownloadPathsQueryNoArtifactsResponse = {
export const securityReportMergeRequestDownloadPathsQueryNoArtifactsResponse = {
project: {
mergeRequest: {
headPipeline: {
......@@ -447,8 +447,6 @@ export const securityReportMergeRequestDownloadPathsQueryResponse = {
},
};
export const securityReportDownloadPathsQueryResponse = securityReportMergeRequestDownloadPathsQueryResponse;
export const securityReportPipelineDownloadPathsQueryResponse = {
project: {
pipeline: {
......@@ -556,7 +554,7 @@ export const securityReportPipelineDownloadPathsQueryResponse = {
};
/**
* These correspond to SAST jobs in the securityReportDownloadPathsQueryResponse above.
* These correspond to SAST jobs in the securityReportMergeRequestDownloadPathsQueryResponse above.
*/
export const sastArtifacts = [
{
......@@ -572,7 +570,7 @@ export const sastArtifacts = [
];
/**
* These correspond to Secret Detection jobs in the securityReportDownloadPathsQueryResponse above.
* These correspond to Secret Detection jobs in the securityReportMergeRequestDownloadPathsQueryResponse above.
*/
export const secretDetectionArtifacts = [
{
......@@ -589,7 +587,7 @@ export const expectedDownloadDropdownProps = {
};
/**
* These correspond to any jobs with zip archives in the securityReportDownloadPathsQueryResponse above.
* These correspond to any jobs with zip archives in the securityReportMergeRequestDownloadPathsQueryResponse above.
*/
export const archiveArtifacts = [
{
......@@ -600,7 +598,7 @@ export const archiveArtifacts = [
];
/**
* These correspond to any jobs with trace data in the securityReportDownloadPathsQueryResponse above.
* These correspond to any jobs with trace data in the securityReportMergeRequestDownloadPathsQueryResponse above.
*/
export const traceArtifacts = [
{
......@@ -626,7 +624,7 @@ export const traceArtifacts = [
];
/**
* These correspond to any jobs with metadata data in the securityReportDownloadPathsQueryResponse above.
* These correspond to any jobs with metadata data in the securityReportMergeRequestDownloadPathsQueryResponse above.
*/
export const metadataArtifacts = [
{
......
......@@ -9,8 +9,8 @@ import { trimText } from 'helpers/text_helper';
import waitForPromises from 'helpers/wait_for_promises';
import {
expectedDownloadDropdownProps,
securityReportDownloadPathsQueryNoArtifactsResponse,
securityReportDownloadPathsQueryResponse,
securityReportMergeRequestDownloadPathsQueryNoArtifactsResponse,
securityReportMergeRequestDownloadPathsQueryResponse,
sastDiffSuccessMock,
secretScanningDiffSuccessMock,
} from 'jest/vue_shared/security_reports/mock_data';
......@@ -22,7 +22,7 @@ import {
REPORT_TYPE_SAST,
REPORT_TYPE_SECRET_DETECTION,
} from '~/vue_shared/security_reports/constants';
import securityReportDownloadPathsQuery from '~/vue_shared/security_reports/queries/security_report_download_paths.query.graphql';
import securityReportMergeRequestDownloadPathsQuery from '~/vue_shared/security_reports/queries/security_report_merge_request_download_paths.query.graphql';
import SecurityReportsApp from '~/vue_shared/security_reports/security_reports_app.vue';
jest.mock('~/flash');
......@@ -59,12 +59,13 @@ describe('Security reports app', () => {
};
const pendingHandler = () => new Promise(() => {});
const successHandler = () => Promise.resolve({ data: securityReportDownloadPathsQueryResponse });
const successHandler = () =>
Promise.resolve({ data: securityReportMergeRequestDownloadPathsQueryResponse });
const successEmptyHandler = () =>
Promise.resolve({ data: securityReportDownloadPathsQueryNoArtifactsResponse });
Promise.resolve({ data: securityReportMergeRequestDownloadPathsQueryNoArtifactsResponse });
const failureHandler = () => Promise.resolve({ errors: [{ message: 'some error' }] });
const createMockApolloProvider = (handler) => {
const requestHandlers = [[securityReportDownloadPathsQuery, handler]];
const requestHandlers = [[securityReportMergeRequestDownloadPathsQuery, handler]];
return createMockApollo(requestHandlers);
};
......
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