Commit b21159d5 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch 'jnnkl-secure-config-page-auto-devops-alert' into 'master'

Add Autodevops alert to security Config Page

See merge request gitlab-org/gitlab!65124
parents 1bac5803 423cda68
<script>
import { GlAlert, GlLink, GlSprintf } from '@gitlab/ui';
import { s__ } from '~/locale';
export default {
components: {
GlSprintf,
GlAlert,
GlLink,
},
inject: ['autoDevopsHelpPagePath', 'autoDevopsPath'],
i18n: {
primaryButtonText: s__('SecurityConfiguration|Enable Auto DevOps'),
body: s__(
'SecurityConfiguration|Quickly enable all continuous testing and compliance tools by enabling %{linkStart}Auto DevOps%{linkEnd}',
),
},
methods: {
dismissMethod() {
this.$emit('dismiss');
},
},
};
</script>
<template>
<gl-alert
variant="info"
:primary-button-link="autoDevopsPath"
:primary-button-text="$options.i18n.primaryButtonText"
@dismiss="dismissMethod"
>
<gl-sprintf :message="$options.i18n.body">
<template #link="{ content }">
<gl-link :href="autoDevopsHelpPagePath">
{{ content }}
</gl-link>
</template>
</gl-sprintf>
</gl-alert>
</template>
......@@ -2,6 +2,7 @@
import { GlTab, GlTabs, GlSprintf, GlLink } from '@gitlab/ui';
import { __, s__ } from '~/locale';
import UserCalloutDismisser from '~/vue_shared/components/user_callout_dismisser.vue';
import AutoDevOpsAlert from './auto_dev_ops_alert.vue';
import FeatureCard from './feature_card.vue';
import SectionLayout from './section_layout.vue';
import UpgradeBanner from './upgrade_banner.vue';
......@@ -31,6 +32,7 @@ export default {
FeatureCard,
SectionLayout,
UpgradeBanner,
AutoDevOpsAlert,
UserCalloutDismisser,
},
props: {
......@@ -47,6 +49,16 @@ export default {
required: false,
default: false,
},
autoDevopsEnabled: {
type: Boolean,
required: false,
default: false,
},
canEnableAutoDevops: {
type: Boolean,
required: false,
default: false,
},
gitlabCiHistoryPath: {
type: String,
required: false,
......@@ -67,16 +79,26 @@ export default {
canViewCiHistory() {
return Boolean(this.gitlabCiPresent && this.gitlabCiHistoryPath);
},
shouldShowDevopsAlert() {
return !this.autoDevopsEnabled && !this.gitlabCiPresent && this.canEnableAutoDevops;
},
},
};
</script>
<template>
<article>
<user-callout-dismisser
v-if="shouldShowDevopsAlert"
feature-name="security_configuration_devops_alert"
>
<template #default="{ dismiss, shouldShowCallout }">
<auto-dev-ops-alert v-if="shouldShowCallout" class="gl-mt-3" @dismiss="dismiss" />
</template>
</user-callout-dismisser>
<header>
<h1 class="gl-font-size-h1">{{ $options.i18n.securityConfiguration }}</h1>
</header>
<user-callout-dismisser v-if="canUpgrade" feature-name="security_configuration_upgrade_banner">
<template #default="{ dismiss, shouldShowCallout }">
<upgrade-banner v-if="shouldShowCallout" @close="dismiss" />
......
......@@ -20,6 +20,8 @@ export const initRedesignedSecurityConfiguration = (el) => {
features,
latestPipelinePath,
gitlabCiHistoryPath,
autoDevopsHelpPagePath,
autoDevopsPath,
} = el.dataset;
const { augmentedSecurityFeatures, augmentedComplianceFeatures } = augmentFeatures(
......@@ -34,6 +36,8 @@ export const initRedesignedSecurityConfiguration = (el) => {
provide: {
projectPath,
upgradePath,
autoDevopsHelpPagePath,
autoDevopsPath,
},
render(createElement) {
return createElement(RedesignedSecurityConfigurationApp, {
......@@ -42,7 +46,11 @@ export const initRedesignedSecurityConfiguration = (el) => {
augmentedSecurityFeatures,
latestPipelinePath,
gitlabCiHistoryPath,
...parseBooleanDataAttributes(el, ['gitlabCiPresent']),
...parseBooleanDataAttributes(el, [
'gitlabCiPresent',
'autoDevopsEnabled',
'canEnableAutoDevops',
]),
},
});
},
......
......@@ -34,7 +34,8 @@ class UserCallout < ApplicationRecord
security_configuration_upgrade_banner: 32,
cloud_licensing_subscription_activation_banner: 33, # EE-only
trial_status_reminder_d14: 34, # EE-only
trial_status_reminder_d3: 35 # EE-only
trial_status_reminder_d3: 35, # EE-only
security_configuration_devops_alert: 36 # EE-only
}
validates :user, presence: true
......
......@@ -15290,6 +15290,7 @@ Name of the feature that the callout is for.
| <a id="usercalloutfeaturenameenumpipeline_needs_banner"></a>`PIPELINE_NEEDS_BANNER` | Callout feature name for pipeline_needs_banner. |
| <a id="usercalloutfeaturenameenumpipeline_needs_hover_tip"></a>`PIPELINE_NEEDS_HOVER_TIP` | Callout feature name for pipeline_needs_hover_tip. |
| <a id="usercalloutfeaturenameenumregistration_enabled_callout"></a>`REGISTRATION_ENABLED_CALLOUT` | Callout feature name for registration_enabled_callout. |
| <a id="usercalloutfeaturenameenumsecurity_configuration_devops_alert"></a>`SECURITY_CONFIGURATION_DEVOPS_ALERT` | Callout feature name for security_configuration_devops_alert. |
| <a id="usercalloutfeaturenameenumsecurity_configuration_upgrade_banner"></a>`SECURITY_CONFIGURATION_UPGRADE_BANNER` | Callout feature name for security_configuration_upgrade_banner. |
| <a id="usercalloutfeaturenameenumservice_templates_deprecated_callout"></a>`SERVICE_TEMPLATES_DEPRECATED_CALLOUT` | Callout feature name for service_templates_deprecated_callout. |
| <a id="usercalloutfeaturenameenumsuggest_pipeline"></a>`SUGGEST_PIPELINE` | Callout feature name for suggest_pipeline. |
......
......@@ -29039,6 +29039,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable %{feature}"
msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
msgid "SecurityConfiguration|Enabled"
msgstr ""
......@@ -29072,6 +29075,9 @@ msgstr ""
msgid "SecurityConfiguration|Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan."
msgstr ""
msgid "SecurityConfiguration|Quickly enable all continuous testing and compliance tools by enabling %{linkStart}Auto DevOps%{linkEnd}"
msgstr ""
msgid "SecurityConfiguration|Runtime security metrics for application environments."
msgstr ""
......
import { GlAlert } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import AutoDevopsAlert from '~/security_configuration/components/auto_dev_ops_alert.vue';
const autoDevopsHelpPagePath = '/autoDevopsHelpPagePath';
const autoDevopsPath = '/enableAutoDevopsPath';
describe('AutoDevopsAlert component', () => {
let wrapper;
const createComponent = () => {
wrapper = mount(AutoDevopsAlert, {
provide: {
autoDevopsHelpPagePath,
autoDevopsPath,
},
});
};
const findAlert = () => wrapper.findComponent(GlAlert);
beforeEach(() => {
createComponent();
});
afterEach(() => {
wrapper.destroy();
});
it('contains correct body text', () => {
expect(wrapper.text()).toContain('Quickly enable all');
});
it('renders the link correctly', () => {
const link = wrapper.find('a');
expect(link.attributes('href')).toBe(autoDevopsHelpPagePath);
expect(link.text()).toBe('Auto DevOps');
});
it('bubbles up dismiss events from the GlAlert', () => {
expect(wrapper.emitted('dismiss')).toBe(undefined);
findAlert().vm.$emit('dismiss');
expect(wrapper.emitted('dismiss')).toEqual([[]]);
});
it('has a button pointing to autoDevopsPath', () => {
expect(findAlert().props()).toMatchObject({
primaryButtonText: 'Enable Auto DevOps',
primaryButtonLink: autoDevopsPath,
});
});
});
......@@ -2,6 +2,7 @@ import { GlTab } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { makeMockUserCalloutDismisser } from 'helpers/mock_user_callout_dismisser';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import AutoDevopsAlert from '~/security_configuration/components/auto_dev_ops_alert.vue';
import {
SAST_NAME,
SAST_SHORT_NAME,
......@@ -13,6 +14,7 @@ import {
LICENSE_COMPLIANCE_HELP_PATH,
} from '~/security_configuration/components/constants';
import FeatureCard from '~/security_configuration/components/feature_card.vue';
import RedesignedSecurityConfigurationApp, {
i18n,
} from '~/security_configuration/components/redesigned_app.vue';
......@@ -23,6 +25,8 @@ import {
} from '~/vue_shared/security_reports/constants';
const upgradePath = '/upgrade';
const autoDevopsHelpPagePath = '/autoDevopsHelpPagePath';
const autoDevopsPath = '/autoDevopsPath';
const gitlabCiHistoryPath = 'test/historyPath';
describe('redesigned App component', () => {
......@@ -37,6 +41,8 @@ describe('redesigned App component', () => {
propsData,
provide: {
upgradePath,
autoDevopsHelpPagePath,
autoDevopsPath,
},
stubs: {
UserCalloutDismisser: makeMockUserCalloutDismisser({
......@@ -76,6 +82,7 @@ describe('redesigned App component', () => {
container: findByTestId('compliance-testing-tab'),
});
const findUpgradeBanner = () => wrapper.findComponent(UpgradeBanner);
const findAutoDevopsAlert = () => wrapper.findComponent(AutoDevopsAlert);
const securityFeaturesMock = [
{
......@@ -154,6 +161,44 @@ describe('redesigned App component', () => {
});
});
describe('autoDevOpsAlert', () => {
describe('given the right props', () => {
beforeEach(() => {
createComponent({
augmentedSecurityFeatures: securityFeaturesMock,
augmentedComplianceFeatures: complianceFeaturesMock,
autoDevopsEnabled: false,
gitlabCiPresent: false,
canEnableAutoDevops: true,
});
});
it('should show AutoDevopsAlert', () => {
expect(findAutoDevopsAlert().exists()).toBe(true);
});
it('calls the dismiss callback when closing the AutoDevopsAlert', () => {
expect(userCalloutDismissSpy).not.toHaveBeenCalled();
findAutoDevopsAlert().vm.$emit('dismiss');
expect(userCalloutDismissSpy).toHaveBeenCalledTimes(1);
});
});
describe('given the wrong props', () => {
beforeEach(() => {
createComponent({
augmentedSecurityFeatures: securityFeaturesMock,
augmentedComplianceFeatures: complianceFeaturesMock,
});
});
it('should not show AutoDevopsAlert', () => {
expect(findAutoDevopsAlert().exists()).toBe(false);
});
});
});
describe('upgrade banner', () => {
const makeAvailable = (available) => (feature) => ({ ...feature, available });
......
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