From 51ef619140fc87c23352aced941e313e8aa1c699 Mon Sep 17 00:00:00 2001
From: Claire <claire.github-309c@sitedethib.com>
Date: Fri, 26 Apr 2024 15:19:02 +0200
Subject: [PATCH] Fix Idempotency-Key ignored when scheduling a post (#30084)

---
 app/services/post_status_service.rb       | 4 ++--
 spec/services/post_status_service_spec.rb | 7 +++++++
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb
index ea27f374e7..e4dd480f10 100644
--- a/app/services/post_status_service.rb
+++ b/app/services/post_status_service.rb
@@ -160,7 +160,7 @@ class PostStatusService < BaseService
 
   def idempotency_duplicate
     if scheduled?
-      @account.schedule_statuses.find(@idempotency_duplicate)
+      @account.scheduled_statuses.find(@idempotency_duplicate)
     else
       @account.statuses.find(@idempotency_duplicate)
     end
@@ -214,7 +214,7 @@ class PostStatusService < BaseService
   end
 
   def scheduled_options
-    @options.tap do |options_hash|
+    @options.dup.tap do |options_hash|
       options_hash[:in_reply_to_id]  = options_hash.delete(:thread)&.id
       options_hash[:application_id]  = options_hash.delete(:application)&.id
       options_hash[:scheduled_at]    = nil
diff --git a/spec/services/post_status_service_spec.rb b/spec/services/post_status_service_spec.rb
index 7d7679c889..a74e826261 100644
--- a/spec/services/post_status_service_spec.rb
+++ b/spec/services/post_status_service_spec.rb
@@ -54,6 +54,13 @@ RSpec.describe PostStatusService, type: :service do
     it 'does not change statuses count' do
       expect { subject.call(account, text: 'Hi future!', scheduled_at: future, thread: previous_status) }.to_not(change { [account.statuses_count, previous_status.replies_count] })
     end
+
+    it 'returns existing status when used twice with idempotency key' do
+      account = Fabricate(:account)
+      status1 = subject.call(account, text: 'test', idempotency: 'meepmeep', scheduled_at: future)
+      status2 = subject.call(account, text: 'test', idempotency: 'meepmeep', scheduled_at: future)
+      expect(status2.id).to eq status1.id
+    end
   end
 
   it 'creates response to the original status of boost' do