Skip to content

Commit 105337e

Browse files
committed
Replace raw state integers with named enum scopes in jobs
Using state: 0 relied on knowing the integer value of the approved enum, which breaks silently if values change. Both DailyPuzzleJob and PuzzleInventoryCheckJob now use Puzzle.approved.where(sent_at: nil).
1 parent 24872fc commit 105337e

4 files changed

Lines changed: 156 additions & 2 deletions

File tree

app/jobs/daily_puzzle_job.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ class DailyPuzzleJob < ApplicationJob
33
retry_on StandardError, attempts: 3
44

55
def perform
6-
puzzle = Puzzle.where(sent_at: nil, state: 0).order("RANDOM()").first
6+
puzzle = Puzzle.approved.where(sent_at: nil).order("RANDOM()").first
77
return unless puzzle
88

99
Server.where(active: true).each do |server|

app/jobs/puzzle_inventory_check_job.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ class PuzzleInventoryCheckJob < ApplicationJob
33
retry_on StandardError, attempts: 3
44

55
def perform
6-
approved_unsent_puzzle_count = Puzzle.where(state: 0, sent_at: nil).count
6+
approved_unsent_puzzle_count = Puzzle.approved.where(sent_at: nil).count
77

88
if approved_unsent_puzzle_count < 5
99
send_low_inventory_notification(approved_unsent_puzzle_count)

test/jobs/daily_puzzle_job_test.rb

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
require "test_helper"
2+
3+
class DailyPuzzleJobTest < ActiveJob::TestCase
4+
test "only selects approved puzzles, not pending or rejected" do
5+
pending_puzzle = Puzzle.create!(
6+
question: "Pending puzzle question",
7+
answer: "ruby",
8+
explanation: "Test explanation",
9+
state: :pending,
10+
sent_at: nil,
11+
suggested_by: "test_user"
12+
)
13+
rejected_puzzle = Puzzle.create!(
14+
question: "Rejected puzzle question",
15+
answer: "rails",
16+
explanation: "Test explanation",
17+
state: :rejected,
18+
sent_at: nil,
19+
suggested_by: "test_user"
20+
)
21+
22+
DailyPuzzleJob.perform_now
23+
24+
assert_nil pending_puzzle.reload.sent_at
25+
assert_nil rejected_puzzle.reload.sent_at
26+
end
27+
28+
test "only selects puzzles that have not been sent yet" do
29+
already_sent = Puzzle.create!(
30+
question: "Already sent puzzle question",
31+
answer: "ruby",
32+
explanation: "Test explanation",
33+
state: :approved,
34+
sent_at: 1.day.ago,
35+
suggested_by: "test_user"
36+
)
37+
38+
DailyPuzzleJob.perform_now
39+
40+
assert_equal already_sent.reload.sent_at.to_i, 1.day.ago.to_i
41+
end
42+
43+
test "marks the selected puzzle as archived and sets sent_at" do
44+
puzzle = Puzzle.create!(
45+
question: "Approved unsent puzzle question",
46+
answer: "ruby",
47+
explanation: "Test explanation",
48+
state: :approved,
49+
sent_at: nil,
50+
suggested_by: "test_user"
51+
)
52+
53+
DailyPuzzleJob.perform_now
54+
55+
puzzle.reload
56+
assert_not_nil puzzle.sent_at
57+
assert_equal "archived", puzzle.state
58+
end
59+
60+
test "does nothing when no approved unsent puzzles exist" do
61+
Puzzle.approved.where(sent_at: nil).delete_all
62+
63+
assert_nothing_raised do
64+
DailyPuzzleJob.perform_now
65+
end
66+
end
67+
end
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
require "test_helper"
2+
3+
class PuzzleInventoryCheckJobTest < ActiveJob::TestCase
4+
setup do
5+
Puzzle.approved.where(sent_at: nil).delete_all
6+
end
7+
8+
test "sends notification when fewer than 5 approved unsent puzzles exist" do
9+
3.times do |i|
10+
Puzzle.create!(
11+
question: "Approved unsent puzzle #{i}",
12+
answer: "ruby",
13+
state: :approved,
14+
sent_at: nil,
15+
explanation: "Test explanation",
16+
suggested_by: "test_user"
17+
)
18+
end
19+
20+
notification_sent = false
21+
job = PuzzleInventoryCheckJob.new
22+
job.define_singleton_method(:send_message) { |*| notification_sent = true }
23+
job.perform
24+
25+
assert notification_sent, "Expected a low inventory notification to be sent"
26+
end
27+
28+
test "does not send notification when 5 or more approved unsent puzzles exist" do
29+
5.times do |i|
30+
Puzzle.create!(
31+
question: "Approved unsent puzzle #{i}",
32+
answer: "ruby",
33+
state: :approved,
34+
sent_at: nil,
35+
explanation: "Test explanation",
36+
suggested_by: "test_user"
37+
)
38+
end
39+
40+
notification_sent = false
41+
job = PuzzleInventoryCheckJob.new
42+
job.define_singleton_method(:send_message) { |*| notification_sent = true }
43+
job.perform
44+
45+
assert_not notification_sent, "Expected no notification to be sent"
46+
end
47+
48+
test "only counts approved puzzles, not pending or rejected" do
49+
5.times do |i|
50+
Puzzle.create!(
51+
question: "Pending puzzle #{i}",
52+
answer: "ruby",
53+
state: :pending,
54+
sent_at: nil,
55+
explanation: "Test explanation",
56+
suggested_by: "test_user"
57+
)
58+
end
59+
60+
notification_sent = false
61+
job = PuzzleInventoryCheckJob.new
62+
job.define_singleton_method(:send_message) { |*| notification_sent = true }
63+
job.perform
64+
65+
assert notification_sent, "Pending puzzles should not count toward approved inventory"
66+
end
67+
68+
test "only counts unsent puzzles" do
69+
5.times do |i|
70+
Puzzle.create!(
71+
question: "Already sent puzzle #{i}",
72+
answer: "ruby",
73+
state: :approved,
74+
sent_at: 1.day.ago,
75+
explanation: "Test explanation",
76+
suggested_by: "test_user"
77+
)
78+
end
79+
80+
notification_sent = false
81+
job = PuzzleInventoryCheckJob.new
82+
job.define_singleton_method(:send_message) { |*| notification_sent = true }
83+
job.perform
84+
85+
assert notification_sent, "Already sent puzzles should not count toward available inventory"
86+
end
87+
end

0 commit comments

Comments
 (0)