From 10f0de42129d17fd28fc6ff92b77d49156b0185b Mon Sep 17 00:00:00 2001
From: Matt Jankowski <matt@jankowski.online>
Date: Fri, 14 Apr 2023 08:42:10 -0400
Subject: [PATCH] Refactor race condition reblog service spec (#24526)

---
 spec/services/reblog_service_spec.rb | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/spec/services/reblog_service_spec.rb b/spec/services/reblog_service_spec.rb
index fdf5ec923c..2ad6d30f6b 100644
--- a/spec/services/reblog_service_spec.rb
+++ b/spec/services/reblog_service_spec.rb
@@ -35,13 +35,25 @@ RSpec.describe ReblogService, type: :service do
   end
 
   context 'when the reblogged status is discarded in the meantime' do
-    let(:status) { Fabricate(:status, account: alice, visibility: :public) }
+    let(:status) { Fabricate(:status, account: alice, visibility: :public, text: 'discard-status-text') }
 
+    # Add a callback to discard the status being reblogged after the
+    # validations pass but before the database commit is executed.
     before do
-      # Update the in-database attribute without reflecting the change in
-      # the object. This cannot simulate all race conditions, but it is
-      # pretty close.
-      Status.where(id: status.id).update_all(deleted_at: Time.now.utc) # rubocop:disable Rails/SkipsModelValidations
+      Status.class_eval do
+        before_save :discard_status
+        def discard_status
+          Status
+            .where(id: reblog_of_id)
+            .where(text: 'discard-status-text')
+            .update_all(deleted_at: Time.now.utc) # rubocop:disable Rails/SkipsModelValidations
+        end
+      end
+    end
+
+    # Remove race condition simulating `discard_status` callback.
+    after do
+      Status._save_callbacks.delete(:discard_status)
     end
 
     it 'raises an exception' do
-- 
GitLab