account_statuses_cleanup_service_spec.rb 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. # frozen_string_literal: true
  2. require 'rails_helper'
  3. describe AccountStatusesCleanupService, type: :service do
  4. let(:account) { Fabricate(:account, username: 'alice', domain: nil) }
  5. let(:account_policy) { Fabricate(:account_statuses_cleanup_policy, account: account) }
  6. let!(:unrelated_status) { Fabricate(:status, created_at: 3.years.ago) }
  7. describe '#call' do
  8. context 'when the account has not posted anything' do
  9. it 'returns 0 deleted toots' do
  10. expect(subject.call(account_policy)).to eq 0
  11. end
  12. end
  13. context 'when the account has posted several old statuses' do
  14. let!(:very_old_status) { Fabricate(:status, created_at: 3.years.ago, account: account) }
  15. let!(:old_status) { Fabricate(:status, created_at: 1.year.ago, account: account) }
  16. let!(:another_old_status) { Fabricate(:status, created_at: 1.year.ago, account: account) }
  17. let!(:recent_status) { Fabricate(:status, created_at: 1.day.ago, account: account) }
  18. context 'when given a budget of 1' do
  19. it 'reports 1 deleted toot' do
  20. expect(subject.call(account_policy, 1)).to eq 1
  21. end
  22. end
  23. context 'when given a normal budget of 10' do
  24. it 'reports 3 deleted statuses' do
  25. expect(subject.call(account_policy, 10)).to eq 3
  26. end
  27. it 'records the last deleted id' do
  28. subject.call(account_policy, 10)
  29. expect(account_policy.last_inspected).to eq [old_status.id, another_old_status.id].max
  30. end
  31. it 'actually deletes the statuses' do
  32. subject.call(account_policy, 10)
  33. expect(Status.find_by(id: [very_old_status.id, old_status.id, another_old_status.id])).to be_nil
  34. expect { recent_status.reload }.to_not raise_error
  35. end
  36. it 'preserves recent and unrelated statuses' do
  37. subject.call(account_policy, 10)
  38. expect { unrelated_status.reload }.to_not raise_error
  39. expect { recent_status.reload }.to_not raise_error
  40. end
  41. end
  42. context 'when called repeatedly with a budget of 2' do
  43. it 'reports 2 then 1 deleted statuses' do
  44. expect(subject.call(account_policy, 2)).to eq 2
  45. expect(subject.call(account_policy, 2)).to eq 1
  46. end
  47. it 'actually deletes the statuses in the expected order' do
  48. subject.call(account_policy, 2)
  49. expect(Status.find_by(id: very_old_status.id)).to be_nil
  50. subject.call(account_policy, 2)
  51. expect(Status.find_by(id: [very_old_status.id, old_status.id, another_old_status.id])).to be_nil
  52. end
  53. end
  54. context 'when a self-faved toot is unfaved' do
  55. let!(:self_faved) { Fabricate(:status, created_at: 6.months.ago, account: account) }
  56. let!(:favourite) { Fabricate(:favourite, account: account, status: self_faved) }
  57. it 'deletes it once unfaved' do
  58. expect(subject.call(account_policy, 20)).to eq 3
  59. expect(Status.find_by(id: self_faved.id)).to_not be_nil
  60. expect(subject.call(account_policy, 20)).to eq 0
  61. favourite.destroy!
  62. expect(subject.call(account_policy, 20)).to eq 1
  63. expect(Status.find_by(id: self_faved.id)).to be_nil
  64. end
  65. end
  66. context 'when there are more un-deletable old toots than the early search cutoff' do
  67. before do
  68. stub_const 'AccountStatusesCleanupPolicy::EARLY_SEARCH_CUTOFF', 5
  69. # Old statuses that should be cut-off
  70. 10.times do
  71. Fabricate(:status, created_at: 4.years.ago, visibility: :direct, account: account)
  72. end
  73. # New statuses that prevent cut-off id to reach the last status
  74. 10.times do
  75. Fabricate(:status, created_at: 4.seconds.ago, visibility: :direct, account: account)
  76. end
  77. end
  78. it 'reports 0 deleted statuses then 0 then 3 then 0 again' do
  79. expect(subject.call(account_policy, 10)).to eq 0
  80. expect(subject.call(account_policy, 10)).to eq 0
  81. expect(subject.call(account_policy, 10)).to eq 3
  82. expect(subject.call(account_policy, 10)).to eq 0
  83. end
  84. it 'never causes the recorded id to get higher than oldest deletable toot' do
  85. subject.call(account_policy, 10)
  86. subject.call(account_policy, 10)
  87. subject.call(account_policy, 10)
  88. subject.call(account_policy, 10)
  89. expect(account_policy.last_inspected).to be < Mastodon::Snowflake.id_at(account_policy.min_status_age.seconds.ago, with_random: false)
  90. end
  91. end
  92. end
  93. end
  94. end