DEV: Make problem check registration more explicit (#26413)

Previously the problem check registry simply looked at the subclasses of ProblemCheck. This was causing some confusion in environments where eager loading is not enabled, as the registry would appear empty as a result of the classes never being referenced (and thus never loaded.)

This PR changes the approach to a more explicit one. I followed other implementations (bookmarkable and hashtag autocomplete.) As a bonus, this now has a neat plugin entry point as well.
This commit is contained in:
Ted Johansson
2024-03-28 14:00:47 +08:00
committed by GitHub
parent e04b35a184
commit 0c875cb4d5
6 changed files with 95 additions and 19 deletions
+26 -10
View File
@@ -1,14 +1,10 @@
# frozen_string_literal: true
RSpec.describe Jobs::RunProblemCheck do
after do
Discourse.redis.flushdb
ProblemCheck.send(:remove_const, "TestCheck")
end
after { Discourse.redis.flushdb }
context "when there are problems" do
before do
around do |example|
ProblemCheck::TestCheck =
Class.new(ProblemCheck) do
self.perform_every = 30.minutes
@@ -25,6 +21,10 @@ RSpec.describe Jobs::RunProblemCheck do
]
end
end
stub_const(ProblemCheck, "CORE_PROBLEM_CHECKS", [ProblemCheck::TestCheck], &example)
ProblemCheck.send(:remove_const, "TestCheck")
end
it "adds the messages to the Redis problems array" do
@@ -37,7 +37,7 @@ RSpec.describe Jobs::RunProblemCheck do
end
context "with multiple problems with the same identifier" do
before do
around do |example|
ProblemCheck::TestCheck =
Class.new(ProblemCheck) do
self.perform_every = 30.minutes
@@ -58,6 +58,10 @@ RSpec.describe Jobs::RunProblemCheck do
]
end
end
stub_const(ProblemCheck, "CORE_PROBLEM_CHECKS", [ProblemCheck::TestCheck], &example)
ProblemCheck.send(:remove_const, "TestCheck")
end
it "does not add the same problem twice" do
@@ -70,7 +74,7 @@ RSpec.describe Jobs::RunProblemCheck do
end
context "when there are retries remaining" do
before do
around do |example|
ProblemCheck::TestCheck =
Class.new(ProblemCheck) do
self.perform_every = 30.minutes
@@ -80,6 +84,10 @@ RSpec.describe Jobs::RunProblemCheck do
[ProblemCheck::Problem.new("Yuge problem")]
end
end
stub_const(ProblemCheck, "CORE_PROBLEM_CHECKS", [ProblemCheck::TestCheck], &example)
ProblemCheck.send(:remove_const, "TestCheck")
end
it "does not yet update the problem check tracker" do
@@ -100,7 +108,7 @@ RSpec.describe Jobs::RunProblemCheck do
end
context "when there are no retries remaining" do
before do
around do |example|
ProblemCheck::TestCheck =
Class.new(ProblemCheck) do
self.perform_every = 30.minutes
@@ -110,6 +118,10 @@ RSpec.describe Jobs::RunProblemCheck do
[ProblemCheck::Problem.new("Yuge problem")]
end
end
stub_const(ProblemCheck, "CORE_PROBLEM_CHECKS", [ProblemCheck::TestCheck], &example)
ProblemCheck.send(:remove_const, "TestCheck")
end
it "updates the problem check tracker" do
@@ -126,7 +138,7 @@ RSpec.describe Jobs::RunProblemCheck do
end
context "when the check unexpectedly errors out" do
before do
around do |example|
ProblemCheck::TestCheck =
Class.new(ProblemCheck) do
self.max_retries = 1
@@ -135,6 +147,10 @@ RSpec.describe Jobs::RunProblemCheck do
raise StandardError.new("Something went wrong")
end
end
stub_const(ProblemCheck, "CORE_PROBLEM_CHECKS", [ProblemCheck::TestCheck], &example)
ProblemCheck.send(:remove_const, "TestCheck")
end
it "does not add a problem to the Redis array" do
+8 -3
View File
@@ -1,7 +1,7 @@
# frozen_string_literal: true
RSpec.describe Jobs::RunProblemChecks do
before do
around do |example|
ProblemCheck::ScheduledCheck =
Class.new(ProblemCheck) do
self.perform_every = 30.minutes
@@ -10,9 +10,14 @@ RSpec.describe Jobs::RunProblemChecks do
end
ProblemCheck::NonScheduledCheck = Class.new(ProblemCheck) { def call = [] }
end
after do
stub_const(
ProblemCheck,
"CORE_PROBLEM_CHECKS",
[ProblemCheck::ScheduledCheck, ProblemCheck::NonScheduledCheck],
&example
)
Discourse.redis.flushdb
AdminDashboardData.reset_problem_checks
+23 -5
View File
@@ -1,17 +1,17 @@
# frozen_string_literal: true
RSpec.describe ProblemCheck do
# rubocop:disable RSpec/BeforeAfterAll
before(:all) do
around do |example|
ScheduledCheck = Class.new(described_class) { self.perform_every = 30.minutes }
RealtimeCheck = Class.new(described_class)
end
PluginCheck = Class.new(described_class)
stub_const(described_class, "CORE_PROBLEM_CHECKS", [ScheduledCheck, RealtimeCheck], &example)
after(:all) do
Object.send(:remove_const, ScheduledCheck.name)
Object.send(:remove_const, RealtimeCheck.name)
Object.send(:remove_const, PluginCheck.name)
end
# rubocop:enable RSpec/BeforeAfterAll
let(:scheduled_check) { ScheduledCheck }
let(:realtime_check) { RealtimeCheck }
@@ -48,4 +48,22 @@ RSpec.describe ProblemCheck do
it { expect(realtime_check).to be_realtime }
it { expect(scheduled_check).to_not be_realtime }
end
describe "plugin problem check registration" do
before { DiscoursePluginRegistry.register_problem_check(PluginCheck, stub(enabled?: enabled)) }
after { DiscoursePluginRegistry.reset! }
context "when the plugin is enabled" do
let(:enabled) { true }
it { expect(described_class.checks).to include(PluginCheck) }
end
context "when the plugin is disabled" do
let(:enabled) { false }
it { expect(described_class.checks).not_to include(PluginCheck) }
end
end
end