resque-stages 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +103 -0
  5. data/.rubocop_todo.yml +34 -0
  6. data/.ruby-version +1 -0
  7. data/.travis.yml +6 -0
  8. data/CODE_OF_CONDUCT.md +74 -0
  9. data/Gemfile +9 -0
  10. data/Gemfile.lock +172 -0
  11. data/LICENSE.txt +21 -0
  12. data/README.md +250 -0
  13. data/Rakefile +8 -0
  14. data/bin/console +16 -0
  15. data/bin/setup +8 -0
  16. data/lib/resque-stages.rb +11 -0
  17. data/lib/resque/plugins/stages.rb +110 -0
  18. data/lib/resque/plugins/stages/cleaner.rb +36 -0
  19. data/lib/resque/plugins/stages/redis_access.rb +16 -0
  20. data/lib/resque/plugins/stages/staged_group.rb +181 -0
  21. data/lib/resque/plugins/stages/staged_group_list.rb +79 -0
  22. data/lib/resque/plugins/stages/staged_group_stage.rb +275 -0
  23. data/lib/resque/plugins/stages/staged_job.rb +271 -0
  24. data/lib/resque/plugins/stages/version.rb +9 -0
  25. data/lib/resque/server/public/stages.css +56 -0
  26. data/lib/resque/server/views/_group_stages_list_pagination.erb +67 -0
  27. data/lib/resque/server/views/_group_stages_list_table.erb +25 -0
  28. data/lib/resque/server/views/_stage_job_list_pagination.erb +72 -0
  29. data/lib/resque/server/views/_stage_job_list_table.erb +46 -0
  30. data/lib/resque/server/views/_staged_group_list_pagination.erb +67 -0
  31. data/lib/resque/server/views/_staged_group_list_table.erb +44 -0
  32. data/lib/resque/server/views/group_stages_list.erb +58 -0
  33. data/lib/resque/server/views/groups.erb +40 -0
  34. data/lib/resque/server/views/job_details.erb +91 -0
  35. data/lib/resque/server/views/stage.erb +64 -0
  36. data/lib/resque/stages_server.rb +240 -0
  37. data/read_me/groups_list.png +0 -0
  38. data/read_me/job.png +0 -0
  39. data/read_me/stage.png +0 -0
  40. data/read_me/stages.png +0 -0
  41. data/resque-stages.gemspec +49 -0
  42. data/spec/rails_helper.rb +40 -0
  43. data/spec/resque/plugins/stages/cleaner_spec.rb +82 -0
  44. data/spec/resque/plugins/stages/staged_group_list_spec.rb +96 -0
  45. data/spec/resque/plugins/stages/staged_group_spec.rb +226 -0
  46. data/spec/resque/plugins/stages/staged_group_stage_spec.rb +293 -0
  47. data/spec/resque/plugins/stages/staged_job_spec.rb +324 -0
  48. data/spec/resque/plugins/stages_spec.rb +369 -0
  49. data/spec/resque/server/public/stages.css_spec.rb +18 -0
  50. data/spec/resque/server/views/group_stages_list.erb_spec.rb +67 -0
  51. data/spec/resque/server/views/groups.erb_spec.rb +81 -0
  52. data/spec/resque/server/views/job_details.erb_spec.rb +100 -0
  53. data/spec/resque/server/views/stage.erb_spec.rb +68 -0
  54. data/spec/spec_helper.rb +104 -0
  55. data/spec/support/01_utils/fake_logger.rb +7 -0
  56. data/spec/support/config/redis-auth.yml +12 -0
  57. data/spec/support/fake_logger.rb +7 -0
  58. data/spec/support/jobs/basic_job.rb +17 -0
  59. data/spec/support/jobs/compressed_job.rb +18 -0
  60. data/spec/support/jobs/retry_job.rb +21 -0
  61. data/spec/support/purge_all.rb +15 -0
  62. metadata +297 -0
