2023-02-22 00:55:31 +00:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2021-08-09 21:11:50 +00:00
|
|
|
require 'rails_helper'
|
|
|
|
|
2024-09-04 05:12:25 +00:00
|
|
|
RSpec.describe AccountStatusesCleanupService do
|
2021-08-09 21:11:50 +00:00
|
|
|
let(:account) { Fabricate(:account, username: 'alice', domain: nil) }
|
|
|
|
let(:account_policy) { Fabricate(:account_statuses_cleanup_policy, account: account) }
|
|
|
|
let!(:unrelated_status) { Fabricate(:status, created_at: 3.years.ago) }
|
|
|
|
|
|
|
|
describe '#call' do
|
|
|
|
context 'when the account has not posted anything' do
|
|
|
|
it 'returns 0 deleted toots' do
|
|
|
|
expect(subject.call(account_policy)).to eq 0
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the account has posted several old statuses' do
|
|
|
|
let!(:very_old_status) { Fabricate(:status, created_at: 3.years.ago, account: account) }
|
|
|
|
let!(:old_status) { Fabricate(:status, created_at: 1.year.ago, account: account) }
|
|
|
|
let!(:another_old_status) { Fabricate(:status, created_at: 1.year.ago, account: account) }
|
|
|
|
let!(:recent_status) { Fabricate(:status, created_at: 1.day.ago, account: account) }
|
|
|
|
|
2023-05-04 03:49:08 +00:00
|
|
|
context 'when given a budget of 1' do
|
2021-08-09 21:11:50 +00:00
|
|
|
it 'reports 1 deleted toot' do
|
|
|
|
expect(subject.call(account_policy, 1)).to eq 1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-05-04 03:49:08 +00:00
|
|
|
context 'when given a normal budget of 10' do
|
2024-10-04 14:11:15 +00:00
|
|
|
it 'reports 3 deleted statuses and records last deleted id, deletes statuses, preserves recent unrelated statuses' do
|
|
|
|
expect(subject.call(account_policy, 10))
|
|
|
|
.to eq(3)
|
|
|
|
|
|
|
|
expect(account_policy.last_inspected)
|
|
|
|
.to eq [old_status.id, another_old_status.id].max
|
|
|
|
|
|
|
|
expect(Status.find_by(id: [very_old_status.id, old_status.id, another_old_status.id]))
|
|
|
|
.to be_nil
|
|
|
|
expect { recent_status.reload }
|
|
|
|
.to_not raise_error
|
|
|
|
expect { unrelated_status.reload }
|
|
|
|
.to_not raise_error
|
|
|
|
expect { recent_status.reload }
|
|
|
|
.to_not raise_error
|
2021-08-09 21:11:50 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when called repeatedly with a budget of 2' do
|
2024-10-04 14:11:15 +00:00
|
|
|
it 'reports 2 then 1 deleted statuses and deletes in expected order' do
|
|
|
|
expect(subject.call(account_policy, 2))
|
|
|
|
.to eq(2)
|
|
|
|
expect(Status.find_by(id: very_old_status.id))
|
|
|
|
.to be_nil
|
|
|
|
|
|
|
|
expect(subject.call(account_policy, 2))
|
|
|
|
.to eq(1)
|
|
|
|
expect(Status.find_by(id: [very_old_status.id, old_status.id, another_old_status.id]))
|
|
|
|
.to be_nil
|
2021-08-09 21:11:50 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when a self-faved toot is unfaved' do
|
|
|
|
let!(:self_faved) { Fabricate(:status, created_at: 6.months.ago, account: account) }
|
|
|
|
let!(:favourite) { Fabricate(:favourite, account: account, status: self_faved) }
|
|
|
|
|
|
|
|
it 'deletes it once unfaved' do
|
|
|
|
expect(subject.call(account_policy, 20)).to eq 3
|
|
|
|
expect(Status.find_by(id: self_faved.id)).to_not be_nil
|
|
|
|
expect(subject.call(account_policy, 20)).to eq 0
|
|
|
|
favourite.destroy!
|
|
|
|
expect(subject.call(account_policy, 20)).to eq 1
|
|
|
|
expect(Status.find_by(id: self_faved.id)).to be_nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when there are more un-deletable old toots than the early search cutoff' do
|
|
|
|
before do
|
|
|
|
stub_const 'AccountStatusesCleanupPolicy::EARLY_SEARCH_CUTOFF', 5
|
|
|
|
# Old statuses that should be cut-off
|
|
|
|
10.times do
|
|
|
|
Fabricate(:status, created_at: 4.years.ago, visibility: :direct, account: account)
|
|
|
|
end
|
|
|
|
# New statuses that prevent cut-off id to reach the last status
|
|
|
|
10.times do
|
|
|
|
Fabricate(:status, created_at: 4.seconds.ago, visibility: :direct, account: account)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-10-04 14:11:15 +00:00
|
|
|
it 'reports 0 deleted statuses then 0 then 3 then 0 again, and keeps id under oldest deletable record' do
|
|
|
|
expect(subject.call(account_policy, 10))
|
|
|
|
.to eq(0)
|
|
|
|
expect(subject.call(account_policy, 10))
|
|
|
|
.to eq(0)
|
|
|
|
expect(subject.call(account_policy, 10))
|
|
|
|
.to eq(3)
|
|
|
|
expect(subject.call(account_policy, 10))
|
|
|
|
.to eq(0)
|
|
|
|
expect(account_policy.last_inspected)
|
|
|
|
.to be < oldest_deletable_record_id
|
2021-08-09 21:11:50 +00:00
|
|
|
end
|
|
|
|
|
2024-10-04 14:11:15 +00:00
|
|
|
def oldest_deletable_record_id
|
|
|
|
Mastodon::Snowflake.id_at(
|
|
|
|
account_policy.min_status_age.seconds.ago,
|
|
|
|
with_random: false
|
|
|
|
)
|
2021-08-09 21:11:50 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|