Commit d599e22b authored by Paul Gascou-Vaillancourt's avatar Paul Gascou-Vaillancourt Committed by Natalia Tepluhina

Wire up DAST Saved Scans with the API

This updates the frontend so that the following queries and mutations
hit the actual API rather than local mocks:

- dastProfileCreate mutation
- dastProfileUpdate mutation
- dastProfiles query
parent 1b7335b4
---
filenames:
- ee/app/assets/javascripts/on_demand_scans/graphql/dast_scan_create.mutation.graphql
- ee/app/assets/javascripts/oncall_schedules/graphql/mutations/update_oncall_schedule_rotation.mutation.graphql
- ee/app/assets/javascripts/security_configuration/api_fuzzing/graphql/api_fuzzing_ci_configuration.query.graphql
- ee/app/assets/javascripts/on_demand_scans/graphql/dast_profile_update.mutation.graphql
......@@ -35,8 +35,8 @@ import {
TYPE_SITE_PROFILE,
TYPE_SCANNER_PROFILE,
} from '../settings';
import dastScanCreateMutation from '../graphql/dast_scan_create.mutation.graphql';
import dastScanUpdateMutation from '../graphql/dast_scan_update.mutation.graphql';
import dastProfileCreateMutation from '../graphql/dast_profile_create.mutation.graphql';
import dastProfileUpdateMutation from '../graphql/dast_profile_update.mutation.graphql';
import dastOnDemandScanCreateMutation from '../graphql/dast_on_demand_scan_create.mutation.graphql';
import ProfileSelectorSummaryCell from './profile_selector/summary_cell.vue';
import ScannerProfileSelector from './profile_selector/scanner_profile_selector.vue';
......@@ -252,15 +252,15 @@ export default {
this.loading = button;
this.hideErrors();
let mutation = dastOnDemandScanCreateMutation;
let reponseType = 'dastOnDemandScanCreate';
let responseType = 'dastOnDemandScanCreate';
let input = {
fullPath: this.projectPath,
dastScannerProfileId: this.selectedScannerProfile.id,
dastSiteProfileId: this.selectedSiteProfile.id,
};
if (this.glFeatures.dastSavedScans) {
mutation = this.isEdit ? dastScanUpdateMutation : dastScanCreateMutation;
reponseType = this.isEdit ? 'dastScanUpdate' : 'dastScanCreate';
mutation = this.isEdit ? dastProfileUpdateMutation : dastProfileCreateMutation;
responseType = this.isEdit ? 'dastProfileUpdate' : 'dastProfileCreate';
input = {
...input,
...(this.isEdit ? { id: this.dastScan.id } : {}),
......@@ -278,13 +278,13 @@ export default {
},
})
.then(({ data }) => {
const response = data[reponseType];
const response = data[responseType];
const { errors } = response;
if (errors?.length) {
this.showErrors(ERROR_RUN_SCAN, errors);
this.loading = false;
} else if (this.glFeatures.dastSavedScans && !runAfterCreate) {
redirectTo(response.dastScan.editPath);
redirectTo(response.dastProfile.editPath);
} else {
redirectTo(response.pipelineUrl);
}
......
mutation dastProfileCreate($input: DastProfileCreateInput!) {
dastProfileCreate(input: $input) {
dastProfile {
editPath
}
pipelineUrl
errors
}
}
mutation dastProfileUpdate($input: DastProfileUpdateInput!) {
dastProfileUpdate(input: $input) {
dastProfile {
editPath
}
pipelineUrl
errors
}
}
mutation dastScanCreate(
$fullPath: ID!
$name: String!
$description: String
$dastSiteProfileId: DastSiteProfileID!
$dastScannerProfileID: DastScannerProfileID!
$runAfterCreate: Boolean
) {
dastScanCreate(
input: {
fullPath: $fullPath
name: $name
description: $description
dastSiteProfileId: $dastSiteProfileId
dastScannerProfileID: $dastScannerProfileID
runAfterCreate: $runAfterCreate
}
) {
dastScan {
editPath
}
pipelineUrl
errors
}
}
mutation dastScanUpdate(
$id: DastScanID!
$fullPath: ID!
$name: String!
$description: String
$dastSiteProfileId: DastSiteProfileID!
$dastScannerProfileID: DastScannerProfileID!
$runAfterCreate: Boolean
) {
dastScanUpdate(
input: {
id: $id
fullPath: $fullPath
name: $name
description: $description
dastSiteProfileId: $dastSiteProfileId
dastScannerProfileID: $dastScannerProfileID
runAfterCreate: $runAfterCreate
}
) @client {
dastScan {
editPath
}
pipelineUrl
errors
}
}
#import "~/graphql_shared/fragments/pageInfo.fragment.graphql"
query DastSavedScans($fullPath: ID!, $after: String, $before: String, $first: Int, $last: Int) {
project @client {
savedScans(after: $after, before: $before, first: $first, last: $last) {
query DastProfiles($fullPath: ID!, $after: String, $before: String, $first: Int, $last: Int) {
project(fullPath: $fullPath) {
dastProfiles(after: $after, before: $before, first: $first, last: $last) {
pageInfo {
...PageInfo
}
......
/* eslint-disable @gitlab/require-i18n-strings */
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import { range } from 'lodash';
import createDefaultClient from '~/lib/graphql';
Vue.use(VueApollo);
// NOTE: We currently mock some fake DAST scans while the feature is feature-flagged and the
// backend is being worked on.
// This will be cleaned up as part of https://gitlab.com/gitlab-org/gitlab/-/issues/295248.
let id = 0;
const generateFakeDastScan = () => {
id += 1;
return {
node: {
id,
name: `My daily scan #${id}`,
description: 'Tests for SQL injection',
dastSiteProfile: {
id,
targetUrl: 'http://example.com ',
__typename: 'DastSiteProfile',
},
dastScannerProfile: {
id,
scanType: Math.random() < 0.5 ? 'PASSIVE' : 'ACTIVE',
__typename: 'DastScannerProfile',
},
editPath: '/on_demand_scans/1/edit',
__typename: 'DastSavedScan',
},
__typename: 'DastSavedScanEdge',
};
};
const resolvers = {
Query: {
project: () => ({
__typename: 'Project',
savedScans: {
pageInfo: {
hasNextPage: true,
hasPreviousPage: false,
startCursor: 'startCursor',
endCursor: 'endCursor',
__typename: 'PageInfo',
},
edges: range(10).map(generateFakeDastScan),
__typename: 'DastSavedScanConnection',
},
}),
},
};
export default new VueApollo({
defaultClient: createDefaultClient(resolvers, {
assumeImmutableResults: true,
}),
defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
});
import dastSavedScansQuery from 'ee/security_configuration/dast_profiles/graphql/dast_saved_scans.query.graphql';
import dastProfilesQuery from 'ee/security_configuration/dast_profiles/graphql/dast_profiles.query.graphql';
import dastSavedScansDelete from 'ee/security_configuration/dast_profiles/graphql/dast_saved_scans_delete.mutation.graphql';
import dastSiteProfilesQuery from 'ee/security_configuration/dast_profiles/graphql/dast_site_profiles.query.graphql';
import dastSiteProfilesDelete from 'ee/security_configuration/dast_profiles/graphql/dast_site_profiles_delete.mutation.graphql';
......@@ -13,11 +13,11 @@ import { s__ } from '~/locale';
export const getProfileSettings = ({ createNewProfilePaths, isDastSavedScansEnabled }) => ({
...(isDastSavedScansEnabled
? {
savedScans: {
profileType: 'savedScans',
dastProfiles: {
profileType: 'dastProfiles',
createNewProfilePath: createNewProfilePaths.savedScan,
graphQL: {
query: dastSavedScansQuery,
query: dastProfilesQuery,
deletion: {
mutation: dastSavedScansDelete,
optimisticResponse: dastProfilesDeleteResponse({
......
......@@ -6,8 +6,8 @@ import createApolloProvider from 'helpers/mock_apollo_helper';
import OnDemandScansForm from 'ee/on_demand_scans/components/on_demand_scans_form.vue';
import ScannerProfileSelector from 'ee/on_demand_scans/components/profile_selector/scanner_profile_selector.vue';
import SiteProfileSelector from 'ee/on_demand_scans/components/profile_selector/site_profile_selector.vue';
import dastScanCreateMutation from 'ee/on_demand_scans/graphql/dast_scan_create.mutation.graphql';
import dastScanUpdateMutation from 'ee/on_demand_scans/graphql/dast_scan_update.mutation.graphql';
import dastProfileCreateMutation from 'ee/on_demand_scans/graphql/dast_profile_create.mutation.graphql';
import dastProfileUpdateMutation from 'ee/on_demand_scans/graphql/dast_profile_update.mutation.graphql';
import dastOnDemandScanCreateMutation from 'ee/on_demand_scans/graphql/dast_on_demand_scan_create.mutation.graphql';
import dastScannerProfilesQuery from 'ee/security_configuration/dast_profiles/graphql/dast_scanner_profiles.query.graphql';
import dastSiteProfilesQuery from 'ee/security_configuration/dast_profiles/graphql/dast_site_profiles.query.graphql';
......@@ -79,8 +79,8 @@ describe('OnDemandScansForm', () => {
const setupSuccess = ({ edit = false } = {}) => {
jest.spyOn(subject.vm.$apollo, 'mutate').mockResolvedValue({
data: {
[edit ? 'dastScanUpdate' : 'dastScanCreate']: {
dastScan: { editPath },
[edit ? 'dastProfileUpdate' : 'dastProfileCreate']: {
dastProfile: { editPath },
pipelineUrl,
errors: [],
},
......@@ -265,9 +265,9 @@ describe('OnDemandScansForm', () => {
expect(saveButton.props('disabled')).toBe(!saveButtonLoading);
});
it(`triggers dastScanCreateMutation mutation with runAfterCreate set to ${runAfterCreate}`, async () => {
it(`triggers dastProfileCreateMutation mutation with runAfterCreate set to ${runAfterCreate}`, () => {
expect(subject.vm.$apollo.mutate).toHaveBeenCalledWith({
mutation: dastScanCreateMutation,
mutation: dastProfileCreateMutation,
variables: {
input: {
name: 'My daily scan',
......@@ -301,9 +301,9 @@ describe('OnDemandScansForm', () => {
actionFunction();
});
it(`triggers dastScanUpdateMutation mutation with runAfterCreate set to ${runAfterCreate}`, async () => {
it(`triggers dastProfileUpdateMutation mutation with runAfterCreate set to ${runAfterCreate}`, async () => {
expect(subject.vm.$apollo.mutate).toHaveBeenCalledWith({
mutation: dastScanUpdateMutation,
mutation: dastProfileUpdateMutation,
variables: {
input: {
id: 1,
......@@ -356,7 +356,7 @@ describe('OnDemandScansForm', () => {
mountShallowSubject();
jest
.spyOn(subject.vm.$apollo, 'mutate')
.mockResolvedValue({ data: { dastScanCreate: { pipelineUrl: null, errors } } });
.mockResolvedValue({ data: { dastProfileCreate: { pipelineUrl: null, errors } } });
await setValidFormData();
submitForm();
});
......
......@@ -26,7 +26,7 @@ describe('EE - DastProfiles', () => {
const defaultMocks = {
$apollo: {
queries: {
savedScans: {
dastProfiles: {
fetchMore: jest.fn().mockResolvedValue(),
},
siteProfiles: {
......@@ -139,7 +139,7 @@ describe('EE - DastProfiles', () => {
describe.each`
tabName | index | givenLocationHash
${'Saved Scans'} | ${0} | ${'saved-scans'}
${'Saved Scans'} | ${0} | ${'dast-profiles'}
${'Site Profiles'} | ${1} | ${'site-profiles'}
${'Scanner Profiles'} | ${2} | ${'scanner-profiles'}
`('with location hash set to "$givenLocationHash"', ({ tabName, index, givenLocationHash }) => {
......@@ -173,7 +173,7 @@ describe('EE - DastProfiles', () => {
describe.each`
description | profileType
${'Saved Scans List'} | ${'savedScans'}
${'Saved Scans List'} | ${'dastProfiles'}
${'Site Profiles List'} | ${'siteProfiles'}
${'Scanner Profiles List'} | ${'scannerProfiles'}
`('$description', ({ profileType }) => {
......
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