resque-approve 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +30 -0
  4. data/lib/resque-approve.rb +10 -0
  5. data/lib/resque/approve_server.rb +232 -0
  6. data/lib/resque/plugins/approve.rb +77 -0
  7. data/lib/resque/plugins/approve/approval_key_list.rb +100 -0
  8. data/lib/resque/plugins/approve/cleaner.rb +44 -0
  9. data/lib/resque/plugins/approve/pending_job.rb +187 -0
  10. data/lib/resque/plugins/approve/pending_job_queue.rb +128 -0
  11. data/lib/resque/plugins/approve/redis_access.rb +16 -0
  12. data/lib/resque/plugins/version.rb +9 -0
  13. data/lib/resque/server/public/approve.css +56 -0
  14. data/lib/resque/server/views/_approval_key_list_pagination.erb +67 -0
  15. data/lib/resque/server/views/_approval_key_rows.erb +18 -0
  16. data/lib/resque/server/views/_job_list_table.erb +30 -0
  17. data/lib/resque/server/views/_job_pagination.erb +67 -0
  18. data/lib/resque/server/views/approval_keys.erb +66 -0
  19. data/lib/resque/server/views/job_details.erb +82 -0
  20. data/lib/resque/server/views/job_list.erb +58 -0
  21. data/lib/tasks/resque-approve_tasks.rake +6 -0
  22. data/spec/approve/approval_key_list_spec.rb +289 -0
  23. data/spec/approve/cleaner_spec.rb +96 -0
  24. data/spec/approve/pending_job_queue_spec.rb +219 -0
  25. data/spec/approve/pending_job_spec.rb +326 -0
  26. data/spec/approve_spec.rb +188 -0
  27. data/spec/examples.txt +135 -0
  28. data/spec/rails_helper.rb +35 -0
  29. data/spec/server/public/approve.css_spec.rb +18 -0
  30. data/spec/server/views/approval_keys.erb_spec.rb +105 -0
  31. data/spec/server/views/job_details.erb_spec.rb +133 -0
  32. data/spec/server/views/job_list.erb_spec.rb +108 -0
  33. data/spec/spec_helper.rb +101 -0
  34. data/spec/support/config/redis-auth.yml +12 -0
  35. data/spec/support/jobs/01_basic_job.rb +13 -0
  36. data/spec/support/jobs/auto_delete_approval_key_job.rb +5 -0
  37. data/spec/support/purge_all.rb +15 -0
  38. metadata +292 -0
