diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index e8c9dd8c4df92e..63bafa6bab24f3 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -231,7 +231,7 @@ def idempotency_given? def idempotency_duplicate if scheduled? - @account.schedule_statuses.find(@idempotency_duplicate) + @account.scheduled_statuses.find(@idempotency_duplicate) else @account.statuses.find(@idempotency_duplicate) end @@ -292,12 +292,12 @@ def poll_attributes end def scheduled_options - @options.tap do |options_hash| - options_hash[:in_reply_to_id] = options_hash.delete(:thread)&.id&.to_s + @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 options_hash[:idempotency] = nil - options_hash[:status_reference_ids] = options_hash[:status_reference_ids]&.map(&:to_s)&.filter{ |id| id != options_hash[:quote_id] } + options_hash[:status_reference_ids] = options_hash.delete(:status_reference_ids)&.map(&:to_s)&.filter{ |id| id != options_hash[:quote_id] } options_hash[:with_rate_limit] = false end end diff --git a/spec/services/post_status_service_spec.rb b/spec/services/post_status_service_spec.rb index 15a4c6fb77f538..a1bb678ca3a7fb 100644 --- a/spec/services/post_status_service_spec.rb +++ b/spec/services/post_status_service_spec.rb @@ -68,6 +68,22 @@ expect(status.params['text']).to eq 'Hi future!' expect(media.reload.status).to be_nil expect(Status.where(text: 'Hi future!').exists?).to be_falsey + + it 'does not change statuses count' do + account = Fabricate(:account) + future = Time.now.utc + 2.hours + previous_status = Fabricate(:status, account: account) + + expect { subject.call(account, text: 'Hi future!', scheduled_at: future, thread: previous_status) }.not_to change { [account.statuses_count, previous_status.replies_count] } + end + + it 'returns existing status when used twice with idempotency key' do + account = Fabricate(:account) + future = Time.now.utc + 2.hours + + 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 it 'creates response to the original status of boost' do