From 82fb2596c70a18fc4a2d99ab51106180196bfe98 Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 5 Jan 2026 16:06:20 +0100 Subject: [PATCH] Fix posts with edited out media attachments being returned in `/api/v1/accounts/:id/statuses?only_media=true` (#37363) --- app/lib/account_statuses_filter.rb | 2 +- app/models/status.rb | 1 + spec/requests/api/v1/accounts/statuses_spec.rb | 18 +++++++++++++++++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/app/lib/account_statuses_filter.rb b/app/lib/account_statuses_filter.rb index cfc9be9660..92196b6da4 100644 --- a/app/lib/account_statuses_filter.rb +++ b/app/lib/account_statuses_filter.rb @@ -70,7 +70,7 @@ class AccountStatusesFilter end def only_media_scope - Status.joins(:media_attachments).merge(account.media_attachments).group(Status.arel_table[:id]) + Status.without_empty_attachments.joins(:media_attachments).merge(account.media_attachments).group(Status.arel_table[:id]) end def no_replies_scope diff --git a/app/models/status.rb b/app/models/status.rb index 59fd518a88..8ee290b297 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -136,6 +136,7 @@ class Status < ApplicationRecord scope :tagged_with_none, lambda { |tag_ids| where('NOT EXISTS (SELECT * FROM statuses_tags forbidden WHERE forbidden.status_id = statuses.id AND forbidden.tag_id IN (?))', tag_ids) } + scope :without_empty_attachments, -> { where(ordered_media_attachment_ids: nil).or(where.not(ordered_media_attachment_ids: [])) } after_create_commit :trigger_create_webhooks after_update_commit :trigger_update_webhooks diff --git a/spec/requests/api/v1/accounts/statuses_spec.rb b/spec/requests/api/v1/accounts/statuses_spec.rb index 0a1daa0488..6ba3b47ff0 100644 --- a/spec/requests/api/v1/accounts/statuses_spec.rb +++ b/spec/requests/api/v1/accounts/statuses_spec.rb @@ -21,12 +21,28 @@ RSpec.describe 'API V1 Accounts Statuses' do end context 'with only media' do - it 'returns http success' do + let(:status_attachments) { [Fabricate(:media_attachment, account: user.account)] } + let(:removed_status_attachments) { [Fabricate(:media_attachment, account: user.account)] } + let!(:status_with_unordered_attachments) { Fabricate(:status, account: user.account, media_attachments: [Fabricate(:media_attachment, account: user.account)]) } + let!(:status) { Fabricate(:status, account: user.account, media_attachments: status_attachments, ordered_media_attachment_ids: status_attachments.pluck(:id)) } + let!(:status_with_edited_out_media) { Fabricate(:status, account: user.account, media_attachments: removed_status_attachments, ordered_media_attachment_ids: removed_status_attachments.pluck(:id)) } + + before do + UpdateStatusService.new.call(status_with_edited_out_media, user.account_id, text: 'edited', media_ids: []) + end + + it 'returns http success with expected statuses' do get "/api/v1/accounts/#{user.account.id}/statuses", params: { only_media: true }, headers: headers expect(response).to have_http_status(200) expect(response.content_type) .to start_with('application/json') + expect(response.parsed_body) + .to have_attributes(size: 2) + .and contain_exactly( + include(id: status_with_unordered_attachments.id.to_s), + include(id: status.id.to_s) + ) end end