rpush 4.2.0 → 5.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.
- 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
|