diff --git a/lib/gitlab/quick_actions/work_item_actions.rb b/lib/gitlab/quick_actions/work_item_actions.rb index af5db69fc2fa929ff32f6704b47d30720b58dff2..f35f05b434c715ae290da4963c614b3ab1ae5d9b 100644 --- a/lib/gitlab/quick_actions/work_item_actions.rb +++ b/lib/gitlab/quick_actions/work_item_actions.rb @@ -50,10 +50,14 @@ module WorkItemActions end command :set_parent, :epic do |parent_param| if quick_action_target.instance_of?(WorkItem) - first = extract_work_items(parent_param).first - - @updates[:set_parent] = first - @execution_message[:set_parent] = success_msg[:set_parent] + parent = extract_work_items(parent_param).first + + if parent && current_user.can?(:read_work_item, parent) + @updates[:set_parent] = parent + @execution_message[:set_parent] = success_msg[:set_parent] + else + @execution_message[:set_parent] = _("This parent does not exist or you don't have sufficient permission.") + end elsif quick_action_target.instance_of?(Issue) handle_set_epic(parent_param) end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index d21a1fafa82aa2bae6d682aaffde58bd910eab37..7edcf3b879cba58bdd7555a8d8dde0f0dc32aa87 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -60021,6 +60021,9 @@ msgstr "" msgid "This page is unavailable because you are not allowed to read information across multiple projects." msgstr "" +msgid "This parent does not exist or you don't have sufficient permission." +msgstr "" + msgid "This pipeline makes use of a predefined CI/CD configuration enabled by %{strongStart}Auto DevOps.%{strongEnd}" msgstr "" diff --git a/spec/services/quick_actions/interpret_service_spec.rb b/spec/services/quick_actions/interpret_service_spec.rb index eaf4e679aa4309745e95f78ec448463313611f8a..2eb1aeae9e8a46d0ea5f9c4f2a683f73f49a928e 100644 --- a/spec/services/quick_actions/interpret_service_spec.rb +++ b/spec/services/quick_actions/interpret_service_spec.rb @@ -3313,22 +3313,48 @@ context '/set_parent command' do let_it_be(:parent) { create(:work_item, :issue, project: project) } let_it_be(:task_work_item) { create(:work_item, :task, project: project) } - let_it_be(:issue_work_item) { create(:work_item, :issue, project: project) } let_it_be(:parent_ref) { parent.to_reference(project) } context 'on a work item' do - let(:content) { "/set_parent #{parent_ref}" } + context 'when the parent reference is valid' do + let(:content) { "/set_parent #{parent_ref}" } - it 'returns success message' do - _, _, message = service.execute(content, task_work_item) + it 'returns success message' do + _, _, message = service.execute(content, task_work_item) + + expect(message).to eq(_('Parent set successfully')) + end + + it 'sets correct update params' do + _, updates, _ = service.execute(content, task_work_item) - expect(message).to eq(_('Parent set successfully')) + expect(updates).to eq(set_parent: parent) + end + + context 'when the user does not have permission to read the work item' do + before do + allow(Ability).to receive(:allowed?).and_call_original + allow(Ability).to receive(:allowed?).with(current_user, :read_work_item, parent).and_return(false) + end + + it 'does not assign the parent and returns an appropriate error' do + _, updates, message = service.execute(content, task_work_item) + + expect(updates).to be_empty + expect(message).to eq("This parent does not exist or you don't have sufficient permission.") + end + end end - it 'sets correct update params' do - _, updates, _ = service.execute(content, task_work_item) + context 'when the parent reference is invalid' do + let(:content) { "/set_parent not_a_valid_parent" } - expect(updates).to eq(set_parent: parent) + it 'does not assign the parent and returns an appropriate error' do + _, updates, message = service.execute(content, task_work_item) + + expect(updates).to be_empty + expect(message).to eq("This parent does not exist or you don't have sufficient permission.") + end end context 'when epics are disabled' do @@ -3336,6 +3362,8 @@ stub_licensed_features(epics: false) end + let_it_be(:issue_work_item) { create(:work_item, :issue, project: project) } + it 'does not contain command for issue work item types' do expect(service.available_commands(issue_work_item)).not_to include(a_hash_including(name: :set_parent)) end