rpush 2.3.2 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -0
  3. data/README.md +1 -1
  4. data/lib/generators/rpush_migration_generator.rb +21 -6
  5. data/lib/generators/templates/rpush.rb +5 -5
  6. data/lib/generators/templates/rpush_2_0_0_updates.rb +24 -0
  7. data/lib/rpush/client/active_model/apns/notification.rb +1 -1
  8. data/lib/rpush/client/mongoid.rb +31 -0
  9. data/lib/rpush/client/mongoid/adm/app.rb +14 -0
  10. data/lib/rpush/client/mongoid/adm/notification.rb +11 -0
  11. data/lib/rpush/client/mongoid/apns/app.rb +11 -0
  12. data/lib/rpush/client/mongoid/apns/feedback.rb +21 -0
  13. data/lib/rpush/client/mongoid/apns/notification.rb +15 -0
  14. data/lib/rpush/client/mongoid/app.rb +23 -0
  15. data/lib/rpush/client/mongoid/gcm/app.rb +11 -0
  16. data/lib/rpush/client/mongoid/gcm/notification.rb +11 -0
  17. data/lib/rpush/client/mongoid/notification.rb +43 -0
  18. data/lib/rpush/client/mongoid/wpns/app.rb +11 -0
  19. data/lib/rpush/client/mongoid/wpns/notification.rb +11 -0
  20. data/lib/rpush/client/redis.rb +2 -2
  21. data/lib/rpush/configuration.rb +48 -29
  22. data/lib/rpush/daemon/adm/delivery.rb +1 -1
  23. data/lib/rpush/daemon/apns.rb +1 -1
  24. data/lib/rpush/daemon/apns/feedback_receiver.rb +2 -3
  25. data/lib/rpush/daemon/dispatcher/apns_tcp.rb +2 -1
  26. data/lib/rpush/daemon/feeder.rb +4 -7
  27. data/lib/rpush/daemon/gcm/delivery.rb +1 -1
  28. data/lib/rpush/daemon/interruptible_sleep.rb +5 -50
  29. data/lib/rpush/daemon/proc_title.rb +2 -1
  30. data/lib/rpush/daemon/store/active_record.rb +4 -0
  31. data/lib/rpush/daemon/store/interface.rb +1 -1
  32. data/lib/rpush/daemon/store/mongoid.rb +157 -0
  33. data/lib/rpush/daemon/store/redis.rb +6 -2
  34. data/lib/rpush/deprecatable.rb +1 -2
  35. data/lib/rpush/deprecation.rb +6 -0
  36. data/lib/rpush/embed.rb +5 -0
  37. data/lib/rpush/logger.rb +5 -8
  38. data/lib/rpush/push.rb +5 -0
  39. data/lib/rpush/version.rb +1 -1
  40. data/lib/tasks/quality.rake +1 -1
  41. data/lib/tasks/test.rake +9 -4
  42. data/spec/functional/apns_spec.rb +2 -1
  43. data/spec/functional_spec_helper.rb +2 -2
  44. data/spec/spec_helper.rb +18 -7
  45. data/spec/support/config/mongoid.yml +69 -0
  46. data/spec/support/mongoid_setup.rb +10 -0
  47. data/spec/unit/client/active_record/adm/app_spec.rb +1 -1
  48. data/spec/unit/client/active_record/adm/notification_spec.rb +1 -1
  49. data/spec/unit/client/active_record/apns/app_spec.rb +1 -1
  50. data/spec/unit/client/active_record/apns/feedback_spec.rb +1 -1
  51. data/spec/unit/client/active_record/apns/notification_spec.rb +11 -11
  52. data/spec/unit/client/active_record/app_spec.rb +1 -1
  53. data/spec/unit/client/active_record/gcm/notification_spec.rb +1 -1
  54. data/spec/unit/client/active_record/notification_spec.rb +1 -1
  55. data/spec/unit/client/active_record/wpns/notification_spec.rb +1 -1
  56. data/spec/unit/configuration_spec.rb +7 -0
  57. data/spec/unit/daemon/apns/feedback_receiver_spec.rb +5 -5
  58. data/spec/unit/daemon/feeder_spec.rb +2 -2
  59. data/spec/unit/daemon/proc_title_spec.rb +11 -0
  60. data/spec/unit/daemon/store/active_record/reconnectable_spec.rb +1 -1
  61. data/spec/unit/daemon/store/active_record_spec.rb +21 -12
  62. data/spec/unit/daemon/store/mongoid_spec.rb +339 -0
  63. data/spec/unit/daemon/store/redis_spec.rb +365 -0
  64. data/spec/unit/embed_spec.rb +4 -2
  65. data/spec/unit/logger_spec.rb +14 -5
  66. data/spec/unit/notification_shared.rb +1 -1
  67. data/spec/unit/push_spec.rb +4 -2
  68. data/spec/unit_spec_helper.rb +3 -3
  69. metadata +25 -2
