Commit 74b97942 authored by Jan Provaznik's avatar Jan Provaznik

Merge branch 'issue_353474-add_related_epic_links_destroy_service' into 'master'

Add RelatedEpicLinks::DestroyService

See merge request gitlab-org/gitlab!81610
parents e49345ad b6da269c
...@@ -4,11 +4,13 @@ module IssuableLinks ...@@ -4,11 +4,13 @@ module IssuableLinks
class DestroyService < BaseService class DestroyService < BaseService
include IncidentManagement::UsageData include IncidentManagement::UsageData
attr_reader :link, :current_user attr_reader :link, :current_user, :source, :target
def initialize(link, user) def initialize(link, user)
@link = link @link = link
@current_user = user @current_user = user
@source = link.source
@target = link.target
end end
def execute def execute
...@@ -22,6 +24,11 @@ module IssuableLinks ...@@ -22,6 +24,11 @@ module IssuableLinks
private private
def create_notes
SystemNoteService.unrelate_issuable(source, target, current_user)
SystemNoteService.unrelate_issuable(target, source, current_user)
end
def after_destroy def after_destroy
create_notes create_notes
track_event track_event
......
...@@ -4,23 +4,10 @@ module IssueLinks ...@@ -4,23 +4,10 @@ module IssueLinks
class DestroyService < IssuableLinks::DestroyService class DestroyService < IssuableLinks::DestroyService
private private
def source
@source ||= link.source
end
def target
@target ||= link.target
end
def permission_to_remove_relation? def permission_to_remove_relation?
can?(current_user, :admin_issue_link, source) && can?(current_user, :admin_issue_link, target) can?(current_user, :admin_issue_link, source) && can?(current_user, :admin_issue_link, target)
end end
def create_notes
SystemNoteService.unrelate_issue(source, target, current_user)
SystemNoteService.unrelate_issue(target, source, current_user)
end
def track_event def track_event
track_incident_action(current_user, target, :incident_unrelate) track_incident_action(current_user, target, :incident_unrelate)
end end
......
...@@ -53,8 +53,8 @@ module SystemNoteService ...@@ -53,8 +53,8 @@ module SystemNoteService
::SystemNotes::IssuablesService.new(noteable: noteable, project: noteable.project, author: user).relate_issue(noteable_ref) ::SystemNotes::IssuablesService.new(noteable: noteable, project: noteable.project, author: user).relate_issue(noteable_ref)
end end
def unrelate_issue(noteable, noteable_ref, user) def unrelate_issuable(noteable, noteable_ref, user)
::SystemNotes::IssuablesService.new(noteable: noteable, project: noteable.project, author: user).unrelate_issue(noteable_ref) ::SystemNotes::IssuablesService.new(noteable: noteable, project: noteable.project, author: user).unrelate_issuable(noteable_ref)
end end
# Called when the due_date of a Noteable is changed # Called when the due_date of a Noteable is changed
......
...@@ -26,8 +26,8 @@ module SystemNotes ...@@ -26,8 +26,8 @@ module SystemNotes
# "removed the relation with gitlab-foss#9001" # "removed the relation with gitlab-foss#9001"
# #
# Returns the created Note object # Returns the created Note object
def unrelate_issue(noteable_ref) def unrelate_issuable(noteable_ref)
body = "removed the relation with #{noteable_ref.to_reference(noteable.project)}" body = "removed the relation with #{noteable_ref.to_reference(noteable.resource_parent)}"
issue_activity_counter.track_issue_unrelated_action(author: author) if noteable.is_a?(Issue) issue_activity_counter.track_issue_unrelated_action(author: author) if noteable.is_a?(Issue)
......
...@@ -4,6 +4,13 @@ module EpicIssues ...@@ -4,6 +4,13 @@ module EpicIssues
class DestroyService < IssuableLinks::DestroyService class DestroyService < IssuableLinks::DestroyService
extend ::Gitlab::Utils::Override extend ::Gitlab::Utils::Override
def initialize(link, user)
@link = link
@current_user = user
@source = link.epic
@target = link.issue
end
private private
override :after_destroy override :after_destroy
...@@ -18,14 +25,6 @@ module EpicIssues ...@@ -18,14 +25,6 @@ module EpicIssues
::Gitlab::UsageDataCounters::EpicActivityUniqueCounter.track_epic_issue_removed(author: current_user) ::Gitlab::UsageDataCounters::EpicActivityUniqueCounter.track_epic_issue_removed(author: current_user)
end end
def source
@source ||= link.epic
end
def target
@target ||= link.issue
end
def permission_to_remove_relation? def permission_to_remove_relation?
can?(current_user, :admin_epic_issue, target) && can?(current_user, :read_epic, source) can?(current_user, :admin_epic_issue, target) && can?(current_user, :read_epic, source)
end end
......
# frozen_string_literal: true
module Epics
module RelatedEpicLinks
class DestroyService < ::IssuableLinks::DestroyService
private
def permission_to_remove_relation?
can?(current_user, :admin_related_epic_link, source) && can?(current_user, :admin_related_epic_link, target)
end
def track_event
# No op
end
def not_found_message
'No Related Epic Link found'
end
end
end
end
...@@ -2,6 +2,11 @@ ...@@ -2,6 +2,11 @@
module FeatureFlagIssues module FeatureFlagIssues
class DestroyService < IssuableLinks::DestroyService class DestroyService < IssuableLinks::DestroyService
def initialize(link, user)
@link = link
@current_user = user
end
def permission_to_remove_relation? def permission_to_remove_relation?
can?(current_user, :admin_feature_flag, link.feature_flag) can?(current_user, :admin_feature_flag, link.feature_flag)
end end
......
...@@ -88,4 +88,15 @@ RSpec.describe ::SystemNotes::IssuablesService do ...@@ -88,4 +88,15 @@ RSpec.describe ::SystemNotes::IssuablesService do
end end
end end
end end
describe '#unrelate_issuable' do
let(:noteable) { epic }
let(:target) { create(:epic) }
it 'creates system notes when epic gets unrelated' do
result = service.unrelate_issuable(target)
expect(result.note).to eq("removed the relation with #{target.to_reference(noteable.group)}")
end
end
end end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Epics::RelatedEpicLinks::DestroyService do
describe '#execute' do
let_it_be(:user) { create(:user) }
let!(:issuable_link) { create(:related_epic_link) }
before do
stub_licensed_features(epics: true, related_epics: true)
end
subject { described_class.new(issuable_link, user).execute }
it_behaves_like 'a destroyable issuable link'
end
end
...@@ -4,65 +4,26 @@ require 'spec_helper' ...@@ -4,65 +4,26 @@ require 'spec_helper'
RSpec.describe IssueLinks::DestroyService do RSpec.describe IssueLinks::DestroyService do
describe '#execute' do describe '#execute' do
let(:project) { create(:project_empty_repo) } let_it_be(:project) { create(:project_empty_repo, :private) }
let(:user) { create(:user) } let_it_be(:user) { create(:user) }
let_it_be(:issue_a) { create(:issue, project: project) }
let_it_be(:issue_b) { create(:issue, project: project) }
subject { described_class.new(issue_link, user).execute } let!(:issuable_link) { create(:issue_link, source: issue_a, target: issue_b) }
context 'when successfully removes an issue link' do subject { described_class.new(issuable_link, user).execute }
let(:issue_a) { create(:issue, project: project) }
let(:issue_b) { create(:issue, project: project) }
let!(:issue_link) { create(:issue_link, source: issue_a, target: issue_b) } it_behaves_like 'a destroyable issuable link'
context 'when target is an incident' do
before do before do
project.add_reporter(user) project.add_reporter(user)
end end
it 'removes related issue' do let(:issue_b) { create(:incident, project: project) }
expect { subject }.to change(IssueLink, :count).from(1).to(0)
end
it 'creates notes' do
# Two-way notes creation
expect(SystemNoteService).to receive(:unrelate_issue)
.with(issue_link.source, issue_link.target, user)
expect(SystemNoteService).to receive(:unrelate_issue)
.with(issue_link.target, issue_link.source, user)
subject
end
it 'returns success message' do
is_expected.to eq(message: 'Relation was removed', status: :success)
end
context 'target is an incident' do
let(:issue_b) { create(:incident, project: project) }
it_behaves_like 'an incident management tracked event', :incident_management_incident_unrelate do
let(:current_user) { user }
end
end
end
context 'when failing to remove an issue link' do
let(:unauthorized_project) { create(:project) }
let(:issue_a) { create(:issue, project: project) }
let(:issue_b) { create(:issue, project: unauthorized_project) }
let!(:issue_link) { create(:issue_link, source: issue_a, target: issue_b) }
it 'does not remove relation' do
expect { subject }.not_to change(IssueLink, :count).from(1)
end
it 'does not create notes' do
expect(SystemNoteService).not_to receive(:unrelate_issue)
end
it 'returns error message' do it_behaves_like 'an incident management tracked event', :incident_management_incident_unrelate do
is_expected.to eq(message: 'No Issue Link found', status: :error, http_status: 404) let(:current_user) { user }
end end
end end
end end
......
...@@ -117,7 +117,7 @@ RSpec.describe SystemNoteService do ...@@ -117,7 +117,7 @@ RSpec.describe SystemNoteService do
end end
end end
describe '.unrelate_issue' do describe '.unrelate_issuable' do
let(:noteable_ref) { double } let(:noteable_ref) { double }
let(:noteable) { double } let(:noteable) { double }
...@@ -127,10 +127,10 @@ RSpec.describe SystemNoteService do ...@@ -127,10 +127,10 @@ RSpec.describe SystemNoteService do
it 'calls IssuableService' do it 'calls IssuableService' do
expect_next_instance_of(::SystemNotes::IssuablesService) do |service| expect_next_instance_of(::SystemNotes::IssuablesService) do |service|
expect(service).to receive(:unrelate_issue).with(noteable_ref) expect(service).to receive(:unrelate_issuable).with(noteable_ref)
end end
described_class.unrelate_issue(noteable, noteable_ref, double) described_class.unrelate_issuable(noteable, noteable_ref, double)
end end
end end
......
...@@ -30,10 +30,10 @@ RSpec.describe ::SystemNotes::IssuablesService do ...@@ -30,10 +30,10 @@ RSpec.describe ::SystemNotes::IssuablesService do
end end
end end
describe '#unrelate_issue' do describe '#unrelate_issuable' do
let(:noteable_ref) { create(:issue) } let(:noteable_ref) { create(:issue) }
subject { service.unrelate_issue(noteable_ref) } subject { service.unrelate_issuable(noteable_ref) }
it_behaves_like 'a system note' do it_behaves_like 'a system note' do
let(:action) { 'unrelate' } let(:action) { 'unrelate' }
......
# frozen_string_literal: true
shared_examples 'a destroyable issuable link' do
context 'when successfully removes an issuable link' do
before do
issuable_link.source.resource_parent.add_reporter(user)
issuable_link.target.resource_parent.add_reporter(user)
end
it 'removes related issue' do
expect { subject }.to change(issuable_link.class, :count).by(-1)
end
it 'creates notes' do
# Two-way notes creation
expect(SystemNoteService).to receive(:unrelate_issuable)
.with(issuable_link.source, issuable_link.target, user)
expect(SystemNoteService).to receive(:unrelate_issuable)
.with(issuable_link.target, issuable_link.source, user)
subject
end
it 'returns success message' do
is_expected.to eq(message: 'Relation was removed', status: :success)
end
end
context 'when failing to remove an issuable link' do
it 'does not remove relation' do
expect { subject }.not_to change(issuable_link.class, :count).from(1)
end
it 'does not create notes' do
expect(SystemNoteService).not_to receive(:unrelate_issuable)
end
it 'returns error message' do
is_expected.to eq(message: "No #{issuable_link.class.model_name.human.titleize} found", status: :error, http_status: 404)
end
end
end
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