M lib/mastodon/cli/cache.rb => lib/mastodon/cli/cache.rb +34 -14
@@ 23,22 23,12 @@ module Mastodon::CLI
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)
@@ 48,5 38,35 @@ module Mastodon::CLI
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
A spec/fabricators/status_stat_fabricator.rb => spec/fabricators/status_stat_fabricator.rb +8 -0
@@ 0,0 1,8 @@
+# frozen_string_literal: true
+
+Fabricator(:status_stat) do
+ status
+ replies_count '123'
+ reblogs_count '456'
+ favourites_count '789'
+end
M spec/lib/mastodon/cli/cache_spec.rb => spec/lib/mastodon/cli/cache_spec.rb +59 -0
@@ 4,9 4,68 @@ require 'rails_helper'
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
M spec/rails_helper.rb => spec/rails_helper.rb +12 -0
@@ 79,6 79,7 @@ RSpec.configure do |config|
config.before :each, type: :cli do
stub_stdout
+ stub_reset_connection_pools
end
config.before :each, type: :feature do
@@ 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'))