From 17e4345eb2a9e63876afcc225afbdf7fd6ca057f Mon Sep 17 00:00:00 2001
From: Claire <claire.github-309c@sitedethib.com>
Date: Mon, 28 Apr 2025 12:07:22 +0200
Subject: [PATCH] Add `quoted_status` attribute to `PostStatusService` for
 local testing (#34553)

---
 app/services/post_status_service.rb | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb
index 765c80723e..ac4b535ea9 100644
--- a/app/services/post_status_service.rb
+++ b/app/services/post_status_service.rb
@@ -18,6 +18,7 @@ class PostStatusService < BaseService
   # @param [Hash] options
   # @option [String] :text Message
   # @option [Status] :thread Optional status to reply to
+  # @option [Status] :quoted_status Optional status to quote
   # @option [Boolean] :sensitive
   # @option [String] :visibility
   # @option [String] :spoiler_text
@@ -35,6 +36,7 @@ class PostStatusService < BaseService
     @options     = options
     @text        = @options[:text] || ''
     @in_reply_to = @options[:thread]
+    @quoted_status = @options[:quoted_status]
 
     @antispam = Antispam.new
 
@@ -78,6 +80,7 @@ class PostStatusService < BaseService
     @status = @account.statuses.new(status_attributes)
     process_mentions_service.call(@status, save_records: false)
     safeguard_mentions!(@status)
+    attach_quote!(@status)
     @antispam.local_preflight_check!(@status)
 
     # The following transaction block is needed to wrap the UPDATEs to
@@ -87,6 +90,21 @@ class PostStatusService < BaseService
     end
   end
 
+  def attach_quote!(status)
+    return if @quoted_status.nil?
+
+    # NOTE: for now this is only for convenience in testing, as we don't support the request flow nor serialize quotes in ActivityPub
+    # we only support incoming quotes so far
+
+    status.quote = Quote.new(quoted_status: @quoted_status)
+    status.quote.accept! if @status.account == @quoted_status.account || @quoted_status.active_mentions.exists?(mentions: { account_id: status.account_id })
+
+    # TODO: the following has yet to be implemented:
+    # - handle approval of local users (requires the interactionPolicy PR)
+    # - produce a QuoteAuthorization for quotes of local users
+    # - send a QuoteRequest for quotes of remote users
+  end
+
   def safeguard_mentions!(status)
     return if @options[:allowed_mentions].nil?
 
@@ -223,6 +241,7 @@ class PostStatusService < BaseService
     @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[:quoted_status_id] = options_hash.delete(:quoted_status)&.id
       options_hash[:scheduled_at]    = nil
       options_hash[:idempotency]     = nil
       options_hash[:with_rate_limit] = false