Commit 375b2298 authored by David O'Regan's avatar David O'Regan

Merge branch 'djadmin-site-profile-composable' into 'master'

Make site profile form composable

See merge request gitlab-org/gitlab!57455
parents 2f8f6bab 1787a3d5
...@@ -10,7 +10,7 @@ export const returnToPreviousPageFactory = ({ ...@@ -10,7 +10,7 @@ export const returnToPreviousPageFactory = ({
onDemandScansPath, onDemandScansPath,
profilesLibraryPath, profilesLibraryPath,
urlParamKey, urlParamKey,
}) => (gid) => { }) => ({ id } = {}) => {
// when previous page is not On-demand scans page // when previous page is not On-demand scans page
// redirect user to profiles library page // redirect user to profiles library page
if (!document.referrer?.includes(onDemandScansPath)) { if (!document.referrer?.includes(onDemandScansPath)) {
...@@ -20,9 +20,9 @@ export const returnToPreviousPageFactory = ({ ...@@ -20,9 +20,9 @@ export const returnToPreviousPageFactory = ({
// Otherwise, redirect them back to On-demand scans page // Otherwise, redirect them back to On-demand scans page
// with corresponding profile id, if available // with corresponding profile id, if available
// for example, /on_demand_scans?site_profile_id=35 // for example, /on_demand_scans?site_profile_id=35
const previousPagePath = gid const previousPagePath = id
? setUrlParams( ? setUrlParams(
{ [urlParamKey]: getIdFromGraphQLId(gid) }, { [urlParamKey]: getIdFromGraphQLId(id) },
relativePathToAbsolute(onDemandScansPath, getBaseURL()), relativePathToAbsolute(onDemandScansPath, getBaseURL()),
) )
: onDemandScansPath; : onDemandScansPath;
......
...@@ -11,7 +11,6 @@ import { ...@@ -11,7 +11,6 @@ import {
} from '@gitlab/ui'; } from '@gitlab/ui';
import * as Sentry from '@sentry/browser'; import * as Sentry from '@sentry/browser';
import { isEqual } from 'lodash'; import { isEqual } from 'lodash';
import { returnToPreviousPageFactory } from 'ee/security_configuration/dast_profiles/redirect';
import { initFormField } from 'ee/security_configuration/utils'; import { initFormField } from 'ee/security_configuration/utils';
import { serializeFormObject } from '~/lib/utils/forms'; import { serializeFormObject } from '~/lib/utils/forms';
import { __, s__, n__, sprintf } from '~/locale'; import { __, s__, n__, sprintf } from '~/locale';
...@@ -50,19 +49,16 @@ export default { ...@@ -50,19 +49,16 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
profilesLibraryPath: {
type: String,
required: true,
},
onDemandScansPath: {
type: String,
required: true,
},
siteProfile: { siteProfile: {
type: Object, type: Object,
required: false, required: false,
default: null, default: null,
}, },
showHeader: {
type: Boolean,
required: false,
default: true,
},
}, },
data() { data() {
const { name = '', targetUrl = '', excludedUrls = [], auth = {} } = this.siteProfile || {}; const { name = '', targetUrl = '', excludedUrls = [], auth = {} } = this.siteProfile || {};
...@@ -96,11 +92,6 @@ export default { ...@@ -96,11 +92,6 @@ export default {
token: null, token: null,
errorMessage: '', errorMessage: '',
errors: [], errors: [],
returnToPreviousPage: returnToPreviousPageFactory({
onDemandScansPath: this.onDemandScansPath,
profilesLibraryPath: this.profilesLibraryPath,
urlParamKey: 'site_profile_id',
}),
}; };
}, },
computed: { computed: {
...@@ -216,7 +207,9 @@ export default { ...@@ -216,7 +207,9 @@ export default {
this.showErrors({ message: errorMessage, errors }); this.showErrors({ message: errorMessage, errors });
this.isLoading = false; this.isLoading = false;
} else { } else {
this.returnToPreviousPage(id); this.$emit('success', {
id,
});
} }
}, },
) )
...@@ -234,7 +227,7 @@ export default { ...@@ -234,7 +227,7 @@ export default {
} }
}, },
discard() { discard() {
this.returnToPreviousPage(); this.$emit('cancel');
}, },
captureException(exception) { captureException(exception) {
Sentry.captureException(exception); Sentry.captureException(exception);
...@@ -265,7 +258,7 @@ export default { ...@@ -265,7 +258,7 @@ export default {
<template> <template>
<gl-form novalidate @submit.prevent="onSubmit"> <gl-form novalidate @submit.prevent="onSubmit">
<h2 class="gl-mb-6"> <h2 v-if="showHeader" class="gl-mb-6">
{{ i18n.title }} {{ i18n.title }}
</h2> </h2>
......
import Vue from 'vue'; import Vue from 'vue';
import { returnToPreviousPageFactory } from 'ee/security_configuration/dast_profiles/redirect';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import DastSiteProfileForm from './components/dast_site_profile_form.vue'; import DastSiteProfileForm from './components/dast_site_profile_form.vue';
import apolloProvider from './graphql/provider'; import apolloProvider from './graphql/provider';
...@@ -13,14 +14,18 @@ export default () => { ...@@ -13,14 +14,18 @@ export default () => {
const props = { const props = {
fullPath, fullPath,
profilesLibraryPath,
onDemandScansPath,
}; };
if (el.dataset.siteProfile) { if (el.dataset.siteProfile) {
props.siteProfile = convertObjectPropsToCamelCase(JSON.parse(el.dataset.siteProfile)); props.siteProfile = convertObjectPropsToCamelCase(JSON.parse(el.dataset.siteProfile));
} }
const factoryParams = {
onDemandScansPath,
profilesLibraryPath,
urlParamKey: 'site_profile_id',
};
// eslint-disable-next-line no-new // eslint-disable-next-line no-new
new Vue({ new Vue({
el, el,
...@@ -28,6 +33,10 @@ export default () => { ...@@ -28,6 +33,10 @@ export default () => {
render(h) { render(h) {
return h(DastSiteProfileForm, { return h(DastSiteProfileForm, {
props, props,
on: {
success: returnToPreviousPageFactory(factoryParams),
cancel: returnToPreviousPageFactory(factoryParams),
},
}); });
}, },
}); });
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'User sees Scanner profile' do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :repository) }
let(:profile_form_path) {new_project_security_configuration_dast_scans_dast_site_profile_path(project)}
let(:profile_library_path) { project_security_configuration_dast_scans_path(project) }
before_all do
project.add_developer(user)
end
before do
sign_in(user)
end
context 'when feature is available' do
before do
stub_licensed_features(security_on_demand_scans: true)
visit(profile_form_path)
end
it 'shows the form' do
expect(page).to have_gitlab_http_status(:ok)
expect(page).to have_content("New site profile")
end
it 'on submit', :js do
fill_in_profile_form
expect(current_path).to eq(profile_library_path)
end
it 'on cancel', :js do
click_button 'Cancel'
expect(current_path).to eq(profile_library_path)
end
end
context 'when feature is not available' do
before do
visit(profile_form_path)
end
it 'renders a 404' do
expect(page).to have_gitlab_http_status(:not_found)
end
end
def fill_in_profile_form
fill_in 'profileName', with: "hello"
fill_in 'targetUrl', with: "https://example.com"
click_button 'Save profile'
wait_for_requests
end
end
...@@ -53,7 +53,7 @@ describe('DAST Profiles redirector', () => { ...@@ -53,7 +53,7 @@ describe('DAST Profiles redirector', () => {
}); });
it('redirects to previous page with id', () => { it('redirects to previous page with id', () => {
factory(2); factory({ id: 2 });
expect(urlUtility.redirectTo).toHaveBeenCalledWith( expect(urlUtility.redirectTo).toHaveBeenCalledWith(
`${onDemandScansPath}?site_profile_id=2`, `${onDemandScansPath}?site_profile_id=2`,
); );
......
...@@ -13,7 +13,6 @@ import * as responses from 'ee_jest/security_configuration/dast_site_profiles_fo ...@@ -13,7 +13,6 @@ import * as responses from 'ee_jest/security_configuration/dast_site_profiles_fo
import { TEST_HOST } from 'helpers/test_constants'; import { TEST_HOST } from 'helpers/test_constants';
import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import * as urlUtility from '~/lib/utils/url_utility';
const localVue = createLocalVue(); const localVue = createLocalVue();
localVue.use(VueApollo); localVue.use(VueApollo);
...@@ -134,7 +133,18 @@ describe('DastSiteProfileForm', () => { ...@@ -134,7 +133,18 @@ describe('DastSiteProfileForm', () => {
it('renders properly', () => { it('renders properly', () => {
createComponent(); createComponent();
expect(wrapper.html()).not.toBe(''); expect(findForm().exists()).toBe(true);
expect(findForm().text()).toContain('New site profile');
});
it('when showHeader prop is disabled', () => {
createComponent({
propsData: {
...defaultProps,
showHeader: false,
},
});
expect(findForm().text()).not.toContain('New site profile');
}); });
describe('target URL input', () => { describe('target URL input', () => {
...@@ -215,8 +225,6 @@ describe('DastSiteProfileForm', () => { ...@@ -215,8 +225,6 @@ describe('DastSiteProfileForm', () => {
siteProfile, siteProfile,
}, },
}); });
jest.spyOn(urlUtility, 'redirectTo').mockImplementation();
}); });
it('sets the correct title', () => { it('sets the correct title', () => {
...@@ -260,8 +268,10 @@ describe('DastSiteProfileForm', () => { ...@@ -260,8 +268,10 @@ describe('DastSiteProfileForm', () => {
}); });
}); });
it('redirects to the profiles library', () => { it('emits success event with correct params', () => {
expect(urlUtility.redirectTo).toHaveBeenCalledWith(profilesLibraryPath); expect(wrapper.emitted('success')).toBeTruthy();
expect(wrapper.emitted('success')).toHaveLength(1);
expect(wrapper.emitted('success')[0]).toStrictEqual([{ id: '3083' }]);
}); });
it('does not show an alert', () => { it('does not show an alert', () => {
...@@ -319,9 +329,9 @@ describe('DastSiteProfileForm', () => { ...@@ -319,9 +329,9 @@ describe('DastSiteProfileForm', () => {
describe('cancellation', () => { describe('cancellation', () => {
describe('form unchanged', () => { describe('form unchanged', () => {
it('redirects to the profiles library', () => { it('emits cancel event', () => {
findCancelButton().vm.$emit('click'); findCancelButton().vm.$emit('click');
expect(urlUtility.redirectTo).toHaveBeenCalledWith(profilesLibraryPath); expect(wrapper.emitted('cancel')).toBeTruthy();
}); });
}); });
...@@ -337,9 +347,9 @@ describe('DastSiteProfileForm', () => { ...@@ -337,9 +347,9 @@ describe('DastSiteProfileForm', () => {
expect(findCancelModal().vm.show).toHaveBeenCalled(); expect(findCancelModal().vm.show).toHaveBeenCalled();
}); });
it('redirects to the profiles library if confirmed', () => { it('emits cancel event', () => {
findCancelModal().vm.$emit('ok'); findCancelModal().vm.$emit('ok');
expect(urlUtility.redirectTo).toHaveBeenCalledWith(profilesLibraryPath); expect(wrapper.emitted('cancel')).toBeTruthy();
}); });
}); });
}); });
......
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