Skip to content

Commit

Permalink
Add coverage for CLI::Cache command (mastodon#25238)
Browse files Browse the repository at this point in the history
  • Loading branch information
mjankowski authored and skerit committed Jul 7, 2023
1 parent 49d8e5f commit 2f77e81
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 14 deletions.
48 changes: 34 additions & 14 deletions lib/mastodon/cli/cache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,12 @@ def clear
def recount(type)
case type
when 'accounts'
processed, = parallelize_with_progress(Account.local.includes(:account_stat)) do |account|
account_stat = account.account_stat
account_stat.following_count = account.active_relationships.count
account_stat.followers_count = account.passive_relationships.count
account_stat.statuses_count = account.statuses.where.not(visibility: :direct).count

account_stat.save if account_stat.changed?
processed, = parallelize_with_progress(accounts_with_stats) do |account|
recount_account_stats(account)
end
when 'statuses'
processed, = parallelize_with_progress(Status.includes(:status_stat)) do |status|
status_stat = status.status_stat
status_stat.replies_count = status.replies.where.not(visibility: :direct).count
status_stat.reblogs_count = status.reblogs.count
status_stat.favourites_count = status.favourites.count

status_stat.save if status_stat.changed?
processed, = parallelize_with_progress(statuses_with_stats) do |status|
recount_status_stats(status)
end
else
say("Unknown type: #{type}", :red)
Expand All @@ -48,5 +38,35 @@ def recount(type)
say
say("OK, recounted #{processed} records", :green)
end

private

def accounts_with_stats
Account.local.includes(:account_stat)
end

def statuses_with_stats
Status.includes(:status_stat)
end

def recount_account_stats(account)
account.account_stat.tap do |account_stat|
account_stat.following_count = account.active_relationships.count
account_stat.followers_count = account.passive_relationships.count
account_stat.statuses_count = account.statuses.where.not(visibility: :direct).count

account_stat.save if account_stat.changed?
end
end

def recount_status_stats(status)
status.status_stat.tap do |status_stat|
status_stat.replies_count = status.replies.where.not(visibility: :direct).count
status_stat.reblogs_count = status.reblogs.count
status_stat.favourites_count = status.favourites.count

status_stat.save if status_stat.changed?
end
end
end
end
8 changes: 8 additions & 0 deletions spec/fabricators/status_stat_fabricator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

Fabricator(:status_stat) do
status
replies_count '123'
reblogs_count '456'
favourites_count '789'
end
59 changes: 59 additions & 0 deletions spec/lib/mastodon/cli/cache_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,68 @@
require 'mastodon/cli/cache'

describe Mastodon::CLI::Cache do
let(:cli) { described_class.new }

describe '.exit_on_failure?' do
it 'returns true' do
expect(described_class.exit_on_failure?).to be true
end
end

describe '#clear' do
before { allow(Rails.cache).to receive(:clear) }

it 'clears the Rails cache' do
expect { cli.invoke(:clear) }.to output(
a_string_including('OK')
).to_stdout
expect(Rails.cache).to have_received(:clear)
end
end

describe '#recount' do
context 'with the `accounts` argument' do
let(:arguments) { ['accounts'] }
let(:account_stat) { Fabricate(:account_stat) }

before do
account_stat.update(statuses_count: 123)
end

it 're-calculates account records in the cache' do
expect { cli.invoke(:recount, arguments) }.to output(
a_string_including('OK')
).to_stdout

expect(account_stat.reload.statuses_count).to be_zero
end
end

context 'with the `statuses` argument' do
let(:arguments) { ['statuses'] }
let(:status_stat) { Fabricate(:status_stat) }

before do
status_stat.update(replies_count: 123)
end

it 're-calculates account records in the cache' do
expect { cli.invoke(:recount, arguments) }.to output(
a_string_including('OK')
).to_stdout

expect(status_stat.reload.replies_count).to be_zero
end
end

context 'with an unknown type' do
let(:arguments) { ['other-type'] }

it 'Exits with an error message' do
expect { cli.invoke(:recount, arguments) }.to output(
a_string_including('Unknown')
).to_stdout.and raise_error(SystemExit)
end
end
end
end
12 changes: 12 additions & 0 deletions spec/rails_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ def get(path, headers: nil, sign_with: nil, **args)

config.before :each, type: :cli do
stub_stdout
stub_reset_connection_pools
end

config.before :each, type: :feature do
Expand Down Expand Up @@ -121,9 +122,20 @@ def attachment_fixture(name)
end

def stub_stdout
# TODO: Is there a bettery way to:
# - Avoid CLI command output being printed out
# - Allow rspec to assert things against STDOUT
# - Avoid disabling stdout for other desirable output (deprecation warnings, for example)
allow($stdout).to receive(:write)
end

def stub_reset_connection_pools
# TODO: Is there a better way to correctly run specs without stubbing this?
# (Avoids reset_connection_pools! in test env)
allow(ActiveRecord::Base).to receive(:establish_connection)
allow(RedisConfiguration).to receive(:establish_pool)
end

def stub_jsonld_contexts!
stub_request(:get, 'https://www.w3.org/ns/activitystreams').to_return(request_fixture('json-ld.activitystreams.txt'))
stub_request(:get, 'https://w3id.org/identity/v1').to_return(request_fixture('json-ld.identity.txt'))
Expand Down

0 comments on commit 2f77e81

Please sign in to comment.