Commit 95a8b847 authored by Enrique Alcántara's avatar Enrique Alcántara

Merge branch '241150-disable-editing-for-inherited-iterations' into 'master'

Disable editing for inherited iterations

Closes #241150

See merge request gitlab-org/gitlab!40544
parents 5f6cc0d5 1692073d
...@@ -96,6 +96,9 @@ export default { ...@@ -96,6 +96,9 @@ export default {
}; };
}, },
computed: { computed: {
canEditIteration() {
return this.canEdit && this.namespaceType === Namespace.Group;
},
hasIteration() { hasIteration() {
return !this.$apollo.queries.iteration.loading && this.iteration?.title; return !this.$apollo.queries.iteration.loading && this.iteration?.title;
}, },
...@@ -155,7 +158,7 @@ export default { ...@@ -155,7 +158,7 @@ export default {
>{{ formatDate(iteration.startDate) }}{{ formatDate(iteration.dueDate) }}</span >{{ formatDate(iteration.startDate) }}{{ formatDate(iteration.dueDate) }}</span
> >
<gl-new-dropdown <gl-new-dropdown
v-if="canEdit" v-if="canEditIteration"
variant="default" variant="default"
toggle-class="gl-text-decoration-none gl-border-0! gl-shadow-none!" toggle-class="gl-text-decoration-none gl-border-0! gl-shadow-none!"
class="gl-ml-auto gl-text-secondary" class="gl-ml-auto gl-text-secondary"
......
...@@ -9,6 +9,7 @@ RSpec.describe 'User views iteration' do ...@@ -9,6 +9,7 @@ RSpec.describe 'User views iteration' do
let_it_be(:project) { create(:project, group: group) } let_it_be(:project) { create(:project, group: group) }
let_it_be(:sub_project) { create(:project, group: sub_group) } let_it_be(:sub_project) { create(:project, group: sub_group) }
let_it_be(:user) { create(:group_member, :maintainer, user: create(:user), group: group).user } let_it_be(:user) { create(:group_member, :maintainer, user: create(:user), group: group).user }
let_it_be(:guest_user) { create(:group_member, :guest, user: create(:user), group: group).user }
let_it_be(:iteration) { create(:iteration, :skip_future_date_validation, iid: 1, id: 2, group: group, title: 'Correct Iteration', start_date: now - 1.day, due_date: now) } let_it_be(:iteration) { create(:iteration, :skip_future_date_validation, iid: 1, id: 2, group: group, title: 'Correct Iteration', start_date: now - 1.day, due_date: now) }
let_it_be(:other_iteration) { create(:iteration, :skip_future_date_validation, iid: 2, id: 1, group: group, title: 'Wrong Iteration', start_date: now - 4.days, due_date: now - 3.days) } let_it_be(:other_iteration) { create(:iteration, :skip_future_date_validation, iid: 2, id: 1, group: group, title: 'Wrong Iteration', start_date: now - 4.days, due_date: now - 3.days) }
let_it_be(:sub_group_iteration) { create(:iteration, id: 3, group: sub_group) } let_it_be(:sub_group_iteration) { create(:iteration, id: 3, group: sub_group) }
...@@ -18,15 +19,13 @@ RSpec.describe 'User views iteration' do ...@@ -18,15 +19,13 @@ RSpec.describe 'User views iteration' do
let_it_be(:sub_group_issue) { create(:issue, project: sub_project, iteration: iteration) } let_it_be(:sub_group_issue) { create(:issue, project: sub_project, iteration: iteration) }
let_it_be(:other_issue) { create(:issue, project: project, iteration: other_iteration) } let_it_be(:other_issue) { create(:issue, project: project, iteration: other_iteration) }
context 'with license' do context 'with license', :js do
before do context 'view an iteration' do
stub_licensed_features(iterations: true)
sign_in(user)
end
context 'view an iteration', :js do
before do before do
visit group_iteration_path(group, iteration.iid) stub_licensed_features(iterations: true)
sign_in(user)
visit group_iteration_path(iteration.group, iteration.iid)
end end
it 'shows iteration info and dates' do it 'shows iteration info and dates' do
...@@ -51,6 +50,32 @@ RSpec.describe 'User views iteration' do ...@@ -51,6 +50,32 @@ RSpec.describe 'User views iteration' do
expect(page).not_to have_content(other_issue.title) expect(page).not_to have_content(other_issue.title)
end end
end end
context 'when user has edit permissions' do
before do
stub_licensed_features(iterations: true)
sign_in(user)
visit group_iteration_path(iteration.group, iteration.iid)
end
it 'shows action dropdown for editing the iteration' do
expect(page).to have_button('Actions')
end
end
context 'when user does not have edit permissions' do
before do
stub_licensed_features(iterations: true)
sign_in(guest_user)
visit group_iteration_path(iteration.group, iteration.iid)
end
it 'hides action dropdown for editing the iteration' do
expect(page).not_to have_button('Actions')
end
end
end end
context 'without license' do context 'without license' do
......
...@@ -46,6 +46,10 @@ RSpec.describe 'User views iteration' do ...@@ -46,6 +46,10 @@ RSpec.describe 'User views iteration' do
expect(page).to have_content(closed_issue.title) expect(page).to have_content(closed_issue.title)
expect(page).not_to have_content(other_issue.title) expect(page).not_to have_content(other_issue.title)
end end
it 'hides action dropdown for editing the iteration' do
expect(page).not_to have_button('Actions')
end
end end
end end
......
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { GlEmptyState, GlLoadingIcon, GlTab, GlTabs } from '@gitlab/ui'; import { GlNewDropdown, GlEmptyState, GlLoadingIcon, GlTab, GlTabs } from '@gitlab/ui';
import IterationReport from 'ee/iterations/components/iteration_report.vue'; import IterationReport from 'ee/iterations/components/iteration_report.vue';
import IterationReportSummary from 'ee/iterations/components/iteration_report_summary.vue'; import IterationReportSummary from 'ee/iterations/components/iteration_report_summary.vue';
import IterationReportTabs from 'ee/iterations/components/iteration_report_tabs.vue'; import IterationReportTabs from 'ee/iterations/components/iteration_report_tabs.vue';
...@@ -108,5 +108,36 @@ describe('Iterations report', () => { ...@@ -108,5 +108,36 @@ describe('Iterations report', () => {
expect(iterationReportTabs.props('iterationId')).toBe(iteration.id); expect(iterationReportTabs.props('iterationId')).toBe(iteration.id);
expect(iterationReportTabs.props('namespaceType')).toBe(Namespace.Group); expect(iterationReportTabs.props('namespaceType')).toBe(Namespace.Group);
}); });
describe('actions dropdown to edit iteration', () => {
describe.each`
description | canEdit | namespaceType | canEditIteration
${'has permissions'} | ${true} | ${Namespace.Group} | ${true}
${'has permissions'} | ${true} | ${Namespace.Project} | ${false}
${'does not have permissions'} | ${false} | ${Namespace.Group} | ${false}
${'does not have permissions'} | ${false} | ${Namespace.Project} | ${false}
`(
'when user $description and they are viewing an iteration within a $namespaceType',
({ canEdit, namespaceType, canEditIteration }) => {
beforeEach(() => {
mountComponent({
props: {
...defaultProps,
canEdit,
namespaceType,
},
});
wrapper.setData({
iteration,
});
});
it(`${canEditIteration ? 'is shown' : 'is hidden'}`, () => {
expect(wrapper.contains(GlNewDropdown)).toBe(canEditIteration);
});
},
);
});
}); });
}); });
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