rpush 4.1.1 → 5.3.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 +261 -161
- data/README.md +103 -17
- data/lib/generators/rpush_migration_generator.rb +1 -0
- data/lib/generators/templates/rpush.rb +4 -0
- data/lib/generators/templates/rpush_4_2_0_updates.rb +10 -0
- 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 +4 -3
- 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_model/wns/notification.rb +8 -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 -29
- 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/app.rb +1 -1
- data/lib/rpush/client/active_record/notification.rb +1 -1
- 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/notification.rb +2 -1
- 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 +2 -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/dispatcher/apns_http2.rb +4 -2
- data/lib/rpush/daemon/dispatcher/apnsp8_http2.rb +2 -1
- data/lib/rpush/daemon/signal_handler.rb +1 -1
- data/lib/rpush/daemon/store/active_record.rb +1 -1
- data/lib/rpush/daemon/store/active_record/reconnectable.rb +1 -1
- data/lib/rpush/daemon/store/redis.rb +1 -1
- data/lib/rpush/daemon/webpush.rb +10 -0
- data/lib/rpush/daemon/webpush/delivery.rb +114 -0
- data/lib/rpush/daemon/wns/badge_request.rb +8 -3
- data/lib/rpush/daemon/wns/raw_request.rb +9 -2
- data/lib/rpush/daemon/wns/toast_request.rb +6 -2
- data/lib/rpush/logger.rb +1 -0
- data/lib/rpush/version.rb +3 -3
- data/spec/.rubocop.yml +1 -1
- 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/active_record_setup.rb +3 -1
- 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 -288
- 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 -83
- data/spec/unit/client/active_record/notification_spec.rb +10 -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/apns/feedback_receiver_spec.rb +19 -1
- data/spec/unit/daemon/batch_spec.rb +50 -2
- data/spec/unit/daemon/delivery_spec.rb +10 -0
- data/spec/unit/daemon/gcm/delivery_spec.rb +1 -1
- 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 +7 -295
- data/spec/unit/daemon/store/redis_spec.rb +4 -293
- data/spec/unit/daemon/webpush/delivery_spec.rb +142 -0
- data/spec/unit/daemon/wns/post_request_spec.rb +64 -0
- data/spec/unit_spec_helper.rb +3 -0
- metadata +140 -13
- data/lib/rpush/client/active_model/apns/binary_notification_validator.rb +0 -16
|
@@ -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
|
|
@@ -2,11 +2,13 @@ module Rpush
|
|
|
2
2
|
module Daemon
|
|
3
3
|
module Dispatcher
|
|
4
4
|
class ApnsHttp2
|
|
5
|
+
include Loggable
|
|
6
|
+
include Reflectable
|
|
5
7
|
|
|
6
8
|
URLS = {
|
|
7
9
|
production: 'https://api.push.apple.com:443',
|
|
8
|
-
development: 'https://api.
|
|
9
|
-
sandbox: 'https://api.
|
|
10
|
+
development: 'https://api.sandbox.push.apple.com:443',
|
|
11
|
+
sandbox: 'https://api.sandbox.push.apple.com:443'
|
|
10
12
|
}
|
|
11
13
|
|
|
12
14
|
DEFAULT_TIMEOUT = 60
|
|
@@ -29,7 +29,7 @@ module Rpush
|
|
|
29
29
|
|
|
30
30
|
def self.start_handler(read_io)
|
|
31
31
|
@thread = Thread.new do
|
|
32
|
-
while readable_io = IO.select([read_io]) # rubocop:disable AssignmentInCondition
|
|
32
|
+
while readable_io = IO.select([read_io]) # rubocop:disable Lint/AssignmentInCondition
|
|
33
33
|
signal = readable_io.first[0].gets.strip
|
|
34
34
|
|
|
35
35
|
begin
|
|
@@ -183,7 +183,7 @@ module Rpush
|
|
|
183
183
|
|
|
184
184
|
private
|
|
185
185
|
|
|
186
|
-
def create_gcm_like_notification(notification, attrs, data, registration_ids, deliver_after, app) # rubocop:disable ParameterLists
|
|
186
|
+
def create_gcm_like_notification(notification, attrs, data, registration_ids, deliver_after, app) # rubocop:disable Metrics/ParameterLists
|
|
187
187
|
with_database_reconnect_and_retry do
|
|
188
188
|
notification.assign_attributes(attrs)
|
|
189
189
|
notification.data = data
|
|
@@ -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
|
|
@@ -138,7 +138,7 @@ module Rpush
|
|
|
138
138
|
nil
|
|
139
139
|
end
|
|
140
140
|
|
|
141
|
-
def create_gcm_like_notification(notification, attrs, data, registration_ids, deliver_after, app) # rubocop:disable ParameterLists
|
|
141
|
+
def create_gcm_like_notification(notification, attrs, data, registration_ids, deliver_after, app) # rubocop:disable Metrics/ParameterLists
|
|
142
142
|
notification.assign_attributes(attrs)
|
|
143
143
|
notification.data = data
|
|
144
144
|
notification.registration_ids = registration_ids
|
|
@@ -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
|
+
|
|
@@ -4,14 +4,19 @@ module Rpush
|
|
|
4
4
|
class BadgeRequest
|
|
5
5
|
def self.create(notification, access_token)
|
|
6
6
|
body = BadgeRequestPayload.new(notification).to_xml
|
|
7
|
-
uri
|
|
8
|
-
|
|
9
|
-
uri.request_uri,
|
|
7
|
+
uri = URI.parse(notification.uri)
|
|
8
|
+
headers = {
|
|
10
9
|
"Content-Length" => body.length.to_s,
|
|
11
10
|
"Content-Type" => "text/xml",
|
|
12
11
|
"X-WNS-Type" => "wns/badge",
|
|
13
12
|
"X-WNS-RequestForStatus" => "true",
|
|
14
13
|
"Authorization" => "Bearer #{access_token}"
|
|
14
|
+
}
|
|
15
|
+
headers['X-WNS-PRIORITY'] = notification.priority.to_s if notification.priority
|
|
16
|
+
|
|
17
|
+
post = Net::HTTP::Post.new(
|
|
18
|
+
uri.request_uri,
|
|
19
|
+
headers
|
|
15
20
|
)
|
|
16
21
|
post.body = body
|
|
17
22
|
post
|
|
@@ -5,14 +5,21 @@ module Rpush
|
|
|
5
5
|
def self.create(notification, access_token)
|
|
6
6
|
body = notification.data.to_json
|
|
7
7
|
uri = URI.parse(notification.uri)
|
|
8
|
-
|
|
9
|
-
uri.request_uri,
|
|
8
|
+
headers = {
|
|
10
9
|
"Content-Length" => body.length.to_s,
|
|
11
10
|
"Content-Type" => "application/octet-stream",
|
|
12
11
|
"X-WNS-Type" => "wns/raw",
|
|
13
12
|
"X-WNS-RequestForStatus" => "true",
|
|
14
13
|
"Authorization" => "Bearer #{access_token}"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
headers['X-WNS-PRIORITY'] = notification.priority.to_s if notification.priority
|
|
17
|
+
|
|
18
|
+
post = Net::HTTP::Post.new(
|
|
19
|
+
uri.request_uri,
|
|
20
|
+
headers
|
|
15
21
|
)
|
|
22
|
+
|
|
16
23
|
post.body = body
|
|
17
24
|
post
|
|
18
25
|
end
|
|
@@ -5,13 +5,17 @@ module Rpush
|
|
|
5
5
|
def self.create(notification, access_token)
|
|
6
6
|
body = ToastRequestPayload.new(notification).to_xml
|
|
7
7
|
uri = URI.parse(notification.uri)
|
|
8
|
-
|
|
9
|
-
uri.request_uri,
|
|
8
|
+
headers = {
|
|
10
9
|
"Content-Length" => body.length.to_s,
|
|
11
10
|
"Content-Type" => "text/xml",
|
|
12
11
|
"X-WNS-Type" => "wns/toast",
|
|
13
12
|
"X-WNS-RequestForStatus" => "true",
|
|
14
13
|
"Authorization" => "Bearer #{access_token}"
|
|
14
|
+
}
|
|
15
|
+
headers['X-WNS-PRIORITY'] = notification.priority.to_s if notification.priority
|
|
16
|
+
post = Net::HTTP::Post.new(
|
|
17
|
+
uri.request_uri,
|
|
18
|
+
headers
|
|
15
19
|
)
|
|
16
20
|
post.body = body
|
|
17
21
|
post
|
data/lib/rpush/logger.rb
CHANGED
data/lib/rpush/version.rb
CHANGED
data/spec/.rubocop.yml
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
|