From e839a94b9397f8e7d30d1d22ce668b3050fa4042 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 18 Mar 2026 05:11:14 -0400 Subject: [PATCH] Use `with_index` iterator in backup service (#38264) --- app/services/backup_service.rb | 19 ++++++----------- spec/services/backup_service_spec.rb | 32 +++++++++++++++++----------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/app/services/backup_service.rb b/app/services/backup_service.rb index bbe655b71a..0aede0145d 100644 --- a/app/services/backup_service.rb +++ b/app/services/backup_service.rb @@ -25,13 +25,11 @@ class BackupService < BaseService skeleton[:orderedItems] = ['!PLACEHOLDER!'] skeleton = JSON.generate(skeleton) prepend, append = skeleton.split('"!PLACEHOLDER!"') - add_comma = false file.write(prepend) - account.statuses.with_includes.reorder(nil).find_in_batches do |statuses| - file.write(',') if add_comma - add_comma = true + account.statuses.with_includes.reorder(nil).find_in_batches.with_index do |statuses, batch| + file.write(',') unless batch.zero? file.write(statuses.map do |status| serializer = status.reblog? ? ActivityPub::AnnounceNoteSerializer : ActivityPub::CreateNoteSerializer @@ -124,11 +122,8 @@ class BackupService < BaseService zipfile.get_output_stream('likes.json') do |io| io.write(prepend) - add_comma = false - - Status.reorder(nil).joins(:favourites).includes(:account).merge(account.favourites).find_in_batches do |statuses| - io.write(',') if add_comma - add_comma = true + Status.reorder(nil).joins(:favourites).includes(:account).merge(account.favourites).find_in_batches.with_index do |statuses, batch| + io.write(',') unless batch.zero? io.write(statuses.map do |status| JSON.generate(ActivityPub::TagManager.instance.uri_for(status)) @@ -151,10 +146,8 @@ class BackupService < BaseService zipfile.get_output_stream('bookmarks.json') do |io| io.write(prepend) - add_comma = false - Status.reorder(nil).joins(:bookmarks).includes(:account).merge(account.bookmarks).find_in_batches do |statuses| - io.write(',') if add_comma - add_comma = true + Status.reorder(nil).joins(:bookmarks).includes(:account).merge(account.bookmarks).find_in_batches.with_index do |statuses, batch| + io.write(',') unless batch.zero? io.write(statuses.map do |status| JSON.generate(ActivityPub::TagManager.instance.uri_for(status)) diff --git a/spec/services/backup_service_spec.rb b/spec/services/backup_service_spec.rb index 1dcebc24d2..1ca5600097 100644 --- a/spec/services/backup_service_spec.rb +++ b/spec/services/backup_service_spec.rb @@ -10,7 +10,9 @@ RSpec.describe BackupService do let!(:status) { Fabricate(:status, account: user.account, text: 'Hello', visibility: :public, media_attachments: [attachment]) } let!(:private_status) { Fabricate(:status, account: user.account, text: 'secret', visibility: :private) } let!(:favourite) { Fabricate(:favourite, account: user.account) } + let!(:more_favourite) { Fabricate(:favourite, account: user.account) } let!(:bookmark) { Fabricate(:bookmark, account: user.account) } + let!(:more_bookmark) { Fabricate(:bookmark, account: user.account) } let!(:backup) { Fabricate(:backup, user: user) } def read_zip_file(backup, filename) @@ -71,21 +73,27 @@ RSpec.describe BackupService do end def expect_likes_export - json = export_json(:likes) - - aggregate_failures do - expect(json['type']).to eq 'OrderedCollection' - expect(json['orderedItems']).to eq [ActivityPub::TagManager.instance.uri_for(favourite.status)] - end + expect(export_json(:likes).deep_symbolize_keys) + .to include( + id: 'likes.json', + type: 'OrderedCollection', + orderedItems: contain_exactly( + ActivityPub::TagManager.instance.uri_for(favourite.status), + ActivityPub::TagManager.instance.uri_for(more_favourite.status) + ) + ) end def expect_bookmarks_export - json = export_json(:bookmarks) - - aggregate_failures do - expect(json['type']).to eq 'OrderedCollection' - expect(json['orderedItems']).to eq [ActivityPub::TagManager.instance.uri_for(bookmark.status)] - end + expect(export_json(:bookmarks).deep_symbolize_keys) + .to include( + id: 'bookmarks.json', + type: 'OrderedCollection', + orderedItems: contain_exactly( + ActivityPub::TagManager.instance.uri_for(bookmark.status), + ActivityPub::TagManager.instance.uri_for(more_bookmark.status) + ) + ) end def export_json_raw(type)