Commit fec71166 authored by Mayra Cabrera's avatar Mayra Cabrera

Merge branch '325988-subgroup-compliance-frameworks' into 'master'

Removes compliance framework administration abilities from subgroups

See merge request gitlab-org/gitlab!58873
parents 3ae76f25 efce11f0
......@@ -26,11 +26,13 @@ export default {
props: {
addFrameworkPath: {
type: String,
required: true,
required: false,
default: null,
},
editFrameworkPath: {
type: String,
required: true,
required: false,
default: null,
},
emptyStateSvgPath: {
type: String,
......@@ -177,6 +179,7 @@ export default {
<gl-tab disabled :title="$options.i18n.regulatedTab" />
<template #tabs-end>
<gl-button
v-if="addFrameworkPath"
class="gl-align-self-center gl-ml-auto"
category="primary"
variant="confirm"
......
......@@ -9,17 +9,19 @@ export default {
props: {
imagePath: {
type: String,
required: true,
required: false,
default: null,
},
addFrameworkPath: {
type: String,
required: true,
required: false,
default: null,
},
},
i18n: {
heading: s__('ComplianceFrameworks|There are no compliance frameworks set up yet'),
description: s__(
'ComplianceFrameworks|Once you have created a compliance framework it will appear here.',
'ComplianceFrameworks|Once a compliance framework is added it will appear here.',
),
addButton: s__('ComplianceFrameworks|Add framework'),
},
......
......@@ -47,7 +47,7 @@ export default {
<p class="gl-w-full gl-m-0!" data-testid="compliance-framework-description">
{{ framework.description }}
</p>
<div class="gl-display-flex">
<div v-if="framework.editPath" class="gl-display-flex">
<gl-button
v-gl-tooltip="$options.i18n.editFramework"
:disabled="loading"
......
......@@ -4,7 +4,7 @@ import { isNumeric } from '~/lib/utils/number_utils';
import { EDIT_PATH_ID_FORMAT, PIPELINE_CONFIGURATION_PATH_FORMAT } from './constants';
export const injectIdIntoEditPath = (path, id) => {
if (!path.match(EDIT_PATH_ID_FORMAT) || !isNumeric(id)) {
if (!path || !path.match(EDIT_PATH_ID_FORMAT) || !isNumeric(id)) {
return '';
}
......
......@@ -8,18 +8,18 @@ module ComplianceManagement
end
def compliance_frameworks_list_data(group)
{
empty_state_svg_path: image_path('illustrations/welcome/ee_trial.svg'),
group_path: group.full_path,
add_framework_path: new_group_compliance_framework_path(group),
edit_framework_path: edit_group_compliance_framework_path(group, :id)
}
{}.tap do |data|
data[:empty_state_svg_path] = image_path('illustrations/welcome/ee_trial.svg')
data[:group_path] = group.root_ancestor.full_path
data[:add_framework_path] = new_group_compliance_framework_path(group) unless group.subgroup?
data[:edit_framework_path] = edit_group_compliance_framework_path(group, :id) unless group.subgroup?
end
end
def compliance_frameworks_form_data(group, framework_id = nil)
{
framework_id: framework_id,
group_path: group.full_path,
group_path: group.root_ancestor.full_path,
group_edit_path: edit_group_path(group, anchor: 'js-compliance-frameworks-settings'),
graphql_field_name: ComplianceManagement::Framework.name,
pipeline_configuration_full_path_enabled: pipeline_configuration_full_path_enabled?(group).to_s
......
---
title: Remove compliance framework administration abilities from subgroups
merge_request: 58873
author:
type: changed
......@@ -26,7 +26,7 @@ describe('ListEmptyState', () => {
expect(findEmptyState().props()).toMatchObject({
title: 'There are no compliance frameworks set up yet',
description: 'Once you have created a compliance framework it will appear here.',
description: 'Once a compliance framework is added it will appear here.',
svgPath: 'dir/image.svg',
primaryButtonLink: 'group/framework/new',
primaryButtonText: 'Add framework',
......
......@@ -19,6 +19,7 @@ describe('ListItem', () => {
color: '#112233',
editPath: 'group/framework/1/edit',
};
const findLabel = () => wrapper.findComponent(GlLabel);
const findDescription = () => wrapper.findByTestId('compliance-framework-description');
const findEditButton = () => wrapper.findByTestId('compliance-framework-edit-button');
......@@ -50,6 +51,15 @@ describe('ListItem', () => {
expect(button.attributes('aria-label')).toBe(ariaLabel);
};
it('does not show modification buttons when framework is missing paths', () => {
createComponent({
framework: { ...framework, editPath: null },
});
expect(findEditButton().exists()).toBe(false);
expect(findDeleteButton().exists()).toBe(false);
});
it('displays the description defined by the framework', () => {
createComponent();
......@@ -65,7 +75,9 @@ describe('ListItem', () => {
});
it('displays the label as scoped', () => {
createComponent({ framework: { ...framework, name: 'scoped::framework' } });
createComponent({
framework: { ...framework, name: 'scoped::framework' },
});
expect(findLabel().props('title')).toBe('scoped::framework');
expect(findLabel().props('target')).toBe(framework.editPath);
......
......@@ -12,7 +12,6 @@ import { PIPELINE_CONFIGURATION_PATH_FORMAT } from 'ee/groups/settings/complianc
import getComplianceFrameworkQuery from 'ee/groups/settings/compliance_frameworks/graphql/queries/get_compliance_framework.query.graphql';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { validFetchResponse, emptyFetchResponse } from '../mock_data';
const localVue = createLocalVue();
......@@ -44,7 +43,7 @@ describe('List', () => {
return createMockApollo(requestHandlers);
}
function createComponentWithApollo(resolverMock) {
function createComponentWithApollo(resolverMock, props = {}) {
return shallowMount(List, {
localVue,
apolloProvider: createMockApolloProvider(resolverMock),
......@@ -53,6 +52,7 @@ describe('List', () => {
editFrameworkPath: 'group/framework/id/edit',
emptyStateSvgPath: 'dir/image.svg',
groupPath: 'group-1',
...props,
},
stubs: {
GlLoadingIcon,
......@@ -193,6 +193,19 @@ describe('List', () => {
it('renders the delete modal', () => {
expect(findDeleteModal().exists()).toBe(true);
});
describe('when no paths are provided', () => {
beforeEach(() => {
wrapper = createComponentWithApollo(fetch, {
addFrameworkPath: null,
editFrameworkPath: null,
});
});
it('does not show the add framework button', () => {
expect(findAddBtn().exists()).toBe(false);
});
});
});
describe('delete framework', () => {
......
......@@ -22,15 +22,23 @@ RSpec.describe ComplianceManagement::ComplianceFramework::GroupSettingsHelper do
end
context 'the user does not have permission' do
before do
allow(helper).to receive(:can?).with(current_user, :admin_compliance_framework, group).and_return(false)
end
context 'group is not a subgroup' do
before do
allow(helper).to receive(:can?).with(current_user, :admin_compliance_framework, group).and_return(false)
end
it { is_expected.to be false }
it { is_expected.to be false }
end
end
end
describe '#compliance_frameworks_list_data' do
subject { helper.compliance_frameworks_list_data(group) }
before do
allow(helper).to receive(:can?).with(current_user, :admin_compliance_framework, group).and_return(true)
end
it 'returns the correct data' do
expect(helper.compliance_frameworks_list_data(group)).to contain_exactly(
[:empty_state_svg_path, ActionController::Base.helpers.image_path('illustrations/welcome/ee_trial.svg')],
......@@ -39,6 +47,19 @@ RSpec.describe ComplianceManagement::ComplianceFramework::GroupSettingsHelper do
[:edit_framework_path, edit_group_compliance_framework_path(group, :id)]
)
end
context 'group is a subgroup' do
let_it_be(:group) { create(:group, :nested) }
it 'contains the root ancestor as group_path' do
expect(subject[:group_path]).to eq(group.root_ancestor.full_path)
end
it 'does not contain the add_framework_path or edit_framework_path keys' do
expect(subject.keys).not_to include('add_framework_path')
expect(subject.keys).not_to include('edit_framework_path')
end
end
end
describe '#compliance_frameworks_form_data' do
......@@ -83,5 +104,15 @@ RSpec.describe ComplianceManagement::ComplianceFramework::GroupSettingsHelper do
context 'the user does not have pipeline configuration permission' do
it_behaves_like 'returns the correct data', [false]
end
context 'group is a subgroup' do
let_it_be(:group) { create(:group, :nested) }
it 'returns the root ancestor full path as group_path' do
allow(helper).to receive(:can?).with(current_user, :admin_compliance_pipeline_configuration, group).and_return(true)
expect(subject[:group_path]).to eq(group.root_ancestor.full_path)
end
end
end
end
......@@ -8048,7 +8048,7 @@ msgstr ""
msgid "ComplianceFrameworks|Invalid format: it should follow the format [PATH].y(a)ml@[GROUP]/[PROJECT]"
msgstr ""
msgid "ComplianceFrameworks|Once you have created a compliance framework it will appear here."
msgid "ComplianceFrameworks|Once a compliance framework is added it will appear here."
msgstr ""
msgid "ComplianceFrameworks|Regulated"
......
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