Commit 862c76f0 authored by Robert Speicher's avatar Robert Speicher

Merge branch 'sh-fix-discussion-note-promotion-failure-handling' into 'master'

Ensure note is promoted to discussion within reply create transaction

See merge request gitlab-org/gitlab!53542
parents a06beceb 74f6b50a
...@@ -27,7 +27,11 @@ module Notes ...@@ -27,7 +27,11 @@ module Notes
end end
note_saved = note.with_transaction_returning_status do note_saved = note.with_transaction_returning_status do
!only_commands && note.save break false if only_commands
note.save.tap do
update_discussions(note)
end
end end
when_saved(note) if note_saved when_saved(note) if note_saved
...@@ -54,12 +58,17 @@ module Notes ...@@ -54,12 +58,17 @@ module Notes
@quick_actions_service ||= QuickActionsService.new(project, current_user) @quick_actions_service ||= QuickActionsService.new(project, current_user)
end end
def when_saved(note) def update_discussions(note)
# Ensure that individual notes that are promoted into discussions are
# updated in a transaction with the note creation to avoid inconsistencies:
# https://gitlab.com/gitlab-org/gitlab/-/issues/301237
if note.part_of_discussion? && note.discussion.can_convert_to_discussion? if note.part_of_discussion? && note.discussion.can_convert_to_discussion?
note.discussion.convert_to_discussion!.save note.discussion.convert_to_discussion!.save
note.clear_memoization(:discussion) note.clear_memoization(:discussion)
end end
end
def when_saved(note)
todo_service.new_note(note, current_user) todo_service.new_note(note, current_user)
clear_noteable_diffs_cache(note) clear_noteable_diffs_cache(note)
Suggestions::CreateService.new(note).execute Suggestions::CreateService.new(note).execute
......
---
title: Ensure note is promoted to discussion within reply create transaction
merge_request: 53542
author:
type: fixed
...@@ -459,6 +459,26 @@ RSpec.describe Notes::CreateService do ...@@ -459,6 +459,26 @@ RSpec.describe Notes::CreateService do
.and change { existing_note.updated_at } .and change { existing_note.updated_at }
end end
context 'failure in when_saved' do
let(:service) { described_class.new(project, user, reply_opts) }
it 'converts existing note to DiscussionNote' do
expect do
existing_note
allow(service).to receive(:when_saved).and_raise(ActiveRecord::StatementInvalid)
travel_to(Time.current + 1.minute) do
service.execute
rescue ActiveRecord::StatementInvalid
end
existing_note.reload
end.to change { existing_note.type }.from(nil).to('DiscussionNote')
.and change { existing_note.updated_at }
end
end
it 'returns a DiscussionNote with its parent discussion refreshed correctly' do it 'returns a DiscussionNote with its parent discussion refreshed correctly' do
discussion_notes = subject.discussion.notes discussion_notes = subject.discussion.notes
......
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