rpush 2.3.2 → 2.4.0

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 (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?