Skip to content
代码片段 群组 项目
提交 177242a0 编辑于 作者: Samantha Ming's avatar Samantha Ming
浏览文件

Display security training config based on license

上级 46ed26bb
No related branches found
No related tags found
无相关合并请求
......@@ -4,9 +4,10 @@ import { __, s__ } from '~/locale';
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
import UserCalloutDismisser from '~/vue_shared/components/user_callout_dismisser.vue';
import SectionLayout from '~/vue_shared/security_configuration/components/section_layout.vue';
import currentLicenseQuery from '~/security_configuration/graphql/current_license.query.graphql';
import AutoDevOpsAlert from './auto_dev_ops_alert.vue';
import AutoDevOpsEnabledAlert from './auto_dev_ops_enabled_alert.vue';
import { AUTO_DEVOPS_ENABLED_ALERT_DISMISSED_STORAGE_KEY } from './constants';
import { AUTO_DEVOPS_ENABLED_ALERT_DISMISSED_STORAGE_KEY, LICENSE_ULTIMATE } from './constants';
import FeatureCard from './feature_card.vue';
import TrainingProviderList from './training_provider_list.vue';
import UpgradeBanner from './upgrade_banner.vue';
......@@ -50,6 +51,14 @@ export default {
TrainingProviderList,
},
inject: ['projectFullPath', 'vulnerabilityTrainingDocsPath'],
apollo: {
currentLicensePlan: {
query: currentLicenseQuery,
update({ currentLicense }) {
return currentLicense?.plan;
},
},
},
props: {
augmentedSecurityFeatures: {
type: Array,
......@@ -89,6 +98,7 @@ export default {
return {
autoDevopsEnabledAlertDismissedProjects: [],
errorMessage: '',
currentLicensePlan: '',
};
},
computed: {
......@@ -109,6 +119,9 @@ export default {
!this.autoDevopsEnabledAlertDismissedProjects.includes(this.projectFullPath)
);
},
shouldShowVulnerabilityManagementTab() {
return this.currentLicensePlan === LICENSE_ULTIMATE;
},
},
methods: {
dismissAutoDevopsEnabledAlert() {
......@@ -250,6 +263,7 @@ export default {
</section-layout>
</gl-tab>
<gl-tab
v-if="shouldShowVulnerabilityManagementTab"
data-testid="vulnerability-management-tab"
:title="$options.i18n.vulnerabilityManagement"
query-param-value="vulnerability-management"
......
......@@ -310,3 +310,7 @@ export const TEMP_PROVIDER_URLS = {
Kontra: 'https://application.security/',
[__('Secure Code Warrior')]: 'https://www.securecodewarrior.com/',
};
export const LICENSE_ULTIMATE = 'ultimate';
export const LICENSE_FREE = 'free';
export const LICENSE_PREMIUM = 'premium';
query getCurrentLicensePlan {
currentLicense {
id
plan
}
}
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import { GlTab, GlTabs, GlLink } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
import { makeMockUserCalloutDismisser } from 'helpers/mock_user_callout_dismisser';
import stubChildren from 'helpers/stub_children';
......@@ -18,15 +20,22 @@ import {
LICENSE_COMPLIANCE_DESCRIPTION,
LICENSE_COMPLIANCE_HELP_PATH,
AUTO_DEVOPS_ENABLED_ALERT_DISMISSED_STORAGE_KEY,
LICENSE_ULTIMATE,
LICENSE_PREMIUM,
LICENSE_FREE,
} from '~/security_configuration/components/constants';
import FeatureCard from '~/security_configuration/components/feature_card.vue';
import TrainingProviderList from '~/security_configuration/components/training_provider_list.vue';
import createMockApollo from 'helpers/mock_apollo_helper';
import currentLicenseQuery from '~/security_configuration/graphql/current_license.query.graphql';
import waitForPromises from 'helpers/wait_for_promises';
import UpgradeBanner from '~/security_configuration/components/upgrade_banner.vue';
import {
REPORT_TYPE_LICENSE_COMPLIANCE,
REPORT_TYPE_SAST,
} from '~/vue_shared/security_reports/constants';
import { getCurrentLicensePlanResponse } from '../mock_data';
const upgradePath = '/upgrade';
const autoDevopsHelpPagePath = '/autoDevopsHelpPagePath';
......@@ -36,14 +45,24 @@ const projectFullPath = 'namespace/project';
const vulnerabilityTrainingDocsPath = 'user/application_security/vulnerabilities/index';
useLocalStorageSpy();
Vue.use(VueApollo);
describe('App component', () => {
let wrapper;
let userCalloutDismissSpy;
let mockApollo;
const createComponent = ({ shouldShowCallout = true, ...propsData }) => {
const createComponent = ({
shouldShowCallout = true,
license = LICENSE_ULTIMATE,
...propsData
}) => {
userCalloutDismissSpy = jest.fn();
mockApollo = createMockApollo([
[currentLicenseQuery, jest.fn().mockResolvedValue(getCurrentLicensePlanResponse(license))],
]);
wrapper = extendedWrapper(
mount(SecurityConfigurationApp, {
propsData,
......@@ -54,6 +73,7 @@ describe('App component', () => {
projectFullPath,
vulnerabilityTrainingDocsPath,
},
apolloProvider: mockApollo,
stubs: {
...stubChildren(SecurityConfigurationApp),
GlLink: false,
......@@ -128,14 +148,16 @@ describe('App component', () => {
afterEach(() => {
wrapper.destroy();
mockApollo = null;
});
describe('basic structure', () => {
beforeEach(() => {
beforeEach(async () => {
createComponent({
augmentedSecurityFeatures: securityFeaturesMock,
augmentedComplianceFeatures: complianceFeaturesMock,
});
await waitForPromises();
});
it('renders main-heading with correct text', () => {
......@@ -438,11 +460,12 @@ describe('App component', () => {
});
describe('Vulnerability management', () => {
beforeEach(() => {
beforeEach(async () => {
createComponent({
augmentedSecurityFeatures: securityFeaturesMock,
augmentedComplianceFeatures: complianceFeaturesMock,
});
await waitForPromises();
});
it('renders TrainingProviderList component', () => {
......@@ -459,5 +482,21 @@ describe('App component', () => {
expect(trainingLink.text()).toBe('Learn more about vulnerability training');
expect(trainingLink.attributes('href')).toBe(vulnerabilityTrainingDocsPath);
});
it.each`
license | display
${LICENSE_ULTIMATE} | ${true}
${LICENSE_PREMIUM} | ${false}
${LICENSE_FREE} | ${false}
${null} | ${false}
`('displays $display for license $license', async ({ license, display }) => {
createComponent({
license,
augmentedSecurityFeatures: securityFeaturesMock,
augmentedComplianceFeatures: complianceFeaturesMock,
});
await waitForPromises();
expect(findVulnerabilityManagementTab().exists()).toBe(display);
});
});
});
......@@ -111,3 +111,12 @@ export const tempProviderLogos = {
svg: `<svg>${[testProviderName[1]]}</svg>`,
},
};
export const getCurrentLicensePlanResponse = (plan) => ({
data: {
currentLicense: {
id: 'gid://gitlab/License/1',
plan,
},
},
});
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册