mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-05-09 03:18:53 +08:00
When a problem check is run with an invalid target, which can happen if a target is dynamically removed from the list, we destroy the problem check tracker. This makes it so that we also clean up any associated admin notices when this happens. It also marks `target` as required. This is because we now use `__NULL__` to indicate "no target". This allows us to clean up the Ruby implementation a bit. (Context: this is required for uniqueness checks to work, since PostgreSQL considers `NULL` values to be distinct.)
176 lines
5.3 KiB
Ruby
176 lines
5.3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
RSpec.describe ProblemCheck do
|
|
around do |example|
|
|
ScheduledCheck = Class.new(described_class) { self.perform_every = 30.minutes }
|
|
RealtimeCheck = Class.new(described_class)
|
|
InlineCheck = Class.new(described_class) { self.inline = true }
|
|
PluginCheck = Class.new(described_class)
|
|
DisabledCheck = Class.new(described_class) { self.enabled = false }
|
|
MultiTargetCheck = Class.new(described_class) { self.targets = -> { %w[foo bar] } }
|
|
FailingCheck =
|
|
Class.new(described_class) do
|
|
def call
|
|
problem
|
|
end
|
|
|
|
def translation_key
|
|
"failing_check"
|
|
end
|
|
end
|
|
PassingCheck =
|
|
Class.new(described_class) do
|
|
def call
|
|
no_problem
|
|
end
|
|
|
|
def translation_key
|
|
"passing_check"
|
|
end
|
|
end
|
|
|
|
stub_const(
|
|
described_class,
|
|
"CORE_PROBLEM_CHECKS",
|
|
[
|
|
ScheduledCheck,
|
|
RealtimeCheck,
|
|
InlineCheck,
|
|
DisabledCheck,
|
|
MultiTargetCheck,
|
|
FailingCheck,
|
|
PassingCheck,
|
|
],
|
|
&example
|
|
)
|
|
|
|
Object.send(:remove_const, ScheduledCheck.name)
|
|
Object.send(:remove_const, RealtimeCheck.name)
|
|
Object.send(:remove_const, InlineCheck.name)
|
|
Object.send(:remove_const, DisabledCheck.name)
|
|
Object.send(:remove_const, MultiTargetCheck.name)
|
|
Object.send(:remove_const, PluginCheck.name)
|
|
Object.send(:remove_const, FailingCheck.name)
|
|
Object.send(:remove_const, PassingCheck.name)
|
|
end
|
|
|
|
let(:scheduled_check) { ScheduledCheck }
|
|
let(:realtime_check) { RealtimeCheck }
|
|
let(:inline_check) { InlineCheck }
|
|
let(:enabled_check) { RealtimeCheck }
|
|
let(:disabled_check) { DisabledCheck }
|
|
let(:multi_target_check) { MultiTargetCheck }
|
|
let(:plugin_check) { PluginCheck }
|
|
let(:failing_check) { FailingCheck }
|
|
let(:passing_check) { PassingCheck }
|
|
|
|
describe ".[]" do
|
|
it { expect(described_class[:scheduled_check]).to eq(scheduled_check) }
|
|
it { expect(described_class[:foo]).to eq(nil) }
|
|
end
|
|
|
|
describe ".identifier" do
|
|
it { expect(scheduled_check.identifier).to eq(:scheduled_check) }
|
|
end
|
|
|
|
describe ".checks" do
|
|
it { expect(described_class.checks).to include(scheduled_check, realtime_check, inline_check) }
|
|
end
|
|
|
|
describe ".scheduled" do
|
|
it { expect(described_class.scheduled).to include(scheduled_check) }
|
|
it { expect(described_class.scheduled).not_to include(realtime_check) }
|
|
it { expect(described_class.scheduled).not_to include(inline_check) }
|
|
end
|
|
|
|
describe ".realtime" do
|
|
it { expect(described_class.realtime).to include(realtime_check) }
|
|
it { expect(described_class.realtime).not_to include(scheduled_check) }
|
|
it { expect(described_class.realtime).not_to include(inline_check) }
|
|
end
|
|
|
|
describe ".scheduled?" do
|
|
it { expect(scheduled_check).to be_scheduled }
|
|
it { expect(realtime_check).to_not be_scheduled }
|
|
it { expect(inline_check).to_not be_scheduled }
|
|
end
|
|
|
|
describe ".realtime?" do
|
|
it { expect(realtime_check).to be_realtime }
|
|
it { expect(scheduled_check).to_not be_realtime }
|
|
it { expect(inline_check).to_not be_realtime }
|
|
end
|
|
|
|
describe ".inline?" do
|
|
it { expect(inline_check).to be_inline }
|
|
it { expect(realtime_check).to_not be_inline }
|
|
it { expect(scheduled_check).to_not be_inline }
|
|
end
|
|
|
|
describe ".enabled?" do
|
|
it { expect(enabled_check).to be_enabled }
|
|
it { expect(disabled_check).not_to be_enabled }
|
|
end
|
|
|
|
describe ".targeted?" do
|
|
it { expect(scheduled_check).not_to be_targeted }
|
|
it { expect(multi_target_check).to be_targeted }
|
|
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(plugin_check) }
|
|
end
|
|
|
|
context "when the plugin is disabled" do
|
|
let(:enabled) { false }
|
|
|
|
it { expect(described_class.checks).not_to include(plugin_check) }
|
|
end
|
|
end
|
|
|
|
describe "#run" do
|
|
context "when check is failing" do
|
|
it { expect { failing_check.new.run }.to change { ProblemCheckTracker.failing.count }.by(1) }
|
|
end
|
|
|
|
context "when check is passing" do
|
|
it { expect { passing_check.new.run }.to change { ProblemCheckTracker.passing.count }.by(1) }
|
|
end
|
|
|
|
context "when targeted check is initialized with no target" do
|
|
context "when a tracker exists" do
|
|
before do
|
|
ProblemCheckTracker.create!(
|
|
identifier: "multi_target_check",
|
|
target: ProblemCheck::NO_TARGET,
|
|
)
|
|
end
|
|
|
|
it "deletes the tracker" do
|
|
expect { multi_target_check.new.run }.to change { ProblemCheckTracker.count }.by(-1)
|
|
end
|
|
end
|
|
|
|
context "when a tracker does not exist" do
|
|
it "does nothing" do
|
|
expect { multi_target_check.new.run }.not_to change { ProblemCheckTracker.count }
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when targeted check has an outdated target" do
|
|
before { ProblemCheckTracker.create!(identifier: "multi_target_check", target: "baz") }
|
|
|
|
it "deletes the tracker" do
|
|
expect { multi_target_check.new("baz").run }.to change { ProblemCheckTracker.count }.by(-1)
|
|
end
|
|
end
|
|
end
|
|
end
|