@@ -0,0 +1,18 @@
1
+ <% summary_rows.each do |pending_job| %>
2
+ <tr>
3
+ <td>
4
+ <a href="<%= u("approve") %>/job_list?<%= { approval_key: pending_job.approval_key }.to_param %>">
5
+ <%= pending_job.approval_key %>
6
+ </a>
7
+ </td>
8
+ <td>
9
+ <%= pending_job.num_jobs.to_i %>
10
+ </td>
11
+ <td>
12
+ <% if pending_job.first_enqueued.present? %>
13
+ <%= time_ago_in_words(pending_job.first_enqueued) %> ago
14
+ (<%= pending_job.first_enqueued %>)
15
+ <% end %>
16
+ </td>
17
+ </tr>
18
+ <% end %>
@@ -0,0 +1,30 @@
1
+ <div class="table_container">
2
+ <table>
3
+ <tr>
4
+ <th>Class</th>
5
+ <th>Enqueued</th>
6
+ <th>Parameters</th>
7
+ <th>Options</th>
8
+ </tr>
9
+ <% jobs.each do |job_details| %>
10
+ <tr>
11
+ <td>
12
+ <a href="<%= u("approve/job_details") %>?<%=
13
+ { job_id: job_details.id }.to_param %>">
14
+ <%= job_details.class_name %>
15
+ </a>
16
+ </td>
17
+ <td>
18
+ <%= time_ago_in_words(job_details.queue_time) %> ago
19
+ (<%= job_details.queue_time %>)
20
+ </td>
21
+ <td>
22
+ <pre><code><%= "".html_safe + job_details.args.to_yaml %></code></pre>
23
+ </td>
24
+ <td>
25
+ <pre><code><%= "".html_safe + job_details.approve_options.to_hash.to_yaml %></code></pre>
26
+ </td>
27
+ </tr>
28
+ <% end %>
29
+ </table>
30
+ </div>
@@ -0,0 +1,67 @@
1
+ <div class="approve_pagination_block">
2
+ <% total_pages = pending_queue.num_jobs / page_size %>
3
+ <% total_pages += 1 if pending_queue.num_jobs % page_size > 0 %>
4
+ <% page_num = 1 if page_num > total_pages || page_num < 1 %>
5
+ <% first_page = [1, page_num - 3].max %>
6
+ <% last_page = [total_pages, page_num + 3].min %>
7
+ <% last_page = page_num < 4 ? [total_pages, last_page + (4 - page_num)].min : last_page %>
8
+ <% first_page = page_num > total_pages - 3 ? [1, first_page + ((total_pages - page_num) - 3)].max : first_page %>
9
+
10
+ <% if total_pages > 1 %>
11
+ <div class="approve_prev_links">
12
+ <a href="<%= u("approve/job_list") %>?<%=
13
+ { approval_key: approval_key,
14
+ page_size: page_size,
15
+ page_num: 1 }.to_param %>"
16
+ class="approve_first_page"
17
+ disabled="<%= first_page > 1 %>">
18
+ &lt;&lt; First
19
+ </a>
20
+
21
+ <a href="<%= u("approve/job_list") %>?<%=
22
+ { approval_key: approval_key,
23
+ page_size: page_size,
24
+ page_num: [1, page_num - 1].max }.to_param %>"
25
+ class="approve_prev_page"
26
+ disabled="<%= page_num > 1 %>">
27
+ &lt; Prev
28
+ </a>
29
+ </div>
30
+
31
+ <div class="approve_pages">
32
+ <% (first_page..last_page).each do |page_number| %>
33
+ <% if page_number != page_num %>
34
+ <a href="<%= u("approve/job_list") %>?<%=
35
+ { approval_key: approval_key,
36
+ page_size: page_size,
37
+ page_num: page_number }.to_param %>"
38
+ class="approve_page">
39
+ <%= page_number %>
40
+ </a>
41
+ <% else %>
42
+ <%= page_number %>
43
+ <% end %>
44
+ <% end %>
45
+ </div>
46
+
47
+ <div class="approve_next_links">
48
+ <a href="<%= u("approve/job_list") %>?<%=
49
+ { approval_key: approval_key,
50
+ page_size: page_size,
51
+ page_num: [total_pages, page_num + 1].min }.to_param %>"
52
+ class="approve_next_page"
53
+ disabled="<%= page_num < last_page %>">
54
+ Next &gt;
55
+ </a>
56
+
57
+ <a href="<%= u("approve/job_list") %>?<%=
58
+ { approval_key: approval_key,
59
+ page_size: page_size,
60
+ page_num: total_pages }.to_param %>"
61
+ class="approve_last_page"
62
+ disabled="<%= last_page < total_pages %>">
63
+ Last &gt;&gt;
64
+ </a>
65
+ </div>
66
+ <% end %>
67
+ </div>
@@ -0,0 +1,66 @@
1
+ <link href="<%= u("approve/public/approve.css") %>" media="screen" rel="stylesheet" type="text/css">
2
+
3
+ <h1>Approval Keys</h1>
4
+
5
+ <% approval_key_list = Resque::Plugins::Approve::ApprovalKeyList.new %>
6
+
7
+ <div class="approve_reset" />
8
+
9
+ <%= erb(File.read(Resque::ApproveServer.erb_path("_approval_key_list_pagination.erb")),
10
+ locals: { queue_list: approval_key_list, page_num: @page_num, page_size: @page_size }) %>
11
+
12
+ <div class="table_container">
13
+ <table>
14
+ <tr>
15
+ <th><a href="<%= u("approve") %>?<%=
16
+ { sort: "approval_key",
17
+ page_size: @page_size,
18
+ page_num: @page_num,
19
+ order: approval_key_list.
20
+ order_param("approval_key", @sort_by, @sort_order) }.to_param %>">
21
+ Approval Key
22
+ </a></th>
23
+ <th><a href="<%= u("approve") %>?<%=
24
+ { sort: "num_jobs",
25
+ page_size: @page_size,
26
+ page_num: @page_num,
27
+ order: approval_key_list.
28
+ order_param("num_jobs", @sort_by, @sort_order) }.to_param %>">
29
+ Pending Jobs
30
+ </a></th>
31
+ <th><a href="<%= u("approve") %>?<%=
32
+ { sort: "first_enqueued",
33
+ page_size: @page_size,
34
+ page_num: @page_num,
35
+ order: approval_key_list.
36
+ order_param("first_enqueued", @sort_by, @sort_order) }.to_param %>">
37
+ First Enqueued
38
+ </a></th>
39
+ </tr>
40
+
41
+ <%= erb(File.read(Resque::ApproveServer.erb_path("_approval_key_rows.erb")),
42
+ locals: { summary_rows: approval_key_list.queues(@sort_by, @sort_order, @page_num, @page_size) }) %>
43
+ </table>
44
+ </div>
45
+
46
+ <%= erb(File.read(Resque::ApproveServer.erb_path("_approval_key_list_pagination.erb")),
47
+ locals: { queue_list: approval_key_list, page_num: @page_num, page_size: @page_size }) %>
48
+
49
+ <br/>
50
+
51
+ <div>
52
+ <form method="POST" action="<%= u("approve/audit_jobs") %>">
53
+ <input type="submit" name="" value="Audit Jobs"/>
54
+ </form>
55
+ <form method="POST" action="<%= u("approve/audit_queues") %>">
56
+ <input type="submit" name="" value="Audit Queues"/>
57
+ </form>
58
+ <form method="POST" action="<%= u("approve/approve_all_queues") %>">
59
+ <input type="submit" name="" value="Approve All Queues"/>
60
+ </form>
61
+ <form method="POST" action="<%= u("approve/delete_all_queues") %>">
62
+ <input type="submit" name="" value="Delete All Queues"/>
63
+ </form>
64
+ </div>
65
+ <div class="approve_reset"/>
66
+ <br/>
@@ -0,0 +1,82 @@
1
+ <link href="<%= u("approve/public/approve.css") %>" media="screen" rel="stylesheet" type="text/css">
2
+
3
+ <% job_details = Resque::Plugins::Approve::PendingJob.new(@job_id) %>
4
+
5
+ <h1>
6
+ <%= job_details.class_name %>
7
+ </h1>
8
+
9
+ <p>
10
+ <a href="<%= u("approve") %>">
11
+ Approval Keys
12
+ </a>
13
+ |
14
+ <a href="<%= u("approve/job_list") %>?<%= { approval_key: job_details.approval_key }.to_param %>">
15
+ <%= job_details.approval_key %>
16
+ </a>
17
+ </p>
18
+
19
+ <div class="table_container">
20
+ <table>
21
+ <tr>
22
+ <td>
23
+ Enqueued
24
+ </td>
25
+ <td>
26
+ <%= time_ago_in_words(job_details.queue_time) %> ago
27
+ (<%= job_details.queue_time %>)
28
+ </td>
29
+ </tr>
30
+ <tr>
31
+ <td>
32
+ Class
33
+ </td>
34
+ <td>
35
+ <%= job_details.class_name %>
36
+ </td>
37
+ </tr>
38
+ </tr>
39
+ <tr>
40
+ <td>
41
+ Params
42
+ </td>
43
+ <td>
44
+ <pre><code><%= "".html_safe + job_details.args.to_yaml %></code></pre>
45
+ </td>
46
+ </tr>
47
+ <tr>
48
+ <td>
49
+ Queue
50
+ </td>
51
+ <td>
52
+ <%= job_details.approval_queue %>
53
+ </td>
54
+ </tr>
55
+ <% if job_details.approval_at.present? && job_details.approval_at > Time.now %>
56
+ <tr>
57
+ <td>
58
+ Enqueue After
59
+ </td>
60
+ <td>
61
+ <%= job_details.approval_at %>
62
+ </td>
63
+ </tr>
64
+ <% end %>
65
+ </table>
66
+ </div>
67
+
68
+ <br/>
69
+
70
+ <form method="POST" action="<%= u("approve/delete_job") %>?<%=
71
+ { job_id: @job_id }.to_param %>">
72
+ <input type="submit" name="" value="Delete Job"/>
73
+ </form>
74
+
75
+ <form method="POST" action="<%= u("approve/approve_job") %>?<%=
76
+ { job_id: @job_id }.to_param %>">
77
+ <input type="submit" name="" value="Approve Job"/>
78
+ </form>
79
+
80
+ <div class="approve_reset"/>
81
+
82
+ <br/>
@@ -0,0 +1,58 @@
1
+ <link href="<%= u("approve/public/approve.css") %>" media="screen" rel="stylesheet" type="text/css">
2
+
3
+ <% pending_queue = Resque::Plugins::Approve::PendingJobQueue.new(@approval_key) %>
4
+
5
+ <h1>
6
+ <%= pending_queue.approval_key %>
7
+ </h1>
8
+
9
+ <p>
10
+ <a href="<%= u("approve") %>">
11
+ Approval Keys
12
+ </a>
13
+ </p>
14
+
15
+ <% if pending_queue.num_jobs > 0 %>
16
+ <h1>Jobs</h1>
17
+
18
+ <% jobs = pending_queue.paged_jobs(@page_num, @page_size) %>
19
+ <%= erb(File.read(Resque::ApproveServer.erb_path("_job_pagination.erb")),
20
+ locals: { pending_queue: pending_queue,
21
+ approval_key: @approval_key,
22
+ page_num: @page_num,
23
+ page_size: @page_size }) %>
24
+
25
+ <%= erb(File.read(Resque::ApproveServer.erb_path("_job_list_table.erb")),
26
+ locals: { jobs: jobs, show_class: false }) %>
27
+
28
+ <%= erb(File.read(Resque::ApproveServer.erb_path("_job_pagination.erb")),
29
+ locals: { pending_queue: pending_queue,
30
+ approval_key: @approval_key,
31
+ page_num: @page_num,
32
+ page_size: @page_size }) %>
33
+
34
+ <br/>
35
+
36
+ <form method="POST" action="<%= u("approve/delete_queue") %>?<%=
37
+ { approval_key: pending_queue.approval_key }.to_param %>">
38
+ <input type="submit" name="" value="Delete All"/>
39
+ </form>
40
+
41
+ <form method="POST" action="<%= u("approve/delete_one_queue") %>?<%=
42
+ { approval_key: pending_queue.approval_key }.to_param %>">
43
+ <input type="submit" name="" value="Delete One"/>
44
+ </form>
45
+
46
+ <form method="POST" action="<%= u("approve/approve_queue") %>?<%=
47
+ { approval_key: pending_queue.approval_key }.to_param %>">
48
+ <input type="submit" name="" value="Approve All"/>
49
+ </form>
50
+
51
+ <form method="POST" action="<%= u("approve/approve_one_queue") %>?<%=
52
+ { approval_key: pending_queue.approval_key }.to_param %>">
53
+ <input type="submit" name="" value="Approve One"/>
54
+ </form>
55
+ <% end %>
56
+
57
+ <div class="approve_reset"/>
58
+ <br/>
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # desc "Explaining what the task does"
4
+ # task :resque do
5
+ # # Task goes here
6
+ # end
@@ -0,0 +1,289 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails_helper"
4
+
5
+ RSpec.describe Resque::Plugins::Approve::ApprovalKeyList do
6
+ let(:key_list) { Resque::Plugins::Approve::ApprovalKeyList.new }
7
+ let!(:key) { Faker::Lorem.sentence }
8
+ let(:job) { Resque::Plugins::Approve::PendingJob.new SecureRandom.uuid, class_name: BasicJob, args: [approval_key: key] }
9
+ let(:job_queue) { Resque::Plugins::Approve::PendingJobQueue.new(key) }
10
+ let(:multiple_queues) { Array.new(3) { Faker::Lorem.sentence } }
11
+ let(:multiple_jobs) do
12
+ index = 0
13
+ multiple_queues.map do |approval_key|
14
+ Array.new(4) do
15
+ job = Resque::Plugins::Approve::PendingJob.new(SecureRandom.uuid, class_name: BasicJob, args: [index, approval_key: approval_key])
16
+
17
+ index += 1
18
+ key_list.add_job(job)
19
+
20
+ job
21
+ end
22
+ end
23
+ end
24
+
25
+ describe "#order_param" do
26
+ it "returns asc for any column other than the current one" do
27
+ expect(key_list.order_param("sort_option",
28
+ "current_sort",
29
+ %w[asc desc].sample)).to eq "asc"
30
+ end
31
+
32
+ it "returns desc for the current column if it is asc" do
33
+ expect(key_list.order_param("sort_option", "sort_option", "asc")).to eq "desc"
34
+ end
35
+
36
+ it "returns asc for the current column if it is desc" do
37
+ expect(key_list.order_param("sort_option", "sort_option", "desc")).to eq "asc"
38
+ end
39
+ end
40
+
41
+ describe "remove_key" do
42
+ it "removes the key if it is in the list" do
43
+ key_list.add_key key
44
+ 10.times do
45
+ key_list.add_key(Faker::Lorem.sentence)
46
+ end
47
+
48
+ expect { key_list.remove_key key }.to(change { Resque::Plugins::Approve::ApprovalKeyList.new.num_queues }.by(-1))
49
+ end
50
+
51
+ it "does nothing if it is not in the list" do
52
+ 10.times do
53
+ key_list.add_key(Faker::Lorem.sentence)
54
+ end
55
+
56
+ expect { key_list.remove_key key }.not_to(change { Resque::Plugins::Approve::ApprovalKeyList.new.num_queues })
57
+ end
58
+ end
59
+
60
+ describe "add_key" do
61
+ it "adds the key if it is not in the list" do
62
+ 10.times do
63
+ key_list.add_key(Faker::Lorem.sentence)
64
+ end
65
+
66
+ expect { key_list.add_key key }.to(change { Resque::Plugins::Approve::ApprovalKeyList.new.num_queues }.by(1))
67
+ end
68
+
69
+ it "does nothing if it is in the list" do
70
+ key_list.add_key key
71
+ 10.times do
72
+ key_list.add_key(Faker::Lorem.sentence)
73
+ end
74
+
75
+ expect { key_list.add_key key }.not_to(change { Resque::Plugins::Approve::ApprovalKeyList.new.num_queues })
76
+ end
77
+ end
78
+
79
+ describe "add_job" do
80
+ it "adds the key if it is not in the list" do
81
+ 10.times do
82
+ key_list.add_key(Faker::Lorem.sentence)
83
+ end
84
+
85
+ expect { key_list.add_job job }.to(change { Resque::Plugins::Approve::ApprovalKeyList.new.num_queues }.by(1))
86
+ end
87
+
88
+ it "does not add the key if it is in the list" do
89
+ key_list.add_key key
90
+ 10.times do
91
+ key_list.add_key(Faker::Lorem.sentence)
92
+ end
93
+
94
+ expect { key_list.add_job job }.not_to(change { Resque::Plugins::Approve::ApprovalKeyList.new.num_queues })
95
+ end
96
+
97
+ it "adds the job to the queue if it isn't already there" do
98
+ 10.times do
99
+ key_list.add_key(Faker::Lorem.sentence)
100
+ end
101
+
102
+ key_list.add_job job
103
+
104
+ expect(job_queue.jobs.last.id).to eq job.id
105
+ expect(job_queue.jobs.last).to eq job
106
+ end
107
+ end
108
+
109
+ describe "delete_all" do
110
+ before(:each) do
111
+ multiple_jobs
112
+ end
113
+
114
+ it "deletes all jobs for all queues" do
115
+ key_list.delete_all
116
+
117
+ multiple_jobs.flatten.each do |job|
118
+ expect(Resque::Plugins::Approve::PendingJob.new(job.id).class_name).to be_blank
119
+ end
120
+ end
121
+
122
+ it "deletes all queues" do
123
+ queues = key_list.queues
124
+
125
+ key_list.delete_all
126
+
127
+ queues.each do |queue|
128
+ expect(queue.num_jobs).to be_zero
129
+ end
130
+ end
131
+
132
+ it "deletes all keys" do
133
+ key_list.delete_all
134
+
135
+ expect(Resque::Plugins::Approve::ApprovalKeyList.new.num_queues).to be_zero
136
+ end
137
+ end
138
+
139
+ describe "approve_all" do
140
+ before(:each) do
141
+ multiple_jobs
142
+
143
+ allow(Resque).to receive(:enqueue_to).and_call_original
144
+ end
145
+
146
+ it "approves all jobs for all queues" do
147
+ key_list.approve_all
148
+
149
+ index = 0
150
+ multiple_jobs.flatten.each do |job|
151
+ expect(Resque::Plugins::Approve::PendingJob.new(job.id).class_name).to be_blank
152
+ expect(Resque).to have_received(:enqueue_to).with "Some_Queue", BasicJob, index
153
+
154
+ index += 1
155
+ end
156
+ end
157
+
158
+ it "approves all queues" do
159
+ queues = key_list.queues
160
+
161
+ key_list.approve_all
162
+
163
+ queues.each do |queue|
164
+ expect(queue.num_jobs).to be_zero
165
+ end
166
+ end
167
+
168
+ it "does not delete any keys" do
169
+ key_list.approve_all
170
+
171
+ expect(Resque::Plugins::Approve::ApprovalKeyList.new.num_queues).to eq 3
172
+ end
173
+ end
174
+
175
+ describe "queues" do
176
+ let(:sorted_queue_names) { Array.new(30) { |index| "#{index.to_s.rjust(3, "0")} - #{Faker::Lorem.sentence}" } }
177
+ let(:sorted_age) { Array.new(30) { |index| sorted_queue_names[ages.find_index(index)] }.reverse }
178
+ let(:sorted_counts) { Array.new(30) { |index| sorted_queue_names[counts.find_index(index)] } }
179
+ let(:ages) { Array.new(30) { |index| index }.sample(100) }
180
+ let(:counts) { Array.new(30) { |index| index }.sample(100) }
181
+ let!(:jobs) do
182
+ index = 0
183
+
184
+ sorted_queue_names.map do |approval_key|
185
+ Timecop.freeze(ages[index].hours.ago) do
186
+ Array.new(1 + counts[index]) do
187
+ job = Resque::Plugins::Approve::PendingJob.new(SecureRandom.uuid, class_name: BasicJob, args: [approval_key: approval_key])
188
+
189
+ key_list.add_job(job)
190
+
191
+ job
192
+ end
193
+ end
194
+
195
+ index += 1
196
+ end
197
+ end
198
+
199
+ RSpec.shared_examples("pages queues") do
200
+ it "defaults to return the first 20 queues ascending" do
201
+ expect(key_list.queues(sort_key).map(&:approval_key)).to eq sorted_values[0..19]
202
+ end
203
+
204
+ it "does not allow negative page sizes" do
205
+ expect(key_list.queues(sort_key, 0, 0).map(&:approval_key)).to eq sorted_values[0..19]
206
+ end
207
+
208
+ it "pages ascending" do
209
+ expect(key_list.queues(sort_key, "asc", 4, 3).map(&:approval_key)).
210
+ to eq sorted_values[9..11]
211
+ end
212
+
213
+ it "sorts descending" do
214
+ expect(key_list.queues(sort_key, "desc").map(&:approval_key)).
215
+ to eq sorted_values.reverse[0..19]
216
+ end
217
+
218
+ it "pages descending" do
219
+ expect(key_list.queues(sort_key, "desc", 4, 3).map(&:approval_key)).
220
+ to eq sorted_values.reverse[9..11]
221
+ end
222
+
223
+ it "does not do negative pages" do
224
+ expect(key_list.queues(sort_key, "desc", -4, 3).map(&:approval_key)).
225
+ to eq sorted_values.reverse[0..2]
226
+ end
227
+
228
+ it "does not do to large pages" do
229
+ expect(key_list.queues(sort_key, "desc", 400, 3).map(&:approval_key)).
230
+ to eq sorted_values.reverse[0..2]
231
+ end
232
+ end
233
+
234
+ describe "approval_key" do
235
+ let(:sort_key) { :approval_key }
236
+ let(:sorted_values) { sorted_queue_names }
237
+
238
+ it_behaves_like "pages queues"
239
+ end
240
+
241
+ describe "num_jobs" do
242
+ let(:sort_key) { :num_jobs }
243
+ let(:sorted_values) { sorted_counts }
244
+
245
+ it_behaves_like "pages queues"
246
+ end
247
+
248
+ describe "first_enqueued" do
249
+ let(:sort_key) { :first_enqueued }
250
+ let(:sorted_values) { sorted_age }
251
+
252
+ it_behaves_like "pages queues"
253
+ end
254
+ end
255
+
256
+ describe "job_queues" do
257
+ let(:sorted_queue_names) { Array.new(30) { |index| "#{index.to_s.rjust(3, "0")} - #{Faker::Lorem.sentence}" } }
258
+ let!(:jobs) do
259
+ sorted_queue_names.map do |approval_key|
260
+ job = Resque::Plugins::Approve::PendingJob.new(SecureRandom.uuid, class_name: BasicJob, args: [approval_key: approval_key])
261
+
262
+ key_list.add_job(job)
263
+
264
+ job
265
+ end
266
+ end
267
+
268
+ it "returns all queues unsorted" do
269
+ expect(key_list.job_queues.map(&:approval_key).sort).to eq sorted_queue_names
270
+ end
271
+ end
272
+
273
+ describe "num_queues" do
274
+ let(:sorted_queue_names) { Array.new(30) { |index| "#{index.to_s.rjust(3, "0")} - #{Faker::Lorem.sentence}" } }
275
+ let!(:jobs) do
276
+ sorted_queue_names.map do |approval_key|
277
+ job = Resque::Plugins::Approve::PendingJob.new(SecureRandom.uuid, class_name: BasicJob, args: [approval_key: approval_key])
278
+
279
+ key_list.add_job(job)
280
+
281
+ job
282
+ end
283
+ end
284
+
285
+ it "returns the total number of queues" do
286
+ expect(key_list.num_queues).to eq 30
287
+ end
288
+ end
289
+ end