mirror of
https://github.com/discourse/discourse.git
synced 2025-02-07 16:45:01 +08:00
ea5c3a3bdc
In AdminDashboardData we have a bunch of problem checks implemented as methods on that class. This PR absolves it of the responsibility by promoting each of those checks to a first class ProblemCheck. This way each of them can have their own priority and arbitrary functionality can be isolated in its own class. Think "extract class" refactoring over and over. Since they were all moved we can also get rid of the @@problem_syms class variable which was basically the old version of the registry now replaced by ProblemCheck.realtime. In addition AdminDashboardData::Problem value object has been entirely replaced with the new ProblemCheck::Problem (with compatible API). Lastly, I added some RSpec matchers to simplify testing of problem checks and provide helpful error messages when assertions fail.
129 lines
4.6 KiB
Ruby
129 lines
4.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
RSpec.describe AdminDashboardData do
|
|
after do
|
|
AdminDashboardData.reset_problem_checks
|
|
Discourse.redis.flushdb
|
|
end
|
|
|
|
describe "#fetch_problems" do
|
|
describe "adding problem messages" do
|
|
it "adds the message and returns it when the problems are fetched" do
|
|
AdminDashboardData.add_problem_message("dashboard.bad_favicon_url")
|
|
problems = AdminDashboardData.fetch_problems.map(&:to_s)
|
|
expect(problems).to include(
|
|
I18n.t("dashboard.bad_favicon_url", { base_path: Discourse.base_path }),
|
|
)
|
|
end
|
|
|
|
it "does not allow adding of arbitrary problem messages, they must exist in AdminDashboardData.problem_messages" do
|
|
AdminDashboardData.add_problem_message("errors.messages.invalid")
|
|
problems = AdminDashboardData.fetch_problems.map(&:to_s)
|
|
expect(problems).not_to include(I18n.t("errors.messages.invalid"))
|
|
end
|
|
end
|
|
|
|
describe "adding new checks" do
|
|
it "calls the passed block" do
|
|
AdminDashboardData.add_problem_check { "a problem was found" }
|
|
|
|
problems = AdminDashboardData.fetch_problems
|
|
expect(problems.map(&:to_s)).to include("a problem was found")
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "adding scheduled checks" do
|
|
it "does not add duplicate problems with the same identifier" do
|
|
prob1 = ProblemCheck::Problem.new("test problem", identifier: "test")
|
|
prob2 = ProblemCheck::Problem.new("test problem 2", identifier: "test")
|
|
AdminDashboardData.add_found_scheduled_check_problem(prob1)
|
|
AdminDashboardData.add_found_scheduled_check_problem(prob2)
|
|
expect(AdminDashboardData.load_found_scheduled_check_problems.map(&:to_s)).to eq(
|
|
["test problem"],
|
|
)
|
|
end
|
|
|
|
it "does not error when loading malformed problems saved in redis" do
|
|
Discourse.redis.rpush(AdminDashboardData::SCHEDULED_PROBLEM_STORAGE_KEY, "{ 'badjson")
|
|
expect(AdminDashboardData.load_found_scheduled_check_problems).to eq([])
|
|
end
|
|
|
|
it "clears a specific problem by identifier" do
|
|
prob1 = ProblemCheck::Problem.new("test problem 1", identifier: "test")
|
|
AdminDashboardData.add_found_scheduled_check_problem(prob1)
|
|
AdminDashboardData.clear_found_problem("test")
|
|
expect(AdminDashboardData.load_found_scheduled_check_problems).to eq([])
|
|
end
|
|
|
|
it "defaults to low priority, and uses low priority if an invalid priority is passed" do
|
|
prob1 = ProblemCheck::Problem.new("test problem 1")
|
|
prob2 = ProblemCheck::Problem.new("test problem 2", priority: "superbad")
|
|
expect(prob1.priority).to eq("low")
|
|
expect(prob2.priority).to eq("low")
|
|
end
|
|
end
|
|
|
|
describe "stats cache" do
|
|
include_examples "stats cacheable"
|
|
end
|
|
|
|
describe "#problem_message_check" do
|
|
let(:key) { AdminDashboardData.problem_messages.first }
|
|
|
|
after { described_class.clear_problem_message(key) }
|
|
|
|
it "returns nil if message has not been added" do
|
|
expect(described_class.problem_message_check(key)).to be_nil
|
|
end
|
|
|
|
it "returns a message if it was added" do
|
|
described_class.add_problem_message(key)
|
|
expect(described_class.problem_message_check(key)).to eq(
|
|
I18n.t(key, base_path: Discourse.base_path),
|
|
)
|
|
end
|
|
|
|
it "returns a message if it was added with an expiry" do
|
|
described_class.add_problem_message(key, 300)
|
|
expect(described_class.problem_message_check(key)).to eq(
|
|
I18n.t(key, base_path: Discourse.base_path),
|
|
)
|
|
end
|
|
end
|
|
|
|
describe "sidekiq_check" do
|
|
subject(:check) { described_class.new.sidekiq_check }
|
|
|
|
it "returns nil when sidekiq processed a job recently" do
|
|
Jobs.stubs(:last_job_performed_at).returns(1.minute.ago)
|
|
Jobs.stubs(:queued).returns(0)
|
|
expect(check).to be_nil
|
|
end
|
|
|
|
it "returns nil when last job processed was a long time ago, but no jobs are queued" do
|
|
Jobs.stubs(:last_job_performed_at).returns(7.days.ago)
|
|
Jobs.stubs(:queued).returns(0)
|
|
expect(check).to be_nil
|
|
end
|
|
|
|
it "returns nil when no jobs have ever been processed, but no jobs are queued" do
|
|
Jobs.stubs(:last_job_performed_at).returns(nil)
|
|
Jobs.stubs(:queued).returns(0)
|
|
expect(check).to be_nil
|
|
end
|
|
|
|
it "returns a string when no jobs were processed recently and some jobs are queued" do
|
|
Jobs.stubs(:last_job_performed_at).returns(20.minutes.ago)
|
|
Jobs.stubs(:queued).returns(1)
|
|
expect(check).to_not be_nil
|
|
end
|
|
|
|
it "returns a string when no jobs have ever been processed, and some jobs are queued" do
|
|
Jobs.stubs(:last_job_performed_at).returns(nil)
|
|
Jobs.stubs(:queued).returns(1)
|
|
expect(check).to_not be_nil
|
|
end
|
|
end
|
|
end
|