@@ -0,0 +1,293 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails_helper"
4
+
5
+ RSpec.describe Resque::Plugins::Stages::StagedGroupStage do
6
+ let(:group) do
7
+ instance_double(Resque::Plugins::Stages::StagedGroup,
8
+ add_stage: nil,
9
+ remove_stage: nil,
10
+ stage_completed: nil,
11
+ group_id: SecureRandom.uuid)
12
+ end
13
+ let(:stage) { Resque::Plugins::Stages::StagedGroupStage.new SecureRandom.uuid }
14
+ let(:load_stage) { Resque::Plugins::Stages::StagedGroupStage.new stage.group_stage_id }
15
+
16
+ RSpec.shared_examples("enqueues new jobs") do |enqueue_method, enqueue_method_parameters|
17
+ describe enqueue_method do
18
+ let(:enqueue_parameters) { [*enqueue_method_parameters, BasicJob, "This", 1, "is", "an" => "arglist"] }
19
+ let(:job) { load_stage.jobs.first }
20
+ let(:enqueued_parameters) { [*enqueue_method_parameters, BasicJob, { staged_job_id: job.job_id }, "This", 1, "is", "an" => "arglist"] }
21
+
22
+ before(:each) do
23
+ allow(Resque).to receive(enqueue_method).and_return nil
24
+ end
25
+
26
+ it "creates the job" do
27
+ stage.public_send(enqueue_method, *enqueue_parameters)
28
+
29
+ expect(load_stage.num_jobs).to eq 1
30
+
31
+ expect(job.args).to eq ["This", 1, "is", "an" => "arglist"]
32
+ expect(job.class_name).to eq "BasicJob"
33
+ end
34
+
35
+ it "does not enqueue the job is the status is pending" do
36
+ stage.public_send(enqueue_method, *enqueue_parameters)
37
+
38
+ expect(Resque).not_to have_received(enqueue_method)
39
+ end
40
+
41
+ it "enqueues the job if the status is running" do
42
+ stage.status = :running
43
+
44
+ stage.public_send(enqueue_method, *enqueue_parameters)
45
+
46
+ expect(Resque).to have_received(enqueue_method).with(*enqueued_parameters)
47
+ end
48
+
49
+ it "marks the job as queued if the status is running" do
50
+ stage.status = :running
51
+
52
+ stage.public_send(enqueue_method, *enqueue_parameters)
53
+
54
+ expect(load_stage.jobs.first.status).to eq :queued
55
+ end
56
+
57
+ it "enqueues the job and changes status to running if status is completed" do
58
+ stage.status = :complete
59
+
60
+ stage.public_send(enqueue_method, *enqueue_parameters)
61
+
62
+ expect(Resque).to have_received(enqueue_method).with(*enqueued_parameters)
63
+ expect(stage.status).to eq :running
64
+ end
65
+
66
+ it "marks the job as queued and changes status to running if status is completed" do
67
+ stage.status = :complete
68
+
69
+ stage.public_send(enqueue_method, *enqueue_parameters)
70
+
71
+ expect(load_stage.jobs.first.status).to eq :queued
72
+ expect(stage.status).to eq :running
73
+ end
74
+ end
75
+ end
76
+
77
+ describe "enqueuing jobs" do
78
+ it_behaves_like "enqueues new jobs", :enqueue, []
79
+ it_behaves_like "enqueues new jobs", :enqueue_to, ["queue"]
80
+ it_behaves_like "enqueues new jobs", :enqueue_at, [Time.now]
81
+ it_behaves_like "enqueues new jobs", :enqueue_at_with_queue, ["queue", Time.now]
82
+ it_behaves_like "enqueues new jobs", :enqueue_in, [12.seconds]
83
+ it_behaves_like "enqueues new jobs", :enqueue_in_with_queue, ["queue", 12.seconds]
84
+ end
85
+
86
+ describe "status" do
87
+ it "defaults to pending" do
88
+ expect(stage.status).to eq :pending
89
+ end
90
+
91
+ it "saves when set" do
92
+ stage.status = :running
93
+ expect(load_stage.status).to eq :running
94
+ end
95
+ end
96
+
97
+ describe "number" do
98
+ it "defaults to 1" do
99
+ expect(stage.number).to eq 1
100
+ end
101
+
102
+ it "saves when set" do
103
+ stage.number = 8
104
+ expect(load_stage.number).to eq 8
105
+ end
106
+ end
107
+
108
+ describe "staged_group" do
109
+ it "returns nil if staged_group_id is nil" do
110
+ expect(stage.staged_group).to be_nil
111
+ end
112
+
113
+ it "saves the staged_group_id" do
114
+ stage.staged_group = group
115
+
116
+ expect(load_stage.staged_group.group_id).to eq group.group_id
117
+ end
118
+
119
+ it "adds the stage to the group" do
120
+ stage.staged_group = group
121
+
122
+ expect(group).to have_received(:add_stage).with(stage)
123
+ end
124
+ end
125
+
126
+ context "with jobs" do
127
+ let(:jobs) do
128
+ build_jobs = [travel_to(5.hours.ago) { stage.enqueue(BasicJob, "a pending") },
129
+ travel_to(2.hours.ago) { stage.enqueue(BasicJob, "z queued") },
130
+ travel_to(4.hours.ago) { stage.enqueue(BasicJob, "h running") },
131
+ travel_to(1.hours.ago) { stage.enqueue(BasicJob, "c pending_re_run") },
132
+ travel_to(3.hours.ago) { stage.enqueue(BasicJob, "m failed") },
133
+ travel_to(0.hours.ago) { stage.enqueue(BasicJob, "i successful") }]
134
+
135
+ build_jobs[0].status = :pending
136
+ build_jobs[1].status = :queued
137
+ build_jobs[2].status = :running
138
+ build_jobs[3].status = :pending_re_run
139
+ build_jobs[4].status = :failed
140
+ build_jobs[5].status = :successful
141
+
142
+ build_jobs[0].status_message = "y"
143
+ build_jobs[1].status_message = "g"
144
+ build_jobs[2].status_message = "l"
145
+ build_jobs[3].status_message = "q"
146
+ build_jobs[4].status_message = "r"
147
+ build_jobs[5].status_message = "b"
148
+
149
+ build_jobs
150
+ end
151
+
152
+ before(:each) do
153
+ allow(Resque).to receive(:enqueue).and_return nil
154
+ end
155
+
156
+ describe "paginated_jobs" do
157
+ it "paginates by class_name" do
158
+ jobs
159
+
160
+ expect(load_stage.paginated_jobs("class_name", "asc", 2, 2)).to eq [jobs[2], jobs[3]]
161
+ end
162
+
163
+ it "paginates by status" do
164
+ jobs
165
+
166
+ expect(load_stage.paginated_jobs("status", "asc", 2, 2)).to eq [jobs[3], jobs[1]]
167
+ end
168
+
169
+ it "paginates by status_message" do
170
+ jobs
171
+
172
+ expect(load_stage.paginated_jobs("status_message", "asc", 2, 2)).to eq [jobs[2], jobs[3]]
173
+ end
174
+
175
+ it "paginates by queue_time" do
176
+ jobs
177
+
178
+ expect(load_stage.paginated_jobs("queue_time", "asc", 2, 2)).to eq [jobs[4], jobs[1]]
179
+ end
180
+ end
181
+
182
+ describe "jobs" do
183
+ it "returns all jobs" do
184
+ jobs
185
+
186
+ expect(load_stage.jobs.length).to eq jobs.length
187
+ expect(load_stage.num_jobs).to eq jobs.length
188
+ end
189
+
190
+ %i[pending queued running pending_re_run failed successful].each.with_index do |status, index|
191
+ it "returns jobs based on status #{status}" do
192
+ jobs
193
+ expect(load_stage.jobs_by_status(status)).to eq [jobs[index]]
194
+ end
195
+
196
+ it "removes a job when it is deleted" do
197
+ jobs.sample.delete
198
+
199
+ expect(load_stage.jobs.length).to eq jobs.length - 1
200
+ expect(load_stage.num_jobs).to eq jobs.length - 1
201
+ end
202
+
203
+ it "deletes all jobs when deleted" do
204
+ jobs
205
+
206
+ stage.delete
207
+
208
+ expect(load_stage.jobs.length).to eq 0
209
+ expect(load_stage.num_jobs).to eq 0
210
+ end
211
+
212
+ it "removes the stage from the group when deleted" do
213
+ jobs
214
+
215
+ stage.staged_group = group
216
+ stage.delete
217
+
218
+ expect(group).to have_received(:remove_stage).with(stage)
219
+ end
220
+ end
221
+ end
222
+
223
+ describe "initiate" do
224
+ it "queues all pending jobs" do
225
+ allow(Resque).to receive(:enqueue).and_return nil
226
+
227
+ jobs
228
+
229
+ stage.initiate
230
+
231
+ expect(Resque).to have_received(:enqueue).with(BasicJob, { staged_job_id: jobs[0].job_id }, anything)
232
+ expect(Resque).not_to have_received(:enqueue).with(BasicJob, { staged_job_id: jobs[1].job_id }, anything)
233
+ expect(Resque).not_to have_received(:enqueue).with(BasicJob, { staged_job_id: jobs[2].job_id }, anything)
234
+ expect(Resque).not_to have_received(:enqueue).with(BasicJob, { staged_job_id: jobs[3].job_id }, anything)
235
+ expect(Resque).not_to have_received(:enqueue).with(BasicJob, { staged_job_id: jobs[4].job_id }, anything)
236
+ expect(Resque).not_to have_received(:enqueue).with(BasicJob, { staged_job_id: jobs[5].job_id }, anything)
237
+ end
238
+
239
+ it "changes the status to running" do
240
+ allow(Resque).to receive(:enqueue).and_return nil
241
+
242
+ jobs
243
+ stage.initiate
244
+
245
+ expect(stage.status).to eq :running
246
+ end
247
+ end
248
+
249
+ describe "job_completed" do
250
+ it "does nothing if not all jobs are completed" do
251
+ jobs
252
+
253
+ stage.job_completed
254
+
255
+ expect(group).not_to have_received(:stage_completed)
256
+ expect(stage.status).to eq :running
257
+ end
258
+
259
+ it "changes the status to complete if all jobs are completed" do
260
+ jobs.each { |job| job.status = :failed unless job.completed? }
261
+
262
+ expect(stage.status).to eq :complete
263
+ end
264
+
265
+ it "notifies the group if all jobs are completed" do
266
+ stage.staged_group = group
267
+
268
+ jobs.each do |job|
269
+ allow(job).to receive(:staged_group_stage).and_return(stage)
270
+ end
271
+ jobs.each { |job| job.status = :successful unless job.completed? }
272
+
273
+ expect(group).to have_received(:stage_completed)
274
+ end
275
+ end
276
+ end
277
+
278
+ describe "#order_param" do
279
+ it "returns asc for any column other than the current one" do
280
+ expect(load_stage.order_param("sort_option",
281
+ "current_sort",
282
+ %w[asc desc].sample)).to eq "asc"
283
+ end
284
+
285
+ it "returns desc for the current column if it is asc" do
286
+ expect(load_stage.order_param("sort_option", "sort_option", "asc")).to eq "desc"
287
+ end
288
+
289
+ it "returns asc for the current column if it is desc" do
290
+ expect(load_stage.order_param("sort_option", "sort_option", "desc")).to eq "asc"
291
+ end
292
+ end
293
+ end
@@ -0,0 +1,324 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails_helper"
4
+
5
+ RSpec.describe Resque::Plugins::Stages::StagedJob do
6
+ let(:stage) do
7
+ instance_double(Resque::Plugins::Stages::StagedGroupStage,
8
+ add_job: nil,
9
+ remove_job: nil,
10
+ group_stage_id: SecureRandom.uuid,
11
+ status: :pending,
12
+ "status=": nil,
13
+ job_completed: nil)
14
+ end
15
+ let(:job) { Resque::Plugins::Stages::StagedJob.create_job(stage, BasicJob, "This", 1, :is, an: "arglist") }
16
+ let(:load_job) { Resque::Plugins::Stages::StagedJob.new(job.job_id) }
17
+
18
+ context "compressed job" do
19
+ let(:job) { Resque::Plugins::Stages::StagedJob.create_job(stage, CompressedJob, "This", 1, :is, an: "arglist") }
20
+ let(:enqueue_args) do
21
+ [{ resque_compressed: true,
22
+ payload: CompressedJob.compressed_args([{ "staged_job_id" => job.job_id }, "This", 1, :is, an: "arglist"]),
23
+ staged_job_id: job.job_id }]
24
+ end
25
+
26
+ describe "create" do
27
+ it "creates a new job" do
28
+ travel_to(Time.now) do
29
+ job
30
+ load_job
31
+
32
+ expect(load_job.class_name).to eq "CompressedJob"
33
+ expect(load_job.staged_group_stage.group_stage_id).to eq stage.group_stage_id
34
+ expect(load_job.enqueue_args).to eq [CompressedJob, *enqueue_args]
35
+ expect(load_job.args).to eq ["This", 1, "is", "an" => "arglist"]
36
+ expect(load_job.uncompressed_args).to eq ["This", 1, "is", "an" => "arglist"]
37
+ expect(load_job.status).to eq :pending
38
+ expect(load_job.queue_time).to eq Time.now
39
+ end
40
+ end
41
+ end
42
+
43
+ describe "enqueue_job" do
44
+ it "enqueues a job with the staging parameters" do
45
+ allow(Resque).to receive(:enqueue)
46
+
47
+ load_job.enqueue_job
48
+
49
+ expect(Resque).to have_received(:enqueue).with(CompressedJob, *enqueue_args)
50
+ end
51
+ end
52
+
53
+ describe "enqueue_args" do
54
+ it "returns the args for enqueing the job" do
55
+ expect(load_job.enqueue_args).to eq [CompressedJob, *enqueue_args]
56
+ end
57
+ end
58
+
59
+ describe "args" do
60
+ it "returns the args for the job" do
61
+ expect(load_job.args).to eq ["This", 1, "is", "an" => "arglist"]
62
+ end
63
+
64
+ it "returns the uncompressed args for the job" do
65
+ expect(load_job.uncompressed_args).to eq ["This", 1, "is", "an" => "arglist"]
66
+ end
67
+
68
+ it "defaults args to a blank array if nil" do
69
+ job.args = nil
70
+ job.save!
71
+
72
+ expect(load_job.args).to eq []
73
+ end
74
+ end
75
+ end
76
+
77
+ describe "create" do
78
+ it "creates a new job" do
79
+ travel_to(Time.now) do
80
+ job
81
+ load_job
82
+
83
+ expect(load_job.class_name).to eq "BasicJob"
84
+ expect(load_job.staged_group_stage.group_stage_id).to eq stage.group_stage_id
85
+ expect(load_job.args).to eq ["This", 1, "is", "an" => "arglist"]
86
+ expect(load_job.uncompressed_args).to eq ["This", 1, "is", "an" => "arglist"]
87
+ expect(load_job.status).to eq :pending
88
+ expect(load_job.queue_time).to eq Time.now
89
+ end
90
+ end
91
+
92
+ it "adds the job to the staged_group_stage" do
93
+ job
94
+ expect(stage).to have_received(:add_job).with(job)
95
+ end
96
+ end
97
+
98
+ describe "<=>" do
99
+ it "returns true for identical IDs" do
100
+ expect(job <=> load_job).to be_zero
101
+ end
102
+
103
+ it "returns false for different IDs" do
104
+ expect(Resque::Plugins::Stages::StagedJob.new(SecureRandom.uuid) <=> job).not_to be_zero
105
+ end
106
+
107
+ it "returns false for different objects" do
108
+ expect(job <=> job.job_id).to be_nil
109
+ end
110
+ end
111
+
112
+ describe "status" do
113
+ it "saves upon setting" do
114
+ job.status = :successful
115
+
116
+ expect(load_job.status).to eq :successful
117
+ end
118
+
119
+ it "pending sets the group to pending if the stage is completed" do
120
+ allow(stage).to receive(:status).and_return :complete
121
+
122
+ job.status = :pending
123
+
124
+ expect(stage).to have_received(:status=).with(:pending)
125
+ end
126
+
127
+ it "pending does nothing if the stage is pending" do
128
+ allow(stage).to receive(:status).and_return :pending
129
+
130
+ job.status = :pending
131
+
132
+ expect(stage).not_to have_received(:status=)
133
+ end
134
+
135
+ it "pending does nothing if the stage is running" do
136
+ allow(stage).to receive(:status).and_return :running
137
+
138
+ job.status = :pending
139
+
140
+ expect(stage).not_to have_received(:status=)
141
+ end
142
+
143
+ it "queued? changes the stage to running if stage is pending" do
144
+ allow(stage).to receive(:status).and_return :pending
145
+
146
+ job.status = :queued
147
+
148
+ expect(stage).to have_received(:status=).with(:running)
149
+ end
150
+
151
+ it "queued? does nothing if stage is running" do
152
+ allow(stage).to receive(:status).and_return :running
153
+
154
+ job.status = :queued
155
+
156
+ expect(stage).not_to have_received(:status=)
157
+ end
158
+
159
+ it "queued? changes the stage to running if stage is completed" do
160
+ allow(stage).to receive(:status).and_return :complete
161
+
162
+ job.status = :queued
163
+
164
+ expect(stage).to have_received(:status=).with(:running)
165
+ end
166
+
167
+ it "complete? changes notifies the stage" do
168
+ job.status = :failed
169
+
170
+ expect(stage).to have_received(:job_completed)
171
+ end
172
+ end
173
+
174
+ describe "status_message" do
175
+ it "saves upon setting" do
176
+ job.status_message = "This is a large status that we're just telling you about"
177
+
178
+ expect(load_job.status_message).to eq "This is a large status that we're just telling you about"
179
+ end
180
+ end
181
+
182
+ describe "delete" do
183
+ it "deletes the object" do
184
+ job.delete
185
+ expect(load_job.args).to be_empty
186
+ end
187
+
188
+ it "removes the object from the group stage" do
189
+ job.delete
190
+ expect(stage).to have_received(:remove_job).with(job)
191
+ end
192
+ end
193
+
194
+ describe "enqueue_job" do
195
+ it "enqueues a job with the staging parameters" do
196
+ allow(Resque).to receive(:enqueue)
197
+
198
+ load_job.enqueue_job
199
+
200
+ expect(Resque).to have_received(:enqueue).with(BasicJob, { staged_job_id: load_job.job_id }, "This", 1, "is", "an" => "arglist")
201
+ end
202
+
203
+ it "sets the jobs status to queued" do
204
+ allow(Resque).to receive(:enqueue)
205
+
206
+ load_job.enqueue_job
207
+
208
+ expect(load_job.status).to eq :queued
209
+ end
210
+
211
+ it "enqueues delayed jobs" do
212
+ allow(Resque).to receive(:enqueue_delayed_selection)
213
+
214
+ job.status = :pending_re_run
215
+
216
+ load_job.enqueue_job
217
+
218
+ expect(Resque).to have_received(:enqueue_delayed_selection)
219
+ end
220
+ end
221
+
222
+ describe "enqueue_args" do
223
+ it "returns the args for enqueing the job" do
224
+ expect(load_job.enqueue_args).to eq [BasicJob, { staged_job_id: job.job_id }, "This", 1, "is", "an" => "arglist"]
225
+ end
226
+ end
227
+
228
+ describe "args" do
229
+ it "returns the args for the job" do
230
+ expect(load_job.args).to eq ["This", 1, "is", "an" => "arglist"]
231
+ end
232
+
233
+ it "returns the uncompressed_args for the job" do
234
+ expect(load_job.uncompressed_args).to eq ["This", 1, "is", "an" => "arglist"]
235
+ end
236
+
237
+ it "defaults args to a blank array if nil" do
238
+ job.args = nil
239
+ job.save!
240
+
241
+ expect(load_job.args).to eq []
242
+ end
243
+ end
244
+
245
+ describe "staged_group_stage" do
246
+ it "returns a staged_group_stage object" do
247
+ expect(load_job.staged_group_stage).to be_a(Resque::Plugins::Stages::StagedGroupStage)
248
+ end
249
+
250
+ it "returns nil if the job does not exist" do
251
+ job.delete
252
+
253
+ expect(load_job.staged_group_stage).to be_nil
254
+ end
255
+ end
256
+
257
+ describe "completed?" do
258
+ %i[pending queued running pending_re_run].each do |status|
259
+ it "is not completed if status #{status}" do
260
+ job.status = status
261
+
262
+ expect(job.completed?).to be_falsey
263
+ end
264
+ end
265
+
266
+ %i[failed successful].each do |status|
267
+ it "is not completed if status #{status}" do
268
+ job.status = status
269
+
270
+ expect(job.completed?).to be_truthy
271
+ end
272
+ end
273
+ end
274
+
275
+ describe "queued?" do
276
+ %i[pending failed successful].each do |status|
277
+ it "is not completed if status #{status}" do
278
+ job.status = status
279
+
280
+ expect(job.queued?).to be_falsey
281
+ end
282
+ end
283
+
284
+ %i[queued running pending_re_run].each do |status|
285
+ it "is not completed if status #{status}" do
286
+ job.status = status
287
+
288
+ expect(job.queued?).to be_truthy
289
+ end
290
+ end
291
+ end
292
+
293
+ describe "pending?" do
294
+ %i[queued running failed successful].each do |status|
295
+ it "is not completed if status #{status}" do
296
+ job.status = status
297
+
298
+ expect(job.pending?).to be_falsey
299
+ end
300
+ end
301
+
302
+ %i[pending pending_re_run].each do |status|
303
+ it "is not completed if status #{status}" do
304
+ job.status = status
305
+
306
+ expect(job.pending?).to be_truthy
307
+ end
308
+ end
309
+ end
310
+
311
+ describe "blank?" do
312
+ it "is not blank if the job key exists" do
313
+ job
314
+
315
+ expect(load_job).to be_present
316
+ end
317
+
318
+ it "is blank if the job key is missing" do
319
+ job.delete
320
+
321
+ expect(load_job).to be_blank
322
+ end
323
+ end
324
+ end