Commit a41810b5 authored by Kerri Miller's avatar Kerri Miller

Merge branch 'reload_diff_in_update_service_part_2' into 'master'

Only call the resolved notification service if we have resolved all the notes

See merge request gitlab-org/gitlab!79142
parents e8c674b5 382c653c
...@@ -99,6 +99,12 @@ module ResolvableDiscussion ...@@ -99,6 +99,12 @@ module ResolvableDiscussion
update { |notes| notes.unresolve! } update { |notes| notes.unresolve! }
end end
def clear_memoized_values
self.class.memoized_values.each do |name|
clear_memoization(name)
end
end
private private
def update def update
...@@ -110,8 +116,6 @@ module ResolvableDiscussion ...@@ -110,8 +116,6 @@ module ResolvableDiscussion
# Set the notes array to the updated notes # Set the notes array to the updated notes
@notes = notes_relation.fresh.to_a # rubocop:disable Gitlab/ModuleWithInstanceVariables @notes = notes_relation.fresh.to_a # rubocop:disable Gitlab/ModuleWithInstanceVariables
self.class.memoized_values.each do |name| clear_memoized_values
clear_memoization(name)
end
end end
end end
...@@ -1754,6 +1754,8 @@ class MergeRequest < ApplicationRecord ...@@ -1754,6 +1754,8 @@ class MergeRequest < ApplicationRecord
paths = active_diff_discussions.flat_map { |n| n.diff_file.paths }.uniq paths = active_diff_discussions.flat_map { |n| n.diff_file.paths }.uniq
active_discussions_resolved = active_diff_discussions.all?(&:resolved?)
service = Discussions::UpdateDiffPositionService.new( service = Discussions::UpdateDiffPositionService.new(
self.project, self.project,
current_user, current_user,
...@@ -1764,9 +1766,15 @@ class MergeRequest < ApplicationRecord ...@@ -1764,9 +1766,15 @@ class MergeRequest < ApplicationRecord
active_diff_discussions.each do |discussion| active_diff_discussions.each do |discussion|
service.execute(discussion) service.execute(discussion)
discussion.clear_memoized_values
end end
if project.resolve_outdated_diff_discussions? # If they were all already resolved, this method will have already been called.
# If they all don't get resolved, we don't need to call the method
# If they go from unresolved -> resolved, then we call the method
if !active_discussions_resolved &&
active_diff_discussions.all?(&:resolved?) &&
project.resolve_outdated_diff_discussions?
MergeRequests::ResolvedDiscussionNotificationService MergeRequests::ResolvedDiscussionNotificationService
.new(project: project, current_user: current_user) .new(project: project, current_user: current_user)
.execute(self) .execute(self)
......
...@@ -584,4 +584,14 @@ RSpec.describe Discussion, ResolvableDiscussion do ...@@ -584,4 +584,14 @@ RSpec.describe Discussion, ResolvableDiscussion do
expect(subject.last_resolved_note).to eq(second_note) expect(subject.last_resolved_note).to eq(second_note)
end end
end end
describe '#clear_memoized_values' do
it 'resets the memoized values' do
described_class.memoized_values.each do |memo|
subject.instance_variable_set("@#{memo}", 'memoized')
expect { subject.clear_memoized_values }.to change { subject.instance_variable_get("@#{memo}") }
.from('memoized').to(nil)
end
end
end
end end
...@@ -3577,21 +3577,38 @@ RSpec.describe MergeRequest, factory_default: :keep do ...@@ -3577,21 +3577,38 @@ RSpec.describe MergeRequest, factory_default: :keep do
end end
describe '#update_diff_discussion_positions' do describe '#update_diff_discussion_positions' do
let(:discussion) { create(:diff_note_on_merge_request, project: subject.project, noteable: subject).to_discussion } subject { create(:merge_request, source_project: project) }
let(:commit) { subject.project.commit(sample_commit.id) }
let(:old_diff_refs) { subject.diff_refs }
before do let(:project) { create(:project, :repository) }
# Update merge_request_diff so that #diff_refs will return commit.diff_refs let(:create_commit) { project.commit("913c66a37b4a45b9769037c55c2d238bd0942d2e") }
allow(subject).to receive(:create_merge_request_diff) do let(:modify_commit) { project.commit("874797c3a73b60d2187ed6e2fcabd289ff75171e") }
subject.merge_request_diffs.create!( let(:edit_commit) { project.commit("570e7b2abdd848b95f2f578043fc23bd6f6fd24d") }
base_commit_sha: commit.parent_id, let(:discussion) { create(:diff_note_on_merge_request, noteable: subject, project: project, position: old_position).to_discussion }
start_commit_sha: commit.parent_id, let(:path) { "files/ruby/popen.rb" }
head_commit_sha: commit.sha let(:new_line) { 9 }
)
let(:old_diff_refs) do
Gitlab::Diff::DiffRefs.new(
base_sha: create_commit.parent_id,
head_sha: modify_commit.sha
)
end
subject.reload_merge_request_diff let(:new_diff_refs) do
end Gitlab::Diff::DiffRefs.new(
base_sha: create_commit.parent_id,
head_sha: edit_commit.sha
)
end
let(:old_position) do
Gitlab::Diff::Position.new(
old_path: path,
new_path: path,
old_line: nil,
new_line: new_line,
diff_refs: old_diff_refs
)
end end
it "updates diff discussion positions" do it "updates diff discussion positions" do
...@@ -3599,36 +3616,67 @@ RSpec.describe MergeRequest, factory_default: :keep do ...@@ -3599,36 +3616,67 @@ RSpec.describe MergeRequest, factory_default: :keep do
subject.project, subject.project,
subject.author, subject.author,
old_diff_refs: old_diff_refs, old_diff_refs: old_diff_refs,
new_diff_refs: commit.diff_refs, new_diff_refs: new_diff_refs,
paths: discussion.position.paths paths: discussion.position.paths
).and_call_original ).and_call_original
expect_any_instance_of(Discussions::UpdateDiffPositionService).to receive(:execute).with(discussion).and_call_original expect_any_instance_of(Discussions::UpdateDiffPositionService).to receive(:execute).with(discussion).and_call_original
expect_any_instance_of(DiffNote).to receive(:save).once
subject.update_diff_discussion_positions(old_diff_refs: old_diff_refs, subject.update_diff_discussion_positions(old_diff_refs: old_diff_refs,
new_diff_refs: commit.diff_refs, new_diff_refs: new_diff_refs,
current_user: subject.author) current_user: subject.author)
end end
context 'when resolve_outdated_diff_discussions is set' do it 'does not call the resolve method' do
let(:project) { create(:project, :repository) } expect(MergeRequests::ResolvedDiscussionNotificationService).not_to receive(:new)
subject { create(:merge_request, source_project: project) } subject.update_diff_discussion_positions(old_diff_refs: old_diff_refs,
new_diff_refs: new_diff_refs,
current_user: subject.author)
end
context 'when resolve_outdated_diff_discussions is set' do
before do before do
discussion discussion
subject.project.update!(resolve_outdated_diff_discussions: true) subject.project.update!(resolve_outdated_diff_discussions: true)
end end
it 'calls MergeRequests::ResolvedDiscussionNotificationService' do context 'when the active discussion is resolved in the update' do
expect_any_instance_of(MergeRequests::ResolvedDiscussionNotificationService) it 'calls MergeRequests::ResolvedDiscussionNotificationService' do
.to receive(:execute).with(subject) expect_any_instance_of(MergeRequests::ResolvedDiscussionNotificationService)
.to receive(:execute).with(subject)
subject.update_diff_discussion_positions(old_diff_refs: old_diff_refs,
new_diff_refs: new_diff_refs,
current_user: subject.author)
end
end
context 'when the active discussion does not have resolved in the update' do
let(:new_line) { 16 }
subject.update_diff_discussion_positions(old_diff_refs: old_diff_refs, it 'does not call the resolve method' do
new_diff_refs: commit.diff_refs, expect(MergeRequests::ResolvedDiscussionNotificationService).not_to receive(:new)
current_user: subject.author)
subject.update_diff_discussion_positions(old_diff_refs: old_diff_refs,
new_diff_refs: new_diff_refs,
current_user: subject.author)
end
end
context 'when the active discussion was already resolved' do
before do
discussion.resolve!(subject.author)
end
it 'does not call the resolve method' do
expect(MergeRequests::ResolvedDiscussionNotificationService).not_to receive(:new)
subject.update_diff_discussion_positions(old_diff_refs: old_diff_refs,
new_diff_refs: new_diff_refs,
current_user: subject.author)
end
end end
end 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