rpush 4.2.0 → 5.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +248 -163
- data/README.md +103 -17
- data/lib/generators/templates/add_gcm.rb +4 -4
- data/lib/generators/templates/add_rpush.rb +4 -4
- data/lib/generators/templates/rpush.rb +4 -0
- data/lib/generators/templates/rpush_3_3_1_updates.rb +2 -2
- data/lib/rpush/cli.rb +1 -1
- data/lib/rpush/client/active_model.rb +4 -1
- data/lib/rpush/client/active_model/adm/data_validator.rb +1 -1
- data/lib/rpush/client/active_model/apns/device_token_format_validator.rb +2 -2
- data/lib/rpush/client/active_model/apns/notification.rb +9 -1
- data/lib/rpush/client/active_model/apns/notification_payload_size_validator.rb +15 -0
- data/lib/rpush/client/active_model/apns2/notification.rb +14 -0
- data/lib/rpush/client/active_model/gcm/expiry_collapse_key_mutual_inclusion_validator.rb +1 -1
- data/lib/rpush/client/active_model/gcm/notification.rb +2 -2
- data/lib/rpush/client/active_model/payload_data_size_validator.rb +1 -1
- data/lib/rpush/client/active_model/registration_ids_count_validator.rb +1 -1
- data/lib/rpush/client/active_model/webpush/app.rb +41 -0
- data/lib/rpush/client/active_model/webpush/notification.rb +66 -0
- data/lib/rpush/client/active_record.rb +4 -0
- data/lib/rpush/client/active_record/apns/active_record_serializable_notification.rb +65 -0
- data/lib/rpush/client/active_record/apns/notification.rb +1 -57
- data/lib/rpush/client/active_record/apns2/notification.rb +4 -1
- data/lib/rpush/client/active_record/apnsp8/notification.rb +1 -0
- data/lib/rpush/client/active_record/webpush/app.rb +11 -0
- data/lib/rpush/client/active_record/webpush/notification.rb +12 -0
- data/lib/rpush/client/redis.rb +3 -0
- data/lib/rpush/client/redis/apns2/notification.rb +1 -0
- data/lib/rpush/client/redis/apnsp8/notification.rb +2 -0
- data/lib/rpush/client/redis/pushy/notification.rb +0 -1
- data/lib/rpush/client/redis/webpush/app.rb +15 -0
- data/lib/rpush/client/redis/webpush/notification.rb +15 -0
- data/lib/rpush/configuration.rb +3 -2
- data/lib/rpush/daemon.rb +4 -1
- data/lib/rpush/daemon/apns/feedback_receiver.rb +1 -1
- data/lib/rpush/daemon/apns2/delivery.rb +13 -2
- data/lib/rpush/daemon/apnsp8/delivery.rb +7 -2
- data/lib/rpush/daemon/app_runner.rb +1 -1
- data/lib/rpush/daemon/batch.rb +12 -5
- data/lib/rpush/daemon/delivery.rb +1 -2
- data/lib/rpush/daemon/store/active_record/reconnectable.rb +1 -1
- data/lib/rpush/daemon/webpush.rb +10 -0
- data/lib/rpush/daemon/webpush/delivery.rb +114 -0
- data/lib/rpush/logger.rb +1 -0
- data/lib/rpush/version.rb +2 -2
- data/spec/functional/apns2_spec.rb +97 -2
- data/spec/functional/gcm_priority_spec.rb +40 -0
- data/spec/functional/webpush_spec.rb +30 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/support/simplecov_helper.rb +1 -1
- data/spec/unit/client/active_record/adm/app_spec.rb +2 -54
- data/spec/unit/client/active_record/adm/notification_spec.rb +2 -39
- data/spec/unit/client/active_record/apns/app_spec.rb +3 -26
- data/spec/unit/client/active_record/apns/feedback_spec.rb +1 -5
- data/spec/unit/client/active_record/apns/notification_spec.rb +29 -293
- data/spec/unit/client/active_record/apns2/app_spec.rb +4 -0
- data/spec/unit/client/active_record/apns2/notification_spec.rb +65 -0
- data/spec/unit/client/active_record/apnsp8/notification_spec.rb +28 -0
- data/spec/unit/client/active_record/app_spec.rb +1 -26
- data/spec/unit/client/active_record/gcm/app_spec.rb +3 -1
- data/spec/unit/client/active_record/gcm/notification_spec.rb +6 -88
- data/spec/unit/client/active_record/notification_spec.rb +3 -11
- data/spec/unit/client/active_record/pushy/app_spec.rb +2 -13
- data/spec/unit/client/active_record/pushy/notification_spec.rb +2 -55
- data/spec/unit/client/active_record/shared/app.rb +14 -0
- data/spec/unit/{notification_shared.rb → client/active_record/shared/notification.rb} +12 -7
- data/spec/unit/client/active_record/webpush/app_spec.rb +6 -0
- data/spec/unit/client/active_record/webpush/notification_spec.rb +6 -0
- data/spec/unit/client/active_record/wns/badge_notification_spec.rb +1 -11
- data/spec/unit/client/active_record/wns/raw_notification_spec.rb +3 -12
- data/spec/unit/client/active_record/wpns/app_spec.rb +3 -1
- data/spec/unit/client/active_record/wpns/notification_spec.rb +2 -17
- data/spec/unit/client/redis/adm/app_spec.rb +5 -0
- data/spec/unit/client/redis/adm/notification_spec.rb +5 -0
- data/spec/unit/client/redis/apns/app_spec.rb +5 -0
- data/spec/unit/client/redis/apns/feedback_spec.rb +5 -0
- data/spec/unit/client/redis/apns/notification_spec.rb +50 -0
- data/spec/unit/client/redis/apns2/app_spec.rb +4 -0
- data/spec/unit/client/redis/apns2/notification_spec.rb +50 -0
- data/spec/unit/client/redis/apnsp8/notification_spec.rb +29 -0
- data/spec/unit/client/redis/app_spec.rb +5 -0
- data/spec/unit/client/redis/gcm/app_spec.rb +5 -0
- data/spec/unit/client/redis/gcm/notification_spec.rb +5 -0
- data/spec/unit/client/redis/notification_spec.rb +5 -0
- data/spec/unit/client/redis/pushy/app_spec.rb +5 -0
- data/spec/unit/client/redis/pushy/notification_spec.rb +5 -0
- data/spec/unit/client/redis/webpush/app_spec.rb +5 -0
- data/spec/unit/client/redis/webpush/notification_spec.rb +5 -0
- data/spec/unit/client/redis/wns/badge_notification_spec.rb +5 -0
- data/spec/unit/client/redis/wns/raw_notification_spec.rb +22 -0
- data/spec/unit/client/redis/wpns/app_spec.rb +5 -0
- data/spec/unit/client/redis/wpns/notification_spec.rb +5 -0
- data/spec/unit/client/shared/adm/app.rb +51 -0
- data/spec/unit/client/shared/adm/notification.rb +39 -0
- data/spec/unit/client/shared/apns/app.rb +29 -0
- data/spec/unit/client/shared/apns/feedback.rb +9 -0
- data/spec/unit/client/shared/apns/notification.rb +262 -0
- data/spec/unit/client/shared/app.rb +17 -0
- data/spec/unit/client/shared/gcm/app.rb +4 -0
- data/spec/unit/client/shared/gcm/notification.rb +77 -0
- data/spec/unit/client/shared/notification.rb +10 -0
- data/spec/unit/client/shared/pushy/app.rb +17 -0
- data/spec/unit/client/shared/pushy/notification.rb +55 -0
- data/spec/unit/client/shared/webpush/app.rb +33 -0
- data/spec/unit/client/shared/webpush/notification.rb +83 -0
- data/spec/unit/client/shared/wns/badge_notification.rb +15 -0
- data/spec/unit/client/shared/wns/raw_notification.rb +21 -0
- data/spec/unit/client/shared/wpns/app.rb +4 -0
- data/spec/unit/client/shared/wpns/notification.rb +18 -0
- data/spec/unit/daemon/batch_spec.rb +50 -2
- data/spec/unit/daemon/delivery_spec.rb +10 -0
- data/spec/unit/daemon/pushy/delivery_spec.rb +5 -3
- data/spec/unit/daemon/shared/store.rb +312 -0
- data/spec/unit/daemon/store/active_record/reconnectable_spec.rb +7 -7
- data/spec/unit/daemon/store/active_record_spec.rb +2 -290
- data/spec/unit/daemon/store/redis_spec.rb +2 -291
- data/spec/unit/daemon/webpush/delivery_spec.rb +144 -0
- data/spec/unit_spec_helper.rb +3 -0
- metadata +135 -12
- data/lib/rpush/client/active_model/apns/binary_notification_validator.rb +0 -16
@@ -29,7 +29,7 @@ module Rpush
|
|
29
29
|
Rpush.logger.info("[#{app.name}] Starting #{pluralize(app.connections, 'dispatcher')}... ", true)
|
30
30
|
runner = @runners[app.id] = new(app)
|
31
31
|
runner.start_dispatchers
|
32
|
-
puts Rainbow('✔').green if Rpush.config.foreground
|
32
|
+
puts Rainbow('✔').green if Rpush.config.foreground && Rpush.config.foreground_logging
|
33
33
|
runner.start_loops
|
34
34
|
rescue StandardError => e
|
35
35
|
@runners.delete(app.id)
|
data/lib/rpush/daemon/batch.rb
CHANGED
@@ -2,6 +2,7 @@ module Rpush
|
|
2
2
|
module Daemon
|
3
3
|
class Batch
|
4
4
|
include Reflectable
|
5
|
+
include Loggable
|
5
6
|
|
6
7
|
attr_reader :num_processed, :notifications, :delivered, :failed, :retryable
|
7
8
|
|
@@ -31,16 +32,21 @@ module Rpush
|
|
31
32
|
@retryable[deliver_after] ||= []
|
32
33
|
@retryable[deliver_after] << notification
|
33
34
|
end
|
35
|
+
|
34
36
|
Rpush::Daemon.store.mark_retryable(notification, deliver_after, persist: false)
|
35
37
|
end
|
36
38
|
|
37
|
-
def mark_all_retryable(deliver_after)
|
38
|
-
|
39
|
-
|
40
|
-
end
|
39
|
+
def mark_all_retryable(deliver_after, error)
|
40
|
+
retryable_count = 0
|
41
|
+
|
41
42
|
each_notification do |notification|
|
42
|
-
|
43
|
+
next if notification.delivered || notification.failed
|
44
|
+
|
45
|
+
retryable_count += 1
|
46
|
+
mark_retryable(notification, deliver_after)
|
43
47
|
end
|
48
|
+
|
49
|
+
log_warn("Will retry #{retryable_count} of #{@notifications.size} notifications after #{deliver_after.strftime('%Y-%m-%d %H:%M:%S')} due to error (#{error.class.name}, #{error.message})")
|
44
50
|
end
|
45
51
|
|
46
52
|
def mark_delivered(notification)
|
@@ -54,6 +60,7 @@ module Rpush
|
|
54
60
|
@mutex.synchronize do
|
55
61
|
@delivered = @notifications
|
56
62
|
end
|
63
|
+
|
57
64
|
each_notification do |notification|
|
58
65
|
Rpush::Daemon.store.mark_delivered(notification, Time.now, persist: false)
|
59
66
|
end
|
@@ -20,8 +20,7 @@ module Rpush
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def mark_batch_retryable(deliver_after, error)
|
23
|
-
|
24
|
-
@batch.mark_all_retryable(deliver_after)
|
23
|
+
@batch.mark_all_retryable(deliver_after, error)
|
25
24
|
end
|
26
25
|
|
27
26
|
def mark_delivered
|
@@ -67,7 +67,7 @@ module Rpush
|
|
67
67
|
|
68
68
|
def check_database_is_connected
|
69
69
|
# Simply asking the adapter for the connection state is not sufficient.
|
70
|
-
Rpush::Client::ActiveRecord::Notification.
|
70
|
+
Rpush::Client::ActiveRecord::Notification.exists?
|
71
71
|
end
|
72
72
|
|
73
73
|
def sleep_to_avoid_thrashing
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "webpush"
|
4
|
+
|
5
|
+
module Rpush
|
6
|
+
module Daemon
|
7
|
+
module Webpush
|
8
|
+
|
9
|
+
# Webpush::Request handles all the encryption / signing.
|
10
|
+
# We just override #perform to inject the http instance that is managed
|
11
|
+
# by Rpush.
|
12
|
+
#
|
13
|
+
class Request < ::Webpush::Request
|
14
|
+
def perform(http)
|
15
|
+
req = Net::HTTP::Post.new(uri.request_uri, headers)
|
16
|
+
req.body = body
|
17
|
+
http.request(uri, req)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Delivery < Rpush::Daemon::Delivery
|
22
|
+
|
23
|
+
OK = [ 200, 201, 202 ].freeze
|
24
|
+
TEMPORARY_FAILURES = [ 429, 500, 502, 503, 504 ].freeze
|
25
|
+
|
26
|
+
def initialize(app, http, notification, batch)
|
27
|
+
@app = app
|
28
|
+
@http = http
|
29
|
+
@notification = notification
|
30
|
+
@batch = batch
|
31
|
+
end
|
32
|
+
|
33
|
+
def perform
|
34
|
+
response = send_request
|
35
|
+
process_response response
|
36
|
+
rescue SocketError, SystemCallError => error
|
37
|
+
mark_retryable(@notification, Time.now + 10.seconds, error)
|
38
|
+
raise
|
39
|
+
rescue StandardError => error
|
40
|
+
mark_failed(error)
|
41
|
+
raise
|
42
|
+
ensure
|
43
|
+
@batch.notification_processed
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def send_request
|
49
|
+
# The initializer is inherited from Webpush::Request and looks like
|
50
|
+
# this:
|
51
|
+
#
|
52
|
+
# initialize(message: '', subscription:, vapid:, **options)
|
53
|
+
#
|
54
|
+
# where subscription is a hash of :endpoint and :keys, and vapid
|
55
|
+
# holds the vapid public and private keys and the :subject (which is
|
56
|
+
# an email address).
|
57
|
+
Request.new(
|
58
|
+
message: @notification.message,
|
59
|
+
subscription: @notification.subscription,
|
60
|
+
vapid: @app.vapid,
|
61
|
+
ttl: @notification.time_to_live,
|
62
|
+
urgency: @notification.urgency
|
63
|
+
).perform(@http)
|
64
|
+
end
|
65
|
+
|
66
|
+
def process_response(response)
|
67
|
+
case response.code.to_i
|
68
|
+
when *OK
|
69
|
+
mark_delivered
|
70
|
+
when *TEMPORARY_FAILURES
|
71
|
+
retry_delivery(response)
|
72
|
+
else
|
73
|
+
fail_delivery(response)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def retry_delivery(response)
|
78
|
+
time = deliver_after_header(response)
|
79
|
+
if time
|
80
|
+
mark_retryable(@notification, time)
|
81
|
+
else
|
82
|
+
mark_retryable_exponential(@notification)
|
83
|
+
end
|
84
|
+
log_info("Webpush endpoint responded with a #{response.code} error. #{retry_message}")
|
85
|
+
end
|
86
|
+
|
87
|
+
def fail_delivery(response)
|
88
|
+
fail_message = fail_message(response)
|
89
|
+
log_error("#{@notification.id} failed: #{fail_message}")
|
90
|
+
fail Rpush::DeliveryError.new(response.code.to_i, @notification.id, fail_message)
|
91
|
+
end
|
92
|
+
|
93
|
+
def deliver_after_header(response)
|
94
|
+
Rpush::Daemon::RetryHeaderParser.parse(response.header['retry-after'])
|
95
|
+
end
|
96
|
+
|
97
|
+
def retry_message
|
98
|
+
deliver_after = @notification.deliver_after.strftime('%Y-%m-%d %H:%M:%S')
|
99
|
+
"Notification #{@notification.id} will be retried after #{deliver_after} (retry #{@notification.retries})."
|
100
|
+
end
|
101
|
+
|
102
|
+
def fail_message(response)
|
103
|
+
msg = Rpush::Daemon::HTTP_STATUS_CODES[response.code.to_i]
|
104
|
+
if explanation = response.body.to_s[0..200].presence
|
105
|
+
msg += ": #{explanation}"
|
106
|
+
end
|
107
|
+
msg
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
data/lib/rpush/logger.rb
CHANGED
data/lib/rpush/version.rb
CHANGED
@@ -42,6 +42,7 @@ describe 'APNs http2 adapter' do
|
|
42
42
|
app.certificate = TEST_CERT
|
43
43
|
app.name = 'test'
|
44
44
|
app.environment = 'development'
|
45
|
+
app.bundle_id = 'com.example.app'
|
45
46
|
app.save!
|
46
47
|
app
|
47
48
|
end
|
@@ -75,7 +76,12 @@ describe 'APNs http2 adapter' do
|
|
75
76
|
:post,
|
76
77
|
"/3/device/#{fake_device_token}",
|
77
78
|
{ body: "{\"aps\":{\"alert\":\"test\",\"sound\":\"default\",\"content-available\":1}}",
|
78
|
-
headers: {
|
79
|
+
headers: {
|
80
|
+
'apns-expiration' => '0',
|
81
|
+
'apns-priority' => '10',
|
82
|
+
'apns-topic' => 'com.example.app'
|
83
|
+
}
|
84
|
+
}
|
79
85
|
)
|
80
86
|
.and_return(fake_http2_request)
|
81
87
|
|
@@ -104,7 +110,11 @@ describe 'APNs http2 adapter' do
|
|
104
110
|
"/3/device/#{fake_device_token}",
|
105
111
|
{ body: "{\"aps\":{\"alert\":\"test\",\"sound\":\"default\","\
|
106
112
|
"\"content-available\":1},\"some_field\":\"some value\"}",
|
107
|
-
headers: {
|
113
|
+
headers: {
|
114
|
+
'apns-topic' => bundle_id,
|
115
|
+
'apns-expiration' => '0',
|
116
|
+
'apns-priority' => '10'
|
117
|
+
}
|
108
118
|
}
|
109
119
|
).and_return(fake_http2_request)
|
110
120
|
|
@@ -177,6 +187,13 @@ describe 'APNs http2 adapter' do
|
|
177
187
|
end
|
178
188
|
|
179
189
|
context 'when there is SocketError' do
|
190
|
+
let(:fake_http_resp_headers) {
|
191
|
+
{
|
192
|
+
":status" => "500",
|
193
|
+
"apns-id"=>"C6D65840-5E3F-785A-4D91-B97D305C12F6"
|
194
|
+
}
|
195
|
+
}
|
196
|
+
|
180
197
|
before(:each) do
|
181
198
|
expect(fake_client).to receive(:call_async) { raise(SocketError) }
|
182
199
|
end
|
@@ -201,6 +218,24 @@ describe 'APNs http2 adapter' do
|
|
201
218
|
notification = create_notification
|
202
219
|
Rpush.push
|
203
220
|
end
|
221
|
+
|
222
|
+
context 'when specific notification was delivered before request failed' do
|
223
|
+
let(:fake_http_resp_headers) {
|
224
|
+
{
|
225
|
+
":status" => "200",
|
226
|
+
"apns-id"=>"C6D65840-5E3F-785A-4D91-B97D305C12F6"
|
227
|
+
}
|
228
|
+
}
|
229
|
+
|
230
|
+
it 'fails but will not retry this notification' do
|
231
|
+
notification = create_notification
|
232
|
+
expect do
|
233
|
+
Rpush.push
|
234
|
+
notification.reload
|
235
|
+
end.to change(notification, :retries).by(0)
|
236
|
+
.and change(notification, :delivered).to(true)
|
237
|
+
end
|
238
|
+
end
|
204
239
|
end
|
205
240
|
|
206
241
|
context 'when any StandardError occurs' do
|
@@ -228,5 +263,65 @@ describe 'APNs http2 adapter' do
|
|
228
263
|
Rpush.push
|
229
264
|
end
|
230
265
|
end
|
266
|
+
|
267
|
+
context 'when waiting for requests to complete times out' do
|
268
|
+
let(:on_close) do
|
269
|
+
proc { |&block| @thread = Thread.new { sleep(0.01) } }
|
270
|
+
end
|
271
|
+
|
272
|
+
before(:each) do
|
273
|
+
@thread = nil
|
274
|
+
|
275
|
+
expect(fake_http2_request).
|
276
|
+
to receive(:on).with(:close), &on_close
|
277
|
+
|
278
|
+
expect(fake_client).to receive(:join) { @thread.join; raise(NetHttp2::AsyncRequestTimeout) }
|
279
|
+
end
|
280
|
+
|
281
|
+
it 'closes the client' do
|
282
|
+
create_notification
|
283
|
+
expect(fake_client).to receive(:close)
|
284
|
+
Rpush.push
|
285
|
+
end
|
286
|
+
|
287
|
+
it 'reflects :error' do
|
288
|
+
reflected_error = false
|
289
|
+
Rpush.reflect do |on|
|
290
|
+
on.error do |error|
|
291
|
+
reflected_error = true
|
292
|
+
expect(error).to be_kind_of(StandardError)
|
293
|
+
reflector.accept
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
notification = create_notification
|
298
|
+
Rpush.push
|
299
|
+
|
300
|
+
expect(reflected_error).to be true
|
301
|
+
end
|
302
|
+
|
303
|
+
it 'fails but retries delivery several times' do
|
304
|
+
notification = create_notification
|
305
|
+
expect do
|
306
|
+
Rpush.push
|
307
|
+
notification.reload
|
308
|
+
end.to change(notification, :retries)
|
309
|
+
end
|
310
|
+
|
311
|
+
context 'when specific notification was delivered before another async call failed' do
|
312
|
+
let(:on_close) do
|
313
|
+
proc { |&block| @thread = Thread.new { sleep(0.01); block.call } }
|
314
|
+
end
|
315
|
+
|
316
|
+
it 'fails but retries delivery several times' do
|
317
|
+
notification = create_notification
|
318
|
+
expect do
|
319
|
+
Rpush.push
|
320
|
+
notification.reload
|
321
|
+
end.to change(notification, :retries).by(0)
|
322
|
+
.and change(notification, :delivered).to(true)
|
323
|
+
end
|
324
|
+
end
|
325
|
+
end
|
231
326
|
end
|
232
327
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'functional_spec_helper'
|
2
|
+
|
3
|
+
describe 'GCM priority' do
|
4
|
+
let(:app) { Rpush::Gcm::App.new }
|
5
|
+
let(:notification) { Rpush::Gcm::Notification.new }
|
6
|
+
let(:hydrated_notification) { Rpush::Gcm::Notification.find(notification.id) }
|
7
|
+
let(:response) { double(Net::HTTPResponse, code: 200) }
|
8
|
+
let(:http) { double(Net::HTTP::Persistent, request: response, shutdown: nil) }
|
9
|
+
let(:priority) { 'normal' }
|
10
|
+
|
11
|
+
before do
|
12
|
+
app.name = 'test'
|
13
|
+
app.auth_key = 'abc123'
|
14
|
+
app.save!
|
15
|
+
|
16
|
+
notification.app_id = app.id
|
17
|
+
notification.registration_ids = ['foo']
|
18
|
+
notification.data = { message: 'test' }
|
19
|
+
notification.priority = priority
|
20
|
+
notification.save!
|
21
|
+
|
22
|
+
allow(Net::HTTP::Persistent).to receive_messages(new: http)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'supports normal priority' do
|
26
|
+
expect(hydrated_notification.as_json['priority']).to eq('normal')
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'high priority' do
|
30
|
+
let(:priority) { 'high' }
|
31
|
+
|
32
|
+
it 'supports high priority' do
|
33
|
+
expect(hydrated_notification.as_json['priority']).to eq('high')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'does not add an error when receiving expected priority' do
|
38
|
+
expect(hydrated_notification.errors.messages[:priority]).to be_empty
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'functional_spec_helper'
|
2
|
+
|
3
|
+
describe 'Webpush' do
|
4
|
+
let(:code) { 201 }
|
5
|
+
let(:response) { instance_double('Net::HTTPResponse', code: code, body: '') }
|
6
|
+
let(:http) { instance_double('Net::HTTP::Persistent', request: response, shutdown: nil) }
|
7
|
+
let(:app) { Rpush::Webpush::App.create!(name: 'MyApp', vapid_keypair: VAPID_KEYPAIR) }
|
8
|
+
|
9
|
+
let(:device_reg) {
|
10
|
+
{ endpoint: 'https://webpush-provider.example.org/push/some-id',
|
11
|
+
keys: {'auth' => 'DgN9EBia1o057BdhCOGURA', 'p256dh' => 'BAtxJ--7vHq9IVm8utUB3peJ4lpxRqk1rukCIkVJOomS83QkCnrQ4EyYQsSaCRgy_c8XPytgXxuyAvRJdnTPK4A'} }
|
12
|
+
}
|
13
|
+
let(:notification) { Rpush::Webpush::Notification.create!(app: app, registration_ids: [device_reg], data: { message: 'test' }) }
|
14
|
+
|
15
|
+
before do
|
16
|
+
allow(Net::HTTP::Persistent).to receive_messages(new: http)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'deliveres a notification successfully' do
|
20
|
+
expect { Rpush.push }.to change { notification.reload.delivered }.to(true)
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when delivery failed' do
|
24
|
+
let(:code) { 404 }
|
25
|
+
it 'marks a notification as failed' do
|
26
|
+
expect { Rpush.push }.to change { notification.reload.failed }.to(true)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
data/spec/spec_helper.rb
CHANGED
@@ -46,6 +46,8 @@ path = File.join(File.dirname(__FILE__), 'support')
|
|
46
46
|
TEST_CERT = File.read(File.join(path, 'cert_without_password.pem'))
|
47
47
|
TEST_CERT_WITH_PASSWORD = File.read(File.join(path, 'cert_with_password.pem'))
|
48
48
|
|
49
|
+
VAPID_KEYPAIR = Webpush.generate_key.to_hash.merge(subject: 'rpush-test@example.org').to_json
|
50
|
+
|
49
51
|
def after_example_cleanup
|
50
52
|
Rpush.logger = nil
|
51
53
|
Rpush::Daemon.store = nil
|