Skip to content

Commit cbab9ad

Browse files
cursoragentjaracursorsh
authored andcommitted
Add tests for cache store, healthcheck controller error handling
Co-authored-by: jaracursorsh <jaracursorsh@mitomail.com>
1 parent debcb07 commit cbab9ad

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed

test/allgood/cache_store_test.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,35 @@ def delete_matched(pattern)
7171
end
7272
end
7373

74+
def test_cleanup_old_keys_logs_warning_on_error
75+
fake_cache = Class.new do
76+
def write(*) = true
77+
def read(*) = "true"
78+
def delete_matched(*)
79+
raise "delete failed"
80+
end
81+
end.new
82+
83+
messages = []
84+
fake_logger = Logger.new($stdout)
85+
def fake_logger.warn(msg)
86+
(@_msgs ||= []) << msg
87+
end
88+
def fake_logger.messages
89+
@_msgs || []
90+
end
91+
92+
@store.stub(:rails_cache_available?, true) do
93+
Rails.stub(:cache, fake_cache) do
94+
Rails.stub(:logger, fake_logger) do
95+
# Should not raise
96+
@store.cleanup_old_keys
97+
assert fake_logger.messages.any? { |m| m.include?("Failed to cleanup old cache keys") }
98+
end
99+
end
100+
end
101+
end
102+
74103
def test_rails_cache_available_checks_read_write
75104
store = ActiveSupport::Cache::MemoryStore.new
76105
Rails.stub(:cache, store) do

test/allgood/healthcheck_controller_test.rb

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,24 @@ def test_html_ok_when_all_checks_pass
3333
assert check_lines.any? { |t| t.include?("✅") }
3434
end
3535

36+
def test_html_escapes_check_name_and_message
37+
@config.check("<script>alert('x')</script>") { make_sure false, "<b>bad</b>" }
38+
get "/"
39+
doc = Nokogiri::HTML.parse(last_response.body)
40+
# Ensure escaped content appears literally
41+
assert_includes doc.text, "<script>alert('x')</script>"
42+
assert_includes doc.text, "<b>bad</b>"
43+
# Raw script tag should not be rendered
44+
refute doc.at_css('script')
45+
# The name is wrapped in a <b> by the view; ensure its content is the escaped name
46+
name_b = doc.at_css('.check b')
47+
assert_equal "<script>alert('x')</script>", name_b.text
48+
# The message is inside <i> and should not contain raw <b> elements
49+
msg_i = doc.at_css('.check i')
50+
assert_includes msg_i.text, "<b>bad</b>"
51+
refute msg_i.at_css('b')
52+
end
53+
3654
def test_json_error_when_any_check_fails
3755
@config.check("Fail") { expect(1).to_eq(2) }
3856
header "Accept", "application/json"
@@ -52,6 +70,21 @@ def test_json_error_when_any_check_fails
5270
assert_kind_of Numeric, first["duration"]
5371
end
5472

73+
def test_json_schema_for_skipped_check
74+
Rails.stub(:env, ActiveSupport::StringInquirer.new("test")) do
75+
@config.check("Only prod", only: :production) { make_sure true }
76+
end
77+
header "Accept", "application/json"
78+
get "/"
79+
assert_equal 200, last_response.status
80+
json = JSON.parse(last_response.body)
81+
skipped = json["checks"].find { |c| c["name"] == "Only prod" }
82+
assert skipped["success"]
83+
assert_equal true, skipped["skipped"]
84+
assert_kind_of String, skipped["message"]
85+
assert_equal 0, skipped["duration"]
86+
end
87+
5588
def test_timeout_is_handled
5689
@config.check("Timeout", timeout: 0.01) { sleep 0.1; make_sure true }
5790

@@ -103,6 +136,37 @@ def test_rate_limit_resets_next_day
103136
end
104137
end
105138

139+
def test_rate_limit_error_persists_across_periods_and_blocks_execution
140+
travel_to Time.utc(2024, 12, 31, 23, 55, 0) do
141+
# Define a check that fails first time, then passes after midnight
142+
attempts = 0
143+
@config.check("Flaky API", run: "10 times per hour") do
144+
attempts += 1
145+
if attempts == 1
146+
make_sure false, "boom"
147+
else
148+
make_sure true, "ok"
149+
end
150+
end
151+
152+
# First run fails and stores error state
153+
get "/"
154+
assert_equal 503, last_response.status
155+
156+
# Subsequent run within same hour should be skipped due to previous error
157+
get "/"
158+
assert last_response.ok? || last_response.status == 503
159+
assert_includes text_content(last_response.body), "Rate limited"
160+
161+
# Even after period change, previous error should keep the check skipped until success
162+
travel 10.minutes
163+
travel_to Time.utc(2025, 1, 1, 0, 5, 0)
164+
get "/"
165+
# Still rate limited due to previous error persistence
166+
assert_includes text_content(last_response.body), "Rate limited"
167+
end
168+
end
169+
106170
def test_error_rescue_returns_500
107171
# Force an unexpected error in run_checks by stubbing configuration
108172
Allgood.stub(:configuration, nil) do

0 commit comments

Comments
 (0)