sqs_web 0.0.1 → 0.0.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 402d02606f9f97d50fa51892ee6b372b34d13cea
4
- data.tar.gz: 85af922a688dbbe657cd445030827184203fb5eb
3
+ metadata.gz: 1255501537a0297a7b1eda47890fc64bc4919b74
4
+ data.tar.gz: 9663fb87014c3efe614e7c30c532657fa60897ed
5
5
  SHA512:
6
- metadata.gz: fbe157d2c9d2342154a0eb92f043c50664e27afc1dabe04133c93d60ac70cd5371cabb021a880c2b66c2ab77abdd91734e4952d1a7dacc3cd90c58da59a2bb04
7
- data.tar.gz: 34d78f607cfaae8ab4d007d2aa698eff188ad41829007b38c319b9c99cb0f34f8a3f64b1255dbce512d8287ffb10f7b8000993b49c9136585cbd3a350a68754f
6
+ metadata.gz: f61f3cb396aa0bff8b8e4dcaca1166c7625c16201fb092e7fae80c9e71ca51fffb8997ee7a7cfddb74f480ef638df4cf5060c3bd5f80cba76ae60adccd6b7503
7
+ data.tar.gz: 179b3470d93fc17143e5acba25e9d769f9ad73eb0b231095b045c22ebb2f0694f6b3fa789a024028af8fc7f67f81e94913a5f732118ece790305b45ca6e3c0b8
@@ -1,6 +1,4 @@
1
1
  $(function() {
2
- var poll_interval = 3;
3
-
4
2
  var relatizer = function(){
5
3
  var dt = $(this).text(), relatized = $.relatizeDate(this)
6
4
  if ($(this).parents("a").length > 0 || $(this).is("a")) {
@@ -55,4 +53,16 @@ $(function() {
55
53
  $("#bulk_action_submit input").click(function() {
56
54
  $('#bulk_action_form').attr("action", $(this).attr("action"));
57
55
  });
56
+
57
+ $(".remove_single").click(function(e) {
58
+ if (!confirm("Are you sure you want to remove the message?")){
59
+ e.preventDefault();
60
+ }
61
+ });
62
+
63
+ $(".remove_bulk").click(function(e) {
64
+ if (!confirm("Are you sure you want to remove the selected messages?")){
65
+ e.preventDefault();
66
+ }
67
+ });
58
68
  })
@@ -10,7 +10,7 @@
10
10
  <%= csrf_token_tag %>
11
11
  Select/Unselect All <input type="checkbox" id="select_all" />
12
12
  <div id="bulk_action_submit">
13
- <input type="submit" value="Bulk Remove" action="<%= u("bulk_remove") %>"/>
13
+ <input class="remove_bulk" type="submit" value="Bulk Remove" action="<%= u("bulk_remove") %>"/>
14
14
  <input type="submit" value="Bulk Move to Source Queue" action="<%= u("bulk_requeue") %>"/>
15
15
  </div>
16
16
  </form>
@@ -8,7 +8,7 @@
8
8
  <div class="controls">
9
9
  <form action="<%= u("remove/#{queue[:name]}/#{message.message_id}") %>" method="post">
10
10
  <%= csrf_token_tag %>
11
- <input type="submit" value="Remove" />
11
+ <input class="remove_single" type="submit" value="Remove" />
12
12
  </form>
13
13
  or
14
14
  <form action="<%= u("requeue/#{queue[:name]}/#{message.message_id}") %>" method="post">
@@ -1,33 +1,4 @@
1
- require 'support/rails_app'
2
- require 'support/fake_sqs'
3
-
4
- Capybara.app = RailsApp
5
-
6
- RSpec.describe "Mounted in Rails Application", :sqs do
7
-
8
- SOURCE_QUEUE_NAME = "TestSourceQueue"
9
-
10
- DLQ_QUEUE_NAME = "TestSourceQueueDLQ"
11
-
12
- let(:sqs) { Aws::SQS::Client.new(region: "us-east-1", credentials: Aws::Credentials.new("fake", "fake")) }
13
-
14
- let(:source_queue_url) { sqs.get_queue_url(queue_name: SOURCE_QUEUE_NAME).queue_url }
15
-
16
- let(:dlq_queue_url) { sqs.get_queue_url(queue_name: DLQ_QUEUE_NAME).queue_url }
17
-
18
- before do
19
- sqs.config.endpoint = $fake_sqs.uri
20
- [SOURCE_QUEUE_NAME, DLQ_QUEUE_NAME].each{|queue_name| sqs.create_queue(queue_name: queue_name)}
21
- dlq_arn = sqs.get_queue_attributes(queue_url: dlq_queue_url).attributes.fetch("QueueArn")
22
- #Set DLQ
23
- sqs.set_queue_attributes(
24
- queue_url: source_queue_url,
25
- attributes: {
26
- "RedrivePolicy" => "{\"deadLetterTargetArn\":\"#{dlq_arn}\",\"maxReceiveCount\":10}"
27
- }
28
- )
29
- SqsWeb.options[:queues] = [SOURCE_QUEUE_NAME, DLQ_QUEUE_NAME]
30
- end
1
+ RSpec.describe "General Application features", :sqs do
31
2
 
32
3
  # basic smoke test all the tabs
33
4
  %w(overview dlq_console).each do |tab|
@@ -36,334 +7,4 @@ RSpec.describe "Mounted in Rails Application", :sqs do
36
7
  expect(page.status_code).to eq 200
37
8
  end
38
9
  end
39
-
40
- describe "Overview page" do
41
- it "will show Visible Messages" do
42
- default_messages
43
-
44
- visit "/sqs/overview"
45
-
46
- match_content(page, "#{SOURCE_QUEUE_NAME} 5 0 N/A")
47
- match_content(page, "#{DLQ_QUEUE_NAME} 3 0 #{source_queue_url}")
48
- end
49
-
50
- specify "In Flight Messages" do
51
- default_messages
52
-
53
- receive_messages(source_queue_url, {count: 3})
54
- receive_messages(dlq_queue_url, {count: 2})
55
-
56
- visit "/sqs/overview"
57
-
58
- match_content(page, "#{SOURCE_QUEUE_NAME} 2 3 N/A")
59
- match_content(page, "#{DLQ_QUEUE_NAME} 1 2 #{source_queue_url}")
60
- end
61
-
62
- specify "should be default page" do
63
- visit "/sqs"
64
-
65
- expect(current_path).to eq "/sqs/overview"
66
- end
67
-
68
- specify "handle non existent queues" do
69
- SqsWeb.options[:queues] = ["BOGUSQUEUE"]
70
-
71
- visit "/sqs/overview"
72
-
73
- match_content(page, "Aws::SQS::Errors::NonExistentQueue: BOGUSQUEUE")
74
- end
75
- end
76
-
77
- describe "DLQ Console", js: true do
78
-
79
- it "should only show unique entries for each message" do
80
- message_ids = generate_messages(dlq_queue_url, 5).map{|c| c.message_id}
81
-
82
- visit "/sqs/dlq_console"
83
-
84
- message_ids.each{|message_id| expect(page.all("#message_#{message_id}").count).to eq 1}
85
- end
86
-
87
- it "should delete single message" do
88
- messages = generate_messages(dlq_queue_url, 2)
89
- deleted_message_id = messages.pop.message_id
90
- retained_message_id = messages.pop.message_id
91
-
92
- visit "/sqs/dlq_console"
93
-
94
- first("#message_#{deleted_message_id}").hover
95
-
96
- within("#message_#{deleted_message_id}") do
97
- click_on "Remove"
98
- end
99
-
100
- success_message = "Message ID: #{deleted_message_id} in Queue #{DLQ_QUEUE_NAME} was successfully removed."
101
- expect(first("#alert").text).to eq success_message
102
-
103
- expect(page.all("#message_#{deleted_message_id}").count).to eq 0
104
- expect(page.all("#message_#{retained_message_id}").count).to eq 1
105
-
106
- visit "/sqs/overview"
107
-
108
- match_content(page, "#{DLQ_QUEUE_NAME} 1 0 #{source_queue_url}")
109
- end
110
-
111
- it "should handle deleting single message that is already deleted" do
112
- deleted_message_id = generate_messages(dlq_queue_url, 1).first.message_id
113
-
114
- visit "/sqs/dlq_console"
115
-
116
- sqs.purge_queue({ queue_url: dlq_queue_url })
117
-
118
- first("#message_#{deleted_message_id}").hover
119
-
120
- within("#message_#{deleted_message_id}") do
121
- click_on "Remove"
122
- end
123
-
124
- error_message = "Message ID: #{deleted_message_id} in Queue #{DLQ_QUEUE_NAME} has already been deleted or is not visible."
125
- expect(first("#alert").text).to eq error_message
126
- end
127
-
128
- it "should remove multiple selected messages" do
129
- messages = generate_messages(dlq_queue_url, 6)
130
- deleted_message_ids = messages.pop(4).map{|c| c.message_id}
131
- retained_message_ids = messages.pop(2).map{|c| c.message_id}
132
-
133
- visit "/sqs/dlq_console"
134
-
135
- deleted_message_ids.each do |message_id|
136
- first("#batch_action_item_#{message_id}").set(true)
137
- end
138
-
139
- click_on "Bulk Remove"
140
-
141
- expect(first("#alert").text).to eq "Selected messages have been removed successfully."
142
-
143
- deleted_message_ids.each{|message_id| expect(page.all("#message_#{message_id}").count).to eq 0}
144
- retained_message_ids.each{|message_id| expect(page.all("#message_#{message_id}").count).to eq 1}
145
-
146
- visit "/sqs/overview"
147
-
148
- match_content(page, "#{DLQ_QUEUE_NAME} 2 0 #{source_queue_url}")
149
- end
150
-
151
- it "should handle removing multiple selected messages where one or more is already deleted or not visible" do
152
- generate_messages(dlq_queue_url, 3)
153
-
154
- visit "/sqs/dlq_console"
155
-
156
- messages = receive_messages(dlq_queue_url, {count: 3}).messages
157
- sqs.delete_message({queue_url: dlq_queue_url, receipt_handle: messages[2].receipt_handle})
158
- sqs.change_message_visibility_batch({
159
- queue_url: dlq_queue_url,
160
- entries: messages.take(2).map do |message|
161
- {id: message.message_id, receipt_handle: message.receipt_handle, visibility_timeout: 0}
162
- end
163
- })
164
- messages.each do |message|
165
- first("#batch_action_item_#{message.message_id}").set(true)
166
- end
167
-
168
- click_on "Bulk Remove"
169
-
170
- expect(first("#alert").text).to eq "One or more messages may have already been removed or is not visible."
171
-
172
- messages.each{|message| expect(page.all("#message_#{message.message_id}").count).to eq 0}
173
-
174
- visit "/sqs/overview"
175
-
176
- match_content(page, "#{DLQ_QUEUE_NAME} 0 0 #{source_queue_url}")
177
- end
178
-
179
- it "should handle clicking on Bulk Remove without any selection" do
180
- messages = generate_messages(dlq_queue_url, 3)
181
-
182
- visit "/sqs/dlq_console"
183
-
184
- click_on "Bulk Remove"
185
-
186
- expect(first("#alert").text).to eq ""
187
-
188
- messages.each{|message| expect(page.all("#message_#{message.message_id}").count).to eq 1}
189
- end
190
-
191
- it "should render all information related to the visible messages" do
192
- generate_messages(dlq_queue_url, 1)
193
-
194
- visit "/sqs/dlq_console"
195
-
196
- message = receive_messages(dlq_queue_url).messages.first
197
- message.attributes["ApproximateReceiveCount"] = "1"
198
-
199
- message_metadata = <<-EOF
200
- ID #{message.message_id} or Receive Count 1
201
- Queue Name #{DLQ_QUEUE_NAME} Origin Queue #{source_queue_url}
202
- Message Body Test_0
203
- EOF
204
-
205
- message_entry = first("#message_#{message.message_id}")
206
-
207
- within(message_entry) do
208
- click_on "Toggle full message"
209
- first(".toggle_format").click
210
- end
211
-
212
- match_content(message_entry, normalize_whitespace(message_metadata))
213
- match_content(message_entry, normalize_whitespace(message.inspect.to_yaml.split('receipt_handle')[0]))
214
- match_content(message_entry, normalize_whitespace(message.inspect.to_yaml.split('md5', 2)[1]))
215
- match_content(message_entry, normalize_whitespace("Enqueued At #{Time.at(message.attributes["SentTimestamp"].to_i/1000).rfc822}"))
216
- end
217
-
218
- it "should not display any messages that are not in a DLQ" do
219
- generate_messages(source_queue_url, 1)
220
-
221
- visit "/sqs/dlq_console"
222
-
223
- message = receive_messages(source_queue_url).messages.first
224
-
225
- expect(first("#message_#{message.message_id}")).to be_nil
226
-
227
- match_content(page, "Showing 0 visible messages")
228
- end
229
-
230
- it "should be able to move a single message to source queue" do
231
- message_id = generate_messages(dlq_queue_url, 1).first.message_id
232
-
233
-
234
- visit "/sqs/dlq_console"
235
-
236
- first("#message_#{message_id}").hover
237
-
238
- within("#message_#{message_id}") do
239
- click_on "Move to Source Queue"
240
- end
241
-
242
- success_message = "Message ID: #{message_id} in Queue #{DLQ_QUEUE_NAME} was successfully moved to Source Queue #{source_queue_url}."
243
- expect(first("#alert").text).to eq success_message
244
- expect(page.all("#message_#{message_id}").count).to eq 0
245
-
246
- visit "/sqs/overview"
247
-
248
- match_content(page, "#{SOURCE_QUEUE_NAME} 1 0 N/A")
249
- match_content(page, "#{DLQ_QUEUE_NAME} 0 0 #{source_queue_url}")
250
-
251
- moved_message = receive_messages(source_queue_url).messages.first
252
- expect(moved_message).to_not be_nil
253
- expect(moved_message.body).to eq "Test_0"
254
- expect(moved_message.attributes["ApproximateReceiveCount"]).to eq "1"
255
- expect(moved_message.message_attributes["foo_class"].to_hash).to eq({string_value: "FooWorker", data_type: "String"})
256
- end
257
-
258
- it "should move multiple selected messages" do
259
- messages = generate_messages(dlq_queue_url, 6)
260
- retained_message_ids = messages.pop(2).map{|c| c.message_id}
261
- moved_message_ids = messages.pop(4).map{|c| c.message_id}
262
-
263
- visit "/sqs/dlq_console"
264
-
265
- moved_message_ids.each do |message_id|
266
- first("#batch_action_item_#{message_id}").set(true)
267
- end
268
-
269
- click_on "Bulk Move to Source Queue"
270
-
271
- expect(first("#alert").text).to eq "Selected messages have been requeued successfully."
272
-
273
- moved_message_ids.each{|message_id| expect(page.all("#message_#{message_id}").count).to eq 0}
274
- retained_message_ids.each{|message_id| expect(page.all("#message_#{message_id}").count).to eq 1}
275
-
276
- visit "/sqs/overview"
277
-
278
- match_content(page, "#{SOURCE_QUEUE_NAME} 4 0 N/A")
279
- match_content(page, "#{DLQ_QUEUE_NAME} 2 0 #{source_queue_url}")
280
-
281
- moved_messages = receive_messages(source_queue_url, {count: 4}).messages.sort_by{|c| c.body}
282
- moved_messages.each_with_index do |moved_message, index|
283
- expect(moved_message).to_not be_nil
284
- expect(moved_message.body).to match "Test_#{index}"
285
- expect(moved_message.attributes["ApproximateReceiveCount"]).to eq "1"
286
- expect(moved_message.message_attributes["foo_class"].to_hash).to eq({string_value: "FooWorker", data_type: "String"})
287
- end
288
- end
289
-
290
- it "should handle moving multiple selected messages where one or more is already deleted or not visible" do
291
- generate_messages(dlq_queue_url, 3)
292
-
293
- visit "/sqs/dlq_console"
294
-
295
- messages = receive_messages(dlq_queue_url, {count: 3}).messages
296
- sqs.delete_message({queue_url: dlq_queue_url, receipt_handle: messages[2].receipt_handle})
297
- sqs.change_message_visibility_batch({
298
- queue_url: dlq_queue_url,
299
- entries: messages.take(2).map do |message|
300
- {id: message.message_id, receipt_handle: message.receipt_handle, visibility_timeout: 0}
301
- end
302
- })
303
- messages.each do |message|
304
- first("#batch_action_item_#{message.message_id}").set(true)
305
- end
306
-
307
- click_on "Bulk Move to Source Queue"
308
-
309
- expect(first("#alert").text).to eq "One or more messages may have already been requeued or is not visible."
310
-
311
- messages.each{|message| expect(page.all("#message_#{message.message_id}").count).to eq 0}
312
-
313
- visit "/sqs/overview"
314
-
315
- match_content(page, "#{SOURCE_QUEUE_NAME} 2 0 N/A")
316
- match_content(page, "#{DLQ_QUEUE_NAME} 0 0 #{source_queue_url}")
317
- end
318
-
319
- it "should handle clicking on Bulk Move to Source Queue without any selection" do
320
- messages = generate_messages(dlq_queue_url, 3)
321
-
322
- visit "/sqs/dlq_console"
323
-
324
- click_on "Bulk Move to Source Queue"
325
-
326
- expect(first("#alert").text).to eq ""
327
-
328
- messages.each{|message| expect(page.all("#message_#{message.message_id}").count).to eq 1}
329
- end
330
-
331
- it "should have a select/unselect all function" do
332
- messages = generate_messages(dlq_queue_url, 3)
333
-
334
- visit "/sqs/dlq_console"
335
-
336
- first("#select_all").click
337
-
338
- page.all(".bulk_check").each{|node| expect(node["checked"]).to eq true}
339
-
340
- first("#select_all").click
341
-
342
- page.all(".bulk_check").each{|node| expect(node["checked"]).to eq false}
343
- end
344
- end
345
-
346
- def receive_messages(queue_url, options = {count: 1})
347
- sqs.receive_message({
348
- queue_url: queue_url,
349
- attribute_names: ["All"],
350
- message_attribute_names: ["All"],
351
- max_number_of_messages: options[:count],
352
- wait_time_seconds: 1,
353
- visibility_timeout: options[:visibility_timeout]
354
- })
355
- end
356
-
357
- def default_messages
358
- generate_messages(source_queue_url, 5) + generate_messages(dlq_queue_url, 3)
359
- end
360
-
361
- def generate_messages(queue_url, count=1)
362
- messages = []
363
- count.times do |time|
364
- messages << sqs.send_message(queue_url: queue_url, message_body: "Test_#{time}",
365
- message_attributes: {"foo_class"=> {string_value: "FooWorker", data_type: "String"}})
366
- end
367
- messages
368
- end
369
10
  end
@@ -0,0 +1,308 @@
1
+ RSpec.describe "DLQ Console", js: true, sqs: true do
2
+
3
+ it "should only show unique entries for each message" do
4
+ message_ids = generate_messages(dlq_queue_url, 5).map{|c| c.message_id}
5
+
6
+ visit "/sqs/dlq_console"
7
+
8
+ message_ids.each{|message_id| expect(page.all("#message_#{message_id}").count).to eq 1}
9
+ end
10
+
11
+ it "should render all information related to the visible messages" do
12
+ generate_messages(dlq_queue_url, 1)
13
+
14
+ visit "/sqs/dlq_console"
15
+
16
+ message = receive_messages(dlq_queue_url).messages.first
17
+ message.attributes["ApproximateReceiveCount"] = "1"
18
+
19
+ message_metadata = <<-EOF
20
+ ID #{message.message_id} or Receive Count 1
21
+ Queue Name #{DLQ_QUEUE_NAME} Origin Queue #{source_queue_url}
22
+ Message Body Test_0
23
+ EOF
24
+
25
+ message_entry = first("#message_#{message.message_id}")
26
+
27
+ within(message_entry) do
28
+ click_on "Toggle full message"
29
+ first(".toggle_format").click
30
+ end
31
+
32
+ match_content(message_entry, normalize_whitespace(message_metadata))
33
+ match_content(message_entry, normalize_whitespace(message.inspect.to_yaml.split('receipt_handle')[0]))
34
+ match_content(message_entry, normalize_whitespace(message.inspect.to_yaml.split('md5', 2)[1]))
35
+ match_content(message_entry, normalize_whitespace("Enqueued At #{Time.at(message.attributes["SentTimestamp"].to_i/1000).rfc822}"))
36
+ end
37
+
38
+ it "should not display any messages that are not in a DLQ" do
39
+ generate_messages(source_queue_url, 1)
40
+
41
+ visit "/sqs/dlq_console"
42
+
43
+ message = receive_messages(source_queue_url).messages.first
44
+
45
+ expect(first("#message_#{message.message_id}")).to be_nil
46
+
47
+ match_content(page, "Showing 0 visible messages")
48
+ end
49
+
50
+ it "should have a select/unselect all function" do
51
+ messages = generate_messages(dlq_queue_url, 3)
52
+
53
+ visit "/sqs/dlq_console"
54
+
55
+ first("#select_all").click
56
+
57
+ page.all(".bulk_check").each{|node| expect(node["checked"]).to eq true}
58
+
59
+ first("#select_all").click
60
+
61
+ page.all(".bulk_check").each{|node| expect(node["checked"]).to eq false}
62
+ end
63
+
64
+ describe "Remove" do
65
+ it "should delete single message" do
66
+ messages = generate_messages(dlq_queue_url, 2)
67
+ deleted_message_id = messages.pop.message_id
68
+ retained_message_id = messages.pop.message_id
69
+
70
+ visit "/sqs/dlq_console"
71
+
72
+ first("#message_#{deleted_message_id}").hover
73
+
74
+ within("#message_#{deleted_message_id}") do
75
+ click_on "Remove"
76
+ end
77
+
78
+ success_message = "Message ID: #{deleted_message_id} in Queue #{DLQ_QUEUE_NAME} was successfully removed."
79
+ expect(first("#alert").text).to eq success_message
80
+
81
+ expect(page.all("#message_#{deleted_message_id}").count).to eq 0
82
+ expect(page.all("#message_#{retained_message_id}").count).to eq 1
83
+
84
+ visit "/sqs/overview"
85
+
86
+ match_content(page, "#{DLQ_QUEUE_NAME} 1 0 #{source_queue_url}")
87
+ end
88
+
89
+ it "should show a confirmation popup when deleting single message" do
90
+ messages = generate_messages(dlq_queue_url, 2)
91
+ deleted_message_id = messages.pop.message_id
92
+
93
+ visit "/sqs/dlq_console"
94
+
95
+ first("#message_#{deleted_message_id}").hover
96
+
97
+ message = page.accept_confirm do
98
+ within("#message_#{deleted_message_id}") do
99
+ click_on "Remove"
100
+ end
101
+ end
102
+
103
+ expect(message).to eq('Are you sure you want to remove the message?')
104
+ end
105
+
106
+ it "should handle deleting single message that is already deleted" do
107
+ deleted_message_id = generate_messages(dlq_queue_url, 1).first.message_id
108
+
109
+ visit "/sqs/dlq_console"
110
+
111
+ sqs.purge_queue({ queue_url: dlq_queue_url })
112
+
113
+ first("#message_#{deleted_message_id}").hover
114
+
115
+ within("#message_#{deleted_message_id}") do
116
+ click_on "Remove"
117
+ end
118
+
119
+ error_message = "Message ID: #{deleted_message_id} in Queue #{DLQ_QUEUE_NAME} has already been deleted or is not visible."
120
+ expect(first("#alert").text).to eq error_message
121
+ end
122
+ end
123
+
124
+ describe "Bulk Remove" do
125
+ it "should remove multiple selected messages" do
126
+ messages = generate_messages(dlq_queue_url, 6)
127
+ deleted_message_ids = messages.pop(4).map{|c| c.message_id}
128
+ retained_message_ids = messages.pop(2).map{|c| c.message_id}
129
+
130
+ visit "/sqs/dlq_console"
131
+
132
+ deleted_message_ids.each do |message_id|
133
+ first("#batch_action_item_#{message_id}").set(true)
134
+ end
135
+
136
+ click_on "Bulk Remove"
137
+
138
+ expect(first("#alert").text).to eq "Selected messages have been removed successfully."
139
+
140
+ deleted_message_ids.each{|message_id| expect(page.all("#message_#{message_id}").count).to eq 0}
141
+ retained_message_ids.each{|message_id| expect(page.all("#message_#{message_id}").count).to eq 1}
142
+
143
+ visit "/sqs/overview"
144
+
145
+ match_content(page, "#{DLQ_QUEUE_NAME} 2 0 #{source_queue_url}")
146
+ end
147
+
148
+ it "should show a confirmation popup when removing multiple messages" do
149
+ messages = generate_messages(dlq_queue_url, 6)
150
+ deleted_message_ids = messages.pop(4).map{|c| c.message_id}
151
+
152
+ visit "/sqs/dlq_console"
153
+
154
+ deleted_message_ids.each do |message_id|
155
+ first("#batch_action_item_#{message_id}").set(true)
156
+ end
157
+
158
+ message = page.accept_confirm do
159
+ click_on "Bulk Remove"
160
+ end
161
+
162
+ expect(message).to eq('Are you sure you want to remove the selected messages?')
163
+ end
164
+
165
+ it "should handle removing multiple selected messages where one or more is already deleted or not visible" do
166
+ generate_messages(dlq_queue_url, 3)
167
+
168
+ visit "/sqs/dlq_console"
169
+
170
+ messages = receive_messages(dlq_queue_url, {count: 3}).messages
171
+ sqs.delete_message({queue_url: dlq_queue_url, receipt_handle: messages[2].receipt_handle})
172
+ sqs.change_message_visibility_batch({
173
+ queue_url: dlq_queue_url,
174
+ entries: messages.take(2).map do |message|
175
+ {id: message.message_id, receipt_handle: message.receipt_handle, visibility_timeout: 0}
176
+ end
177
+ })
178
+ messages.each do |message|
179
+ first("#batch_action_item_#{message.message_id}").set(true)
180
+ end
181
+
182
+ click_on "Bulk Remove"
183
+
184
+ expect(first("#alert").text).to eq "One or more messages may have already been removed or is not visible."
185
+
186
+ messages.each{|message| expect(page.all("#message_#{message.message_id}").count).to eq 0}
187
+
188
+ visit "/sqs/overview"
189
+
190
+ match_content(page, "#{DLQ_QUEUE_NAME} 0 0 #{source_queue_url}")
191
+ end
192
+
193
+ it "should handle clicking on Bulk Remove without any selection" do
194
+ messages = generate_messages(dlq_queue_url, 3)
195
+
196
+ visit "/sqs/dlq_console"
197
+
198
+ click_on "Bulk Remove"
199
+
200
+ expect(first("#alert").text).to eq ""
201
+
202
+ messages.each{|message| expect(page.all("#message_#{message.message_id}").count).to eq 1}
203
+ end
204
+ end
205
+
206
+ it "Move to Source Queue should be able to move a single message to source queue" do
207
+ message_id = generate_messages(dlq_queue_url, 1).first.message_id
208
+
209
+
210
+ visit "/sqs/dlq_console"
211
+
212
+ first("#message_#{message_id}").hover
213
+
214
+ within("#message_#{message_id}") do
215
+ click_on "Move to Source Queue"
216
+ end
217
+
218
+ success_message = "Message ID: #{message_id} in Queue #{DLQ_QUEUE_NAME} was successfully moved to Source Queue #{source_queue_url}."
219
+ expect(first("#alert").text).to eq success_message
220
+ expect(page.all("#message_#{message_id}").count).to eq 0
221
+
222
+ visit "/sqs/overview"
223
+
224
+ match_content(page, "#{SOURCE_QUEUE_NAME} 1 0 N/A")
225
+ match_content(page, "#{DLQ_QUEUE_NAME} 0 0 #{source_queue_url}")
226
+
227
+ moved_message = receive_messages(source_queue_url).messages.first
228
+ expect(moved_message).to_not be_nil
229
+ expect(moved_message.body).to eq "Test_0"
230
+ expect(moved_message.attributes["ApproximateReceiveCount"]).to eq "1"
231
+ expect(moved_message.message_attributes["foo_class"].to_hash).to eq({string_value: "FooWorker", data_type: "String"})
232
+ end
233
+
234
+ describe "Bulk Move to Source Queue" do
235
+ it "should move multiple selected messages" do
236
+ messages = generate_messages(dlq_queue_url, 6)
237
+ retained_message_ids = messages.pop(2).map{|c| c.message_id}
238
+ moved_message_ids = messages.pop(4).map{|c| c.message_id}
239
+
240
+ visit "/sqs/dlq_console"
241
+
242
+ moved_message_ids.each do |message_id|
243
+ first("#batch_action_item_#{message_id}").set(true)
244
+ end
245
+
246
+ click_on "Bulk Move to Source Queue"
247
+
248
+ expect(first("#alert").text).to eq "Selected messages have been requeued successfully."
249
+
250
+ moved_message_ids.each{|message_id| expect(page.all("#message_#{message_id}").count).to eq 0}
251
+ retained_message_ids.each{|message_id| expect(page.all("#message_#{message_id}").count).to eq 1}
252
+
253
+ visit "/sqs/overview"
254
+
255
+ match_content(page, "#{SOURCE_QUEUE_NAME} 4 0 N/A")
256
+ match_content(page, "#{DLQ_QUEUE_NAME} 2 0 #{source_queue_url}")
257
+
258
+ moved_messages = receive_messages(source_queue_url, {count: 4}).messages.sort_by{|c| c.body}
259
+ moved_messages.each_with_index do |moved_message, index|
260
+ expect(moved_message).to_not be_nil
261
+ expect(moved_message.body).to match "Test_#{index}"
262
+ expect(moved_message.attributes["ApproximateReceiveCount"]).to eq "1"
263
+ expect(moved_message.message_attributes["foo_class"].to_hash).to eq({string_value: "FooWorker", data_type: "String"})
264
+ end
265
+ end
266
+
267
+ it "should handle moving multiple selected messages where one or more is already deleted or not visible" do
268
+ generate_messages(dlq_queue_url, 3)
269
+
270
+ visit "/sqs/dlq_console"
271
+
272
+ messages = receive_messages(dlq_queue_url, {count: 3}).messages
273
+ sqs.delete_message({queue_url: dlq_queue_url, receipt_handle: messages[2].receipt_handle})
274
+ sqs.change_message_visibility_batch({
275
+ queue_url: dlq_queue_url,
276
+ entries: messages.take(2).map do |message|
277
+ {id: message.message_id, receipt_handle: message.receipt_handle, visibility_timeout: 0}
278
+ end
279
+ })
280
+ messages.each do |message|
281
+ first("#batch_action_item_#{message.message_id}").set(true)
282
+ end
283
+
284
+ click_on "Bulk Move to Source Queue"
285
+
286
+ expect(first("#alert").text).to eq "One or more messages may have already been requeued or is not visible."
287
+
288
+ messages.each{|message| expect(page.all("#message_#{message.message_id}").count).to eq 0}
289
+
290
+ visit "/sqs/overview"
291
+
292
+ match_content(page, "#{SOURCE_QUEUE_NAME} 2 0 N/A")
293
+ match_content(page, "#{DLQ_QUEUE_NAME} 0 0 #{source_queue_url}")
294
+ end
295
+
296
+ it "should handle clicking on Bulk Move to Source Queue without any selection" do
297
+ messages = generate_messages(dlq_queue_url, 3)
298
+
299
+ visit "/sqs/dlq_console"
300
+
301
+ click_on "Bulk Move to Source Queue"
302
+
303
+ expect(first("#alert").text).to eq ""
304
+
305
+ messages.each{|message| expect(page.all("#message_#{message.message_id}").count).to eq 1}
306
+ end
307
+ end
308
+ end
@@ -0,0 +1,36 @@
1
+ RSpec.describe "Overview Page", :sqs do
2
+ it "will show Visible Messages" do
3
+ default_messages
4
+
5
+ visit "/sqs/overview"
6
+
7
+ match_content(page, "#{SOURCE_QUEUE_NAME} 5 0 N/A")
8
+ match_content(page, "#{DLQ_QUEUE_NAME} 3 0 #{source_queue_url}")
9
+ end
10
+
11
+ it "will show In Flight Messages" do
12
+ default_messages
13
+
14
+ receive_messages(source_queue_url, {count: 3})
15
+ receive_messages(dlq_queue_url, {count: 2})
16
+
17
+ visit "/sqs/overview"
18
+
19
+ match_content(page, "#{SOURCE_QUEUE_NAME} 2 3 N/A")
20
+ match_content(page, "#{DLQ_QUEUE_NAME} 1 2 #{source_queue_url}")
21
+ end
22
+
23
+ it "should be default page" do
24
+ visit "/sqs"
25
+
26
+ expect(current_path).to eq "/sqs/overview"
27
+ end
28
+
29
+ it "should gracefully handle non existent queues" do
30
+ SqsWeb.options[:queues] = ["BOGUSQUEUE"]
31
+
32
+ visit "/sqs/overview"
33
+
34
+ match_content(page, "Aws::SQS::Errors::NonExistentQueue: BOGUSQUEUE")
35
+ end
36
+ end
data/spec/spec_helper.rb CHANGED
@@ -2,6 +2,7 @@ require "codeclimate-test-reporter"
2
2
  require "byebug"
3
3
  require 'capybara-webkit'
4
4
  require 'capybara/rspec'
5
+ require 'support/shared_context.rb'
5
6
  CodeClimate::TestReporter.start
6
7
 
7
8
  ENV['RACK_ENV'] = 'development'
@@ -13,7 +13,7 @@ SqsWeb.options[:aws][:secret_access_key] = "fake"
13
13
  SqsWeb.options[:aws][:endpoint] = $fake_sqs.uri
14
14
 
15
15
  RSpec.configure do |config|
16
- config.before(:each, :sqs) { $fake_sqs.start }
16
+ config.before(:suite) { $fake_sqs.start }
17
17
  config.before(:each, :sqs) { $fake_sqs.reset }
18
18
  config.after(:suite) { $fake_sqs.stop }
19
19
  end
@@ -3,7 +3,7 @@ require "logger"
3
3
  require "sqs_web"
4
4
 
5
5
  class RailsApp < Rails::Application
6
- config.logger = Rails.logger = Logger.new($stdout)
6
+ config.logger = Rails.logger = Logger.new("test.log")
7
7
  config.secret_token = "a3d6cee7966878577a764ed273359d9e"
8
8
 
9
9
  routes.draw do
@@ -0,0 +1,54 @@
1
+ SOURCE_QUEUE_NAME = "TestSourceQueue"
2
+
3
+ DLQ_QUEUE_NAME = "TestSourceQueueDLQ"
4
+
5
+ RSpec.shared_context "sqs_setup", :sqs do
6
+ require 'support/rails_app'
7
+ require 'support/fake_sqs'
8
+
9
+ Capybara.app = RailsApp
10
+
11
+ let(:sqs) { Aws::SQS::Client.new(region: "us-east-1", credentials: Aws::Credentials.new("fake", "fake")) }
12
+
13
+ let(:source_queue_url) { sqs.get_queue_url(queue_name: SOURCE_QUEUE_NAME).queue_url }
14
+
15
+ let(:dlq_queue_url) { sqs.get_queue_url(queue_name: DLQ_QUEUE_NAME).queue_url }
16
+
17
+ before do
18
+ sqs.config.endpoint = $fake_sqs.uri
19
+ [SOURCE_QUEUE_NAME, DLQ_QUEUE_NAME].each{|queue_name| sqs.create_queue(queue_name: queue_name)}
20
+ dlq_arn = sqs.get_queue_attributes(queue_url: dlq_queue_url).attributes.fetch("QueueArn")
21
+ #Set DLQ
22
+ sqs.set_queue_attributes(
23
+ queue_url: source_queue_url,
24
+ attributes: {
25
+ "RedrivePolicy" => "{\"deadLetterTargetArn\":\"#{dlq_arn}\",\"maxReceiveCount\":10}"
26
+ }
27
+ )
28
+ SqsWeb.options[:queues] = [SOURCE_QUEUE_NAME, DLQ_QUEUE_NAME]
29
+ end
30
+
31
+ def receive_messages(queue_url, options = {count: 1})
32
+ sqs.receive_message({
33
+ queue_url: queue_url,
34
+ attribute_names: ["All"],
35
+ message_attribute_names: ["All"],
36
+ max_number_of_messages: options[:count],
37
+ wait_time_seconds: 1,
38
+ visibility_timeout: options[:visibility_timeout]
39
+ })
40
+ end
41
+
42
+ def default_messages
43
+ generate_messages(source_queue_url, 5) + generate_messages(dlq_queue_url, 3)
44
+ end
45
+
46
+ def generate_messages(queue_url, count=1)
47
+ messages = []
48
+ count.times do |time|
49
+ messages << sqs.send_message(queue_url: queue_url, message_body: "Test_#{time}",
50
+ message_attributes: {"foo_class"=> {string_value: "FooWorker", data_type: "String"}})
51
+ end
52
+ messages
53
+ end
54
+ end
data/sqs_web.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |gem|
2
2
  gem.name = "sqs_web"
3
- gem.version = "0.0.1"
3
+ gem.version = "0.0.2"
4
4
  gem.author = "Nathaniel Ritholtz"
5
5
  gem.email = "nritholtz@gmail.com"
6
6
  gem.homepage = "https://github.com/nritholtz/sqs_web"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sqs_web
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathaniel Ritholtz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-18 00:00:00.000000000 Z
11
+ date: 2015-11-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sinatra
@@ -156,9 +156,12 @@ files:
156
156
  - lib/sqs_web/application/views/working.erb
157
157
  - lib/sqs_web/railtie.rb
158
158
  - spec/integration/app_spec.rb
159
+ - spec/integration/dlq_console_spec.rb
160
+ - spec/integration/overview_spec.rb
159
161
  - spec/spec_helper.rb
160
162
  - spec/support/fake_sqs.rb
161
163
  - spec/support/rails_app.rb
164
+ - spec/support/shared_context.rb
162
165
  - sqs_web.gemspec
163
166
  homepage: https://github.com/nritholtz/sqs_web
164
167
  licenses:
@@ -186,6 +189,9 @@ specification_version: 4
186
189
  summary: Web interface for SQS inspired by delayed_job_web
187
190
  test_files:
188
191
  - spec/integration/app_spec.rb
192
+ - spec/integration/dlq_console_spec.rb
193
+ - spec/integration/overview_spec.rb
189
194
  - spec/spec_helper.rb
190
195
  - spec/support/fake_sqs.rb
191
196
  - spec/support/rails_app.rb
197
+ - spec/support/shared_context.rb