@@ -132,4 +132,4 @@ describe Rpush::Daemon::Store::ActiveRecord::Reconnectable do
132
132
  end
133
133
  end
134
134
  end
135
- end
135
+ end if active_record?
@@ -13,16 +13,34 @@ describe Rpush::Daemon::Store::ActiveRecord do
13
13
  allow(Time).to receive_messages(now: time)
14
14
  end
15
15
 
16
- it 'can update a notification' do
16
+ it 'updates an notification' do
17
17
  expect(notification).to receive(:save!)
18
18
  store.update_notification(notification)
19
19
  end
20
20
 
21
- it 'can update a app' do
21
+ it 'updates an app' do
22
22
  expect(app).to receive(:save!)
23
23
  store.update_app(app)
24
24
  end
25
25
 
26
+ it 'finds an app by ID' do
27
+ expect(store.app(app.id)).to eq(app)
28
+ end
29
+
30
+ it 'finds all apps' do
31
+ app
32
+ expect(store.all_apps).to eq([app])
33
+ end
34
+
35
+ it 'translates an Integer notification ID' do
36
+ expect(store.translate_integer_notification_id(notification.id)).to eq(notification.id)
37
+ end
38
+
39
+ it 'returns the pending notification count' do
40
+ notification
41
+ expect(store.pending_delivery_count).to eq(1)
42
+ end
43
+
26
44
  it 'can release a connection' do
27
45
  expect(ActiveRecord::Base.connection).to receive(:close)
28
46
  store.release_connection
@@ -43,7 +61,6 @@ describe Rpush::Daemon::Store::ActiveRecord do
43
61
 
44
62
  it 'loads notifications in batches' do
45
63
  Rpush.config.batch_size = 5000
46
- Rpush.config.push = false
47
64
  relation = double.as_null_object
48
65
  expect(relation).to receive(:limit).with(5000)
49
66
  allow(relation).to receive_messages(to_a: [])
@@ -51,14 +68,6 @@ describe Rpush::Daemon::Store::ActiveRecord do
51
68
  store.deliverable_notifications(Rpush.config.batch_size)
52
69
  end
53
70
 
54
- it 'does not load notification in batches if in push mode' do
55
- Rpush.config.push = true
56
- relation = double.as_null_object
57
- expect(relation).not_to receive(:limit)
58
- allow(Rpush::Notification).to receive_messages(ready_for_delivery: relation)
59
- store.deliverable_notifications(Rpush.config.batch_size)
60
- end
61
-
62
71
  it 'loads an undelivered notification without deliver_after set' do
63
72
  notification.update_attributes!(delivered: false, deliver_after: nil)
64
73
  expect(store.deliverable_notifications(Rpush.config.batch_size)).to eq [notification]
@@ -345,4 +354,4 @@ describe Rpush::Daemon::Store::ActiveRecord do
345
354
  expect(new_notification.new_record?).to be_falsey
346
355
  end
347
356
  end
348
- end
357
+ end if active_record?
@@ -0,0 +1,339 @@
1
+ require 'unit_spec_helper'
2
+ require 'rpush/daemon/store/mongoid'
3
+
4
+ describe Rpush::Daemon::Store::Mongoid do
5
+ let(:app) { Rpush::Client::Mongoid::Apns::App.create!(name: 'my_app', environment: 'development', certificate: TEST_CERT) }
6
+ let(:notification) { Rpush::Client::Mongoid::Apns::Notification.create!(device_token: "a" * 64, app: app) }
7
+ let(:store) { Rpush::Daemon::Store::Mongoid.new }
8
+ let(:time) { Time.now.utc }
9
+ let(:logger) { double(Rpush::Logger, error: nil, internal_logger: nil) }
10
+
11
+ before do
12
+ allow(Rpush).to receive_messages(logger: logger)
13
+ allow(Time).to receive_messages(now: time)
14
+ end
15
+
16
+ it 'updates an notification' do
17
+ expect(notification).to receive(:save!)
18
+ store.update_notification(notification)
19
+ end
20
+
21
+ it 'updates an app' do
22
+ expect(app).to receive(:save!)
23
+ store.update_app(app)
24
+ end
25
+
26
+ it 'finds an app by ID' do
27
+ expect(store.app(app.id)).to eq(app)
28
+ end
29
+
30
+ it 'finds all apps' do
31
+ expect(store.all_apps).to eq([app])
32
+ end
33
+
34
+ it 'translates an Integer notification ID' do
35
+ expect(store.translate_integer_notification_id(notification.integer_id)).to eq(notification.id)
36
+ end
37
+
38
+ it 'returns the pending notification count' do
39
+ notification
40
+ expect(store.pending_delivery_count).to eq(1)
41
+ end
42
+
43
+ describe 'deliverable_notifications' do
44
+ it 'loads notifications in batches' do
45
+ Rpush.config.batch_size = 5000
46
+ relation = double.as_null_object
47
+ expect(relation).to receive(:limit).with(5000)
48
+ allow(relation).to receive_messages(to_a: [])
49
+ allow(store).to receive_messages(ready_for_delivery: relation)
50
+ store.deliverable_notifications(Rpush.config.batch_size)
51
+ end
52
+
53
+ it 'loads an undelivered notification without deliver_after set' do
54
+ notification.update_attributes!(delivered: false, deliver_after: nil)
55
+ expect(store.deliverable_notifications(Rpush.config.batch_size)).to eq [notification]
56
+ end
57
+
58
+ it 'loads an notification with a deliver_after time in the past' do
59
+ notification.update_attributes!(delivered: false, deliver_after: 1.hour.ago)
60
+ expect(store.deliverable_notifications(Rpush.config.batch_size)).to eq [notification]
61
+ end
62
+
63
+ it 'does not load an notification with a deliver_after time in the future' do
64
+ notification.update_attributes!(delivered: false, deliver_after: 1.hour.from_now)
65
+ expect(store.deliverable_notifications(Rpush.config.batch_size)).to be_empty
66
+ end
67
+
68
+ it 'does not load a previously delivered notification' do
69
+ notification.update_attributes!(delivered: true, delivered_at: time)
70
+ expect(store.deliverable_notifications(Rpush.config.batch_size)).to be_empty
71
+ end
72
+
73
+ it "does not enqueue a notification that has previously failed delivery" do
74
+ notification.update_attributes!(delivered: false, failed: true)
75
+ expect(store.deliverable_notifications(Rpush.config.batch_size)).to be_empty
76
+ end
77
+ end
78
+
79
+ describe 'mark_retryable' do
80
+ it 'increments the retry count' do
81
+ expect do
82
+ store.mark_retryable(notification, time)
83
+ end.to change(notification, :retries).by(1)
84
+ end
85
+
86
+ it 'sets the deliver after timestamp' do
87
+ deliver_after = time + 10.seconds
88
+ expect do
89
+ store.mark_retryable(notification, deliver_after)
90
+ end.to change(notification, :deliver_after).to(deliver_after)
91
+ end
92
+
93
+ it 'saves the notification without validation' do
94
+ expect(notification).to receive(:save!).with(validate: false)
95
+ store.mark_retryable(notification, time)
96
+ end
97
+
98
+ it 'does not save the notification if persist: false' do
99
+ expect(notification).not_to receive(:save!)
100
+ store.mark_retryable(notification, time, persist: false)
101
+ end
102
+ end
103
+
104
+ describe 'mark_batch_retryable' do
105
+ let(:deliver_after) { time + 10.seconds }
106
+
107
+ it 'sets the attributes on the object for use in reflections' do
108
+ store.mark_batch_retryable([notification], deliver_after)
109
+ expect(notification.deliver_after).to eq deliver_after
110
+ expect(notification.retries).to eq 1
111
+ end
112
+
113
+ it 'increments the retired count' do
114
+ expect do
115
+ store.mark_batch_retryable([notification], deliver_after)
116
+ notification.reload
117
+ end.to change(notification, :retries).by(1)
118
+ end
119
+
120
+ it 'sets the deliver after timestamp' do
121
+ expect do
122
+ store.mark_batch_retryable([notification], deliver_after)
123
+ notification.reload
124
+ end.to change { notification.deliver_after.try(:utc).to_s }.to(deliver_after.utc.to_s)
125
+ end
126
+ end
127
+
128
+ describe 'mark_delivered' do
129
+ it 'marks the notification as delivered' do
130
+ expect do
131
+ store.mark_delivered(notification, time)
132
+ end.to change(notification, :delivered).to(true)
133
+ end
134
+
135
+ it 'sets the time the notification was delivered' do
136
+ expect do
137
+ store.mark_delivered(notification, time)
138
+ notification.reload
139
+ end.to change { notification.delivered_at.try(:utc).to_s }.to(time.to_s)
140
+ end
141
+
142
+ it 'saves the notification without validation' do
143
+ expect(notification).to receive(:save!).with(validate: false)
144
+ store.mark_delivered(notification, time)
145
+ end
146
+
147
+ it 'does not save the notification if persist: false' do
148
+ expect(notification).not_to receive(:save!)
149
+ store.mark_delivered(notification, time, persist: false)
150
+ end
151
+ end
152
+
153
+ describe 'mark_batch_delivered' do
154
+ it 'sets the attributes on the object for use in reflections' do
155
+ store.mark_batch_delivered([notification])
156
+ expect(notification.delivered_at).to eq time
157
+ expect(notification.delivered).to be_truthy
158
+ end
159
+
160
+ it 'marks the notifications as delivered' do
161
+ expect do
162
+ store.mark_batch_delivered([notification])
163
+ notification.reload
164
+ end.to change(notification, :delivered).to(true)
165
+ end
166
+
167
+ it 'sets the time the notifications were delivered' do
168
+ expect do
169
+ store.mark_batch_delivered([notification])
170
+ notification.reload
171
+ end.to change { notification.delivered_at.try(:utc).to_s }.to(time.to_s)
172
+ end
173
+ end
174
+
175
+ describe 'mark_failed' do
176
+ it 'marks the notification as not delivered' do
177
+ store.mark_failed(notification, nil, '', time)
178
+ expect(notification.delivered).to eq(false)
179
+ end
180
+
181
+ it 'marks the notification as failed' do
182
+ expect do
183
+ store.mark_failed(notification, nil, '', time)
184
+ notification.reload
185
+ end.to change(notification, :failed).to(true)
186
+ end
187
+
188
+ it 'sets the time the notification delivery failed' do
189
+ expect do
190
+ store.mark_failed(notification, nil, '', time)
191
+ notification.reload
192
+ end.to change { notification.failed_at.try(:utc).to_s }.to(time.to_s)
193
+ end
194
+
195
+ it 'sets the error code' do
196
+ expect do
197
+ store.mark_failed(notification, 42, '', time)
198
+ end.to change(notification, :error_code).to(42)
199
+ end
200
+
201
+ it 'sets the error description' do
202
+ expect do
203
+ store.mark_failed(notification, 42, 'Weeee', time)
204
+ end.to change(notification, :error_description).to('Weeee')
205
+ end
206
+
207
+ it 'saves the notification without validation' do
208
+ expect(notification).to receive(:save!).with(validate: false)
209
+ store.mark_failed(notification, nil, '', time)
210
+ end
211
+
212
+ it 'does not save the notification if persist: false' do
213
+ expect(notification).not_to receive(:save!)
214
+ store.mark_failed(notification, nil, '', time, persist: false)
215
+ end
216
+ end
217
+
218
+ describe 'mark_batch_failed' do
219
+ it 'sets the attributes on the object for use in reflections' do
220
+ store.mark_batch_failed([notification], 123, 'an error')
221
+ expect(notification.failed_at).to eq time
222
+ expect(notification.delivered_at).to be_nil
223
+ expect(notification.delivered).to eq(false)
224
+ expect(notification.failed).to be_truthy
225
+ expect(notification.error_code).to eq 123
226
+ expect(notification.error_description).to eq 'an error'
227
+ end
228
+
229
+ it 'marks the notification as not delivered' do
230
+ store.mark_batch_failed([notification], nil, '')
231
+ notification.reload
232
+ expect(notification.delivered).to be_falsey
233
+ end
234
+
235
+ it 'marks the notification as failed' do
236
+ expect do
237
+ store.mark_batch_failed([notification], nil, '')
238
+ notification.reload
239
+ end.to change(notification, :failed).to(true)
240
+ end
241
+
242
+ it 'sets the time the notification delivery failed' do
243
+ expect do
244
+ store.mark_batch_failed([notification], nil, '')
245
+ notification.reload
246
+ end.to change { notification.failed_at.try(:utc).to_s }.to(time.to_s)
247
+ end
248
+
249
+ it 'sets the error code' do
250
+ expect do
251
+ store.mark_batch_failed([notification], 42, '')
252
+ notification.reload
253
+ end.to change(notification, :error_code).to(42)
254
+ end
255
+
256
+ it 'sets the error description' do
257
+ expect do
258
+ store.mark_batch_failed([notification], 42, 'Weeee')
259
+ notification.reload
260
+ end.to change(notification, :error_description).to('Weeee')
261
+ end
262
+ end
263
+
264
+ describe 'create_apns_feedback' do
265
+ it 'creates the Feedback record' do
266
+ expect(Rpush::Client::Mongoid::Apns::Feedback).to receive(:create!).with(
267
+ failed_at: time, device_token: 'ab' * 32, app: app)
268
+ store.create_apns_feedback(time, 'ab' * 32, app)
269
+ end
270
+ end
271
+
272
+ describe 'create_gcm_notification' do
273
+ let(:data) { { data: true } }
274
+ let(:attributes) { { device_token: 'ab' * 32 } }
275
+ let(:registration_ids) { %w(123 456) }
276
+ let(:deliver_after) { time + 10.seconds }
277
+ let(:args) { [attributes, data, registration_ids, deliver_after, app] }
278
+
279
+ it 'sets the given attributes' do
280
+ new_notification = store.create_gcm_notification(*args)
281
+ expect(new_notification.device_token).to eq 'ab' * 32
282
+ end
283
+
284
+ it 'sets the given data' do
285
+ new_notification = store.create_gcm_notification(*args)
286
+ expect(new_notification.data).to eq(data: true)
287
+ end
288
+
289
+ it 'sets the given registration IDs' do
290
+ new_notification = store.create_gcm_notification(*args)
291
+ expect(new_notification.registration_ids).to eq registration_ids
292
+ end
293
+
294
+ it 'sets the deliver_after timestamp' do
295
+ new_notification = store.create_gcm_notification(*args)
296
+ expect(new_notification.deliver_after.utc.to_s).to eq deliver_after.to_s
297
+ end
298
+
299
+ it 'saves the new notification' do
300
+ new_notification = store.create_gcm_notification(*args)
301
+ expect(new_notification.new_record?).to be_falsey
302
+ end
303
+ end
304
+
305
+ describe 'create_adm_notification' do
306
+ let(:data) { { data: true } }
307
+ let(:attributes) { { app_id: app.id, collapse_key: 'ckey', delay_while_idle: true } }
308
+ let(:registration_ids) { %w(123 456) }
309
+ let(:deliver_after) { time + 10.seconds }
310
+ let(:args) { [attributes, data, registration_ids, deliver_after, app] }
311
+
312
+ it 'sets the given attributes' do
313
+ new_notification = store.create_adm_notification(*args)
314
+ expect(new_notification.app_id).to eq app.id
315
+ expect(new_notification.collapse_key).to eq 'ckey'
316
+ expect(new_notification.delay_while_idle).to be_truthy
317
+ end
318
+
319
+ it 'sets the given data' do
320
+ new_notification = store.create_adm_notification(*args)
321
+ expect(new_notification.data).to eq(data: true)
322
+ end
323
+
324
+ it 'sets the given registration IDs' do
325
+ new_notification = store.create_adm_notification(*args)
326
+ expect(new_notification.registration_ids).to eq registration_ids
327
+ end
328
+
329
+ it 'sets the deliver_after timestamp' do
330
+ new_notification = store.create_adm_notification(*args)
331
+ expect(new_notification.deliver_after.utc.to_s).to eq deliver_after.to_s
332
+ end
333
+
334
+ it 'saves the new notification' do
335
+ new_notification = store.create_adm_notification(*args)
336
+ expect(new_notification.new_record?).to be_falsey
337
+ end
338
+ end
339
+ end if mongoid?
@@ -0,0 +1,365 @@
1
+ require 'unit_spec_helper'
2
+ require 'rpush/daemon/store/redis'
3
+
4
+ describe Rpush::Daemon::Store::Redis do
5
+ let(:app) { Rpush::Client::Redis::Apns::App.create!(name: 'my_app', environment: 'development', certificate: TEST_CERT) }
6
+ let(:notification) { Rpush::Client::Redis::Apns::Notification.create!(device_token: "a" * 64, app: app) }
7
+ let(:store) { Rpush::Daemon::Store::Redis.new }
8
+ let(:time) { Time.now.utc }
9
+ let(:logger) { double(Rpush::Logger, error: nil, internal_logger: nil) }
10
+
11
+ before do
12
+ allow(Rpush).to receive_messages(logger: logger)
13
+ allow(Time).to receive_messages(now: time)
14
+ end
15
+
16
+ it 'updates an notification' do
17
+ expect(notification).to receive(:save!)
18
+ store.update_notification(notification)
19
+ end
20
+
21
+ it 'updates an app' do
22
+ expect(app).to receive(:save!)
23
+ store.update_app(app)
24
+ end
25
+
26
+ it 'finds an app by ID' do
27
+ app
28
+ expect(store.app(app.id)).to eq(app)
29
+ end
30
+
31
+ it 'finds all apps' do
32
+ app
33
+ expect(store.all_apps).to eq([app])
34
+ end
35
+
36
+ it 'translates an Integer notification ID' do
37
+ expect(store.translate_integer_notification_id(notification.id)).to eq(notification.id)
38
+ end
39
+
40
+ it 'returns the pending notification count' do
41
+ notification
42
+ expect(store.pending_delivery_count).to eq(1)
43
+ end
44
+
45
+ describe 'deliverable_notifications' do
46
+ it 'loads notifications in batches' do
47
+ Rpush.config.batch_size = 100
48
+ allow(store).to receive_messages(pending_notification_ids: [1, 2, 3, 4])
49
+ expect(Rpush::Client::Redis::Notification).to receive(:find).exactly(4).times
50
+ store.deliverable_notifications(Rpush.config.batch_size)
51
+ end
52
+
53
+ it 'loads an undelivered notification without deliver_after set' do
54
+ notification.update_attributes!(delivered: false, deliver_after: nil)
55
+ expect(store.deliverable_notifications(Rpush.config.batch_size)).to eq [notification]
56
+ end
57
+
58
+ it 'loads an notification with a deliver_after time in the past' do
59
+ notification.update_attributes!(delivered: false, deliver_after: 1.hour.ago)
60
+ expect(store.deliverable_notifications(Rpush.config.batch_size)).to eq [notification]
61
+ end
62
+
63
+ it 'does not load an notification with a deliver_after time in the future' do
64
+ notification
65
+ notification = store.deliverable_notifications(Rpush.config.batch_size).first
66
+ store.mark_retryable(notification, 1.hour.from_now)
67
+ expect(store.deliverable_notifications(Rpush.config.batch_size)).to be_empty
68
+ end
69
+
70
+ it 'does not load a previously delivered notification' do
71
+ notification
72
+ notification = store.deliverable_notifications(Rpush.config.batch_size).first
73
+ store.mark_delivered(notification, Time.now)
74
+ expect(store.deliverable_notifications(Rpush.config.batch_size)).to be_empty
75
+ end
76
+
77
+ it "does not enqueue a notification that has previously failed delivery" do
78
+ notification
79
+ notification = store.deliverable_notifications(Rpush.config.batch_size).first
80
+ store.mark_failed(notification, 0, "failed", Time.now)
81
+ expect(store.deliverable_notifications(Rpush.config.batch_size)).to be_empty
82
+ end
83
+ end
84
+
85
+ describe 'mark_retryable' do
86
+ it 'increments the retry count' do
87
+ expect do
88
+ store.mark_retryable(notification, time)
89
+ end.to change(notification, :retries).by(1)
90
+ end
91
+
92
+ it 'sets the deliver after timestamp' do
93
+ deliver_after = time + 10.seconds
94
+ expect do
95
+ store.mark_retryable(notification, deliver_after)
96
+ end.to change(notification, :deliver_after).to(deliver_after)
97
+ end
98
+
99
+ it 'saves the notification without validation' do
100
+ expect(notification).to receive(:save!).with(validate: false)
101
+ store.mark_retryable(notification, time)
102
+ end
103
+
104
+ it 'does not save the notification if persist: false' do
105
+ expect(notification).not_to receive(:save!)
106
+ store.mark_retryable(notification, time, persist: false)
107
+ end
108
+ end
109
+
110
+ describe 'mark_ids_retryable' do
111
+ let(:deliver_after) { time + 10.seconds }
112
+
113
+ it 'sets the deliver after timestamp' do
114
+ expect do
115
+ store.mark_ids_retryable([notification.id], deliver_after)
116
+ notification.reload
117
+ end.to change { notification.deliver_after.try(:utc).to_s }.to(deliver_after.utc.to_s)
118
+ end
119
+ end
120
+
121
+ describe 'mark_batch_retryable' do
122
+ let(:deliver_after) { time + 10.seconds }
123
+
124
+ it 'sets the attributes on the object for use in reflections' do
125
+ store.mark_batch_retryable([notification], deliver_after)
126
+ expect(notification.deliver_after).to eq deliver_after
127
+ expect(notification.retries).to eq 1
128
+ end
129
+
130
+ it 'increments the retired count' do
131
+ expect do
132
+ store.mark_batch_retryable([notification], deliver_after)
133
+ notification.reload
134
+ end.to change(notification, :retries).by(1)
135
+ end
136
+
137
+ it 'sets the deliver after timestamp' do
138
+ expect do
139
+ store.mark_batch_retryable([notification], deliver_after)
140
+ notification.reload
141
+ end.to change { notification.deliver_after.try(:utc).to_s }.to(deliver_after.utc.to_s)
142
+ end
143
+ end
144
+
145
+ describe 'mark_delivered' do
146
+ it 'marks the notification as delivered' do
147
+ expect do
148
+ store.mark_delivered(notification, time)
149
+ end.to change(notification, :delivered).to(true)
150
+ end
151
+
152
+ it 'sets the time the notification was delivered' do
153
+ expect do
154
+ store.mark_delivered(notification, time)
155
+ notification.reload
156
+ end.to change { notification.delivered_at.try(:utc).to_s }.to(time.to_s)
157
+ end
158
+
159
+ it 'saves the notification without validation' do
160
+ expect(notification).to receive(:save!).with(validate: false)
161
+ store.mark_delivered(notification, time)
162
+ end
163
+
164
+ it 'does not save the notification if persist: false' do
165
+ expect(notification).not_to receive(:save!)
166
+ store.mark_delivered(notification, time, persist: false)
167
+ end
168
+ end
169
+
170
+ describe 'mark_batch_delivered' do
171
+ it 'sets the attributes on the object for use in reflections' do
172
+ store.mark_batch_delivered([notification])
173
+ expect(notification.delivered_at).to eq time
174
+ expect(notification.delivered).to be_truthy
175
+ end
176
+
177
+ it 'marks the notifications as delivered' do
178
+ expect do
179
+ store.mark_batch_delivered([notification])
180
+ notification.reload
181
+ end.to change(notification, :delivered).to(true)
182
+ end
183
+
184
+ it 'sets the time the notifications were delivered' do
185
+ expect do
186
+ store.mark_batch_delivered([notification])
187
+ notification.reload
188
+ end.to change { notification.delivered_at.try(:utc).to_s }.to(time.to_s)
189
+ end
190
+ end
191
+
192
+ describe 'mark_failed' do
193
+ it 'marks the notification as not delivered' do
194
+ store.mark_failed(notification, nil, '', time)
195
+ expect(notification.delivered).to eq(false)
196
+ end
197
+
198
+ it 'marks the notification as failed' do
199
+ expect do
200
+ store.mark_failed(notification, nil, '', time)
201
+ notification.reload
202
+ end.to change(notification, :failed).to(true)
203
+ end
204
+
205
+ it 'sets the time the notification delivery failed' do
206
+ expect do
207
+ store.mark_failed(notification, nil, '', time)
208
+ notification.reload
209
+ end.to change { notification.failed_at.try(:utc).to_s }.to(time.to_s)
210
+ end
211
+
212
+ it 'sets the error code' do
213
+ expect do
214
+ store.mark_failed(notification, 42, '', time)
215
+ end.to change(notification, :error_code).to(42)
216
+ end
217
+
218
+ it 'sets the error description' do
219
+ expect do
220
+ store.mark_failed(notification, 42, 'Weeee', time)
221
+ end.to change(notification, :error_description).to('Weeee')
222
+ end
223
+
224
+ it 'saves the notification without validation' do
225
+ expect(notification).to receive(:save!).with(validate: false)
226
+ store.mark_failed(notification, nil, '', time)
227
+ end
228
+
229
+ it 'does not save the notification if persist: false' do
230
+ expect(notification).not_to receive(:save!)
231
+ store.mark_failed(notification, nil, '', time, persist: false)
232
+ end
233
+ end
234
+
235
+ describe 'mark_ids_failed' do
236
+ it 'marks the notification as failed' do
237
+ expect do
238
+ store.mark_ids_failed([notification.id], nil, '', Time.now)
239
+ notification.reload
240
+ end.to change(notification, :failed).to(true)
241
+ end
242
+ end
243
+
244
+ describe 'mark_batch_failed' do
245
+ it 'sets the attributes on the object for use in reflections' do
246
+ store.mark_batch_failed([notification], 123, 'an error')
247
+ expect(notification.failed_at).to eq time
248
+ expect(notification.delivered_at).to be_nil
249
+ expect(notification.delivered).to eq(false)
250
+ expect(notification.failed).to be_truthy
251
+ expect(notification.error_code).to eq 123
252
+ expect(notification.error_description).to eq 'an error'
253
+ end
254
+
255
+ it 'marks the notification as not delivered' do
256
+ store.mark_batch_failed([notification], nil, '')
257
+ notification.reload
258
+ expect(notification.delivered).to be_falsey
259
+ end
260
+
261
+ it 'marks the notification as failed' do
262
+ expect do
263
+ store.mark_batch_failed([notification], nil, '')
264
+ notification.reload
265
+ end.to change(notification, :failed).to(true)
266
+ end
267
+
268
+ it 'sets the time the notification delivery failed' do
269
+ expect do
270
+ store.mark_batch_failed([notification], nil, '')
271
+ notification.reload
272
+ end.to change { notification.failed_at.try(:utc).to_s }.to(time.to_s)
273
+ end
274
+
275
+ it 'sets the error code' do
276
+ expect do
277
+ store.mark_batch_failed([notification], 42, '')
278
+ notification.reload
279
+ end.to change(notification, :error_code).to(42)
280
+ end
281
+
282
+ it 'sets the error description' do
283
+ expect do
284
+ store.mark_batch_failed([notification], 42, 'Weeee')
285
+ notification.reload
286
+ end.to change(notification, :error_description).to('Weeee')
287
+ end
288
+ end
289
+
290
+ describe 'create_apns_feedback' do
291
+ it 'creates the Feedback record' do
292
+ expect(Rpush::Client::Redis::Apns::Feedback).to receive(:create!).with(
293
+ failed_at: time, device_token: 'ab' * 32, app_id: app.id)
294
+ store.create_apns_feedback(time, 'ab' * 32, app)
295
+ end
296
+ end
297
+
298
+ describe 'create_gcm_notification' do
299
+ let(:data) { { data: true } }
300
+ let(:attributes) { { device_token: 'ab' * 32 } }
301
+ let(:registration_ids) { %w(123 456) }
302
+ let(:deliver_after) { time + 10.seconds }
303
+ let(:args) { [attributes, data, registration_ids, deliver_after, app] }
304
+
305
+ it 'sets the given attributes' do
306
+ new_notification = store.create_gcm_notification(*args)
307
+ expect(new_notification.device_token).to eq 'ab' * 32
308
+ end
309
+
310
+ it 'sets the given data' do
311
+ new_notification = store.create_gcm_notification(*args)
312
+ expect(new_notification.data).to eq(data: true)
313
+ end
314
+
315
+ it 'sets the given registration IDs' do
316
+ new_notification = store.create_gcm_notification(*args)
317
+ expect(new_notification.registration_ids).to eq registration_ids
318
+ end
319
+
320
+ it 'sets the deliver_after timestamp' do
321
+ new_notification = store.create_gcm_notification(*args)
322
+ expect(new_notification.deliver_after.utc.to_s).to eq deliver_after.to_s
323
+ end
324
+
325
+ it 'saves the new notification' do
326
+ new_notification = store.create_gcm_notification(*args)
327
+ expect(new_notification.new_record?).to be_falsey
328
+ end
329
+ end
330
+
331
+ describe 'create_adm_notification' do
332
+ let(:data) { { data: true } }
333
+ let(:attributes) { { app_id: app.id, collapse_key: 'ckey', delay_while_idle: true } }
334
+ let(:registration_ids) { %w(123 456) }
335
+ let(:deliver_after) { time + 10.seconds }
336
+ let(:args) { [attributes, data, registration_ids, deliver_after, app] }
337
+
338
+ it 'sets the given attributes' do
339
+ new_notification = store.create_adm_notification(*args)
340
+ expect(new_notification.app_id).to eq app.id
341
+ expect(new_notification.collapse_key).to eq 'ckey'
342
+ expect(new_notification.delay_while_idle).to be_truthy
343
+ end
344
+
345
+ it 'sets the given data' do
346
+ new_notification = store.create_adm_notification(*args)
347
+ expect(new_notification.data).to eq(data: true)
348
+ end
349
+
350
+ it 'sets the given registration IDs' do
351
+ new_notification = store.create_adm_notification(*args)
352
+ expect(new_notification.registration_ids).to eq registration_ids
353
+ end
354
+
355
+ it 'sets the deliver_after timestamp' do
356
+ new_notification = store.create_adm_notification(*args)
357
+ expect(new_notification.deliver_after.utc.to_s).to eq deliver_after.to_s
358
+ end
359
+
360
+ it 'saves the new notification' do
361
+ new_notification = store.create_adm_notification(*args)
362
+ expect(new_notification.new_record?).to be_falsey
363
+ end
364
+ end
365
+ end if redis?