rpush 5.4.0 → 7.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +59 -0
- data/README.md +3 -3
- data/lib/generators/templates/add_adm.rb +1 -1
- data/lib/generators/templates/add_alert_is_json_to_rapns_notifications.rb +2 -2
- data/lib/generators/templates/add_app_to_rapns.rb +2 -2
- data/lib/generators/templates/add_fail_after_to_rpush_notifications.rb +1 -1
- data/lib/generators/templates/add_gcm.rb +7 -21
- data/lib/generators/templates/add_rpush.rb +29 -79
- data/lib/generators/templates/add_wpns.rb +1 -1
- data/lib/generators/templates/create_rapns_apps.rb +1 -1
- data/lib/generators/templates/create_rapns_feedback.rb +3 -9
- data/lib/generators/templates/create_rapns_notifications.rb +3 -9
- data/lib/generators/templates/rename_rapns_to_rpush.rb +9 -33
- data/lib/generators/templates/rpush.rb +1 -4
- data/lib/generators/templates/rpush_2_0_0_updates.rb +10 -18
- data/lib/generators/templates/rpush_2_1_0_updates.rb +1 -1
- data/lib/generators/templates/rpush_2_6_0_updates.rb +1 -1
- data/lib/generators/templates/rpush_2_7_0_updates.rb +1 -1
- data/lib/generators/templates/rpush_3_0_0_updates.rb +1 -1
- data/lib/generators/templates/rpush_3_0_1_updates.rb +1 -1
- data/lib/generators/templates/rpush_3_1_0_add_pushy.rb +1 -1
- data/lib/generators/templates/rpush_3_1_1_updates.rb +1 -1
- data/lib/generators/templates/rpush_3_2_0_add_apns_p8.rb +1 -1
- data/lib/generators/templates/rpush_3_2_4_updates.rb +1 -1
- data/lib/generators/templates/rpush_3_3_0_updates.rb +1 -1
- data/lib/generators/templates/rpush_3_3_1_updates.rb +1 -1
- data/lib/generators/templates/rpush_4_1_0_updates.rb +1 -1
- data/lib/generators/templates/rpush_4_1_1_updates.rb +1 -1
- data/lib/generators/templates/rpush_4_2_0_updates.rb +1 -1
- data/lib/rpush/client/active_model/apns/app.rb +1 -17
- data/lib/rpush/client/active_model/apns/notification.rb +4 -0
- data/lib/rpush/client/active_model/apns2/app.rb +7 -1
- data/lib/rpush/client/active_model/certificate_private_key_validator.rb +19 -0
- data/lib/rpush/client/active_model/webpush/notification.rb +1 -1
- data/lib/rpush/client/active_model.rb +1 -0
- data/lib/rpush/daemon/apns2/delivery.rb +1 -0
- data/lib/rpush/daemon/apnsp8/delivery.rb +7 -1
- data/lib/rpush/daemon/store/active_record.rb +11 -7
- data/lib/rpush/daemon/store/redis.rb +6 -6
- data/lib/rpush/daemon/string_helpers.rb +1 -1
- data/lib/rpush/logger.rb +1 -1
- data/lib/rpush/version.rb +3 -3
- data/spec/functional/apns2_spec.rb +4 -2
- data/spec/functional/retry_spec.rb +1 -1
- data/spec/functional/webpush_spec.rb +1 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/support/active_record_setup.rb +4 -3
- data/spec/support/config/database.yml +4 -4
- data/spec/support/simplecov_helper.rb +1 -1
- data/spec/unit/client/active_record/apns/notification_spec.rb +1 -1
- data/spec/unit/client/active_record/apns2/app_spec.rb +1 -0
- data/spec/unit/client/active_record/apns2/notification_spec.rb +1 -1
- data/spec/unit/client/redis/apns/notification_spec.rb +1 -1
- data/spec/unit/client/redis/apns2/notification_spec.rb +1 -1
- data/spec/unit/client/shared/apns/notification.rb +15 -0
- data/spec/unit/daemon/apnsp8/delivery_spec.rb +53 -0
- data/spec/unit/daemon/store/active_record_spec.rb +7 -0
- metadata +15 -11
@@ -1,4 +1,4 @@
|
|
1
|
-
class Rpush300Updates < ActiveRecord::
|
1
|
+
class Rpush300Updates < ActiveRecord::Migration[5.0]
|
2
2
|
def self.up
|
3
3
|
add_column :rpush_notifications, :mutable_content, :boolean, default: false
|
4
4
|
change_column :rpush_notifications, :sound, :string, default: nil
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class Rpush301Updates < ActiveRecord::
|
1
|
+
class Rpush301Updates < ActiveRecord::Migration[5.0]
|
2
2
|
def self.up
|
3
3
|
change_column_null :rpush_notifications, :mutable_content, false
|
4
4
|
change_column_null :rpush_notifications, :content_available, false
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class Rpush311Updates < ActiveRecord::
|
1
|
+
class Rpush311Updates < ActiveRecord::Migration[5.0]
|
2
2
|
def self.up
|
3
3
|
change_table :rpush_notifications do |t|
|
4
4
|
t.remove_index name: 'index_rpush_notifications_multi'
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class Rpush320AddApnsP8 < ActiveRecord::
|
1
|
+
class Rpush320AddApnsP8 < ActiveRecord::Migration[5.0]
|
2
2
|
def self.up
|
3
3
|
add_column :rpush_apps, :apn_key, :string, null: true
|
4
4
|
add_column :rpush_apps, :apn_key_id, :string, null: true
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class Rpush331Updates < ActiveRecord::
|
1
|
+
class Rpush331Updates < ActiveRecord::Migration[5.0]
|
2
2
|
def self.up
|
3
3
|
change_column :rpush_notifications, :device_token, :string, null: true
|
4
4
|
change_column :rpush_feedback, :device_token, :string, null: true
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class Rpush410Updates < ActiveRecord::
|
1
|
+
class Rpush410Updates < ActiveRecord::Migration["#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"]
|
2
2
|
def self.up
|
3
3
|
add_column :rpush_notifications, :dry_run, :boolean, null: false, default: false
|
4
4
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class Rpush411Updates < ActiveRecord::
|
1
|
+
class Rpush411Updates < ActiveRecord::Migration["#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"]
|
2
2
|
def self.up
|
3
3
|
add_column :rpush_apps, :feedback_enabled, :boolean, default: true
|
4
4
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class Rpush420Updates < ActiveRecord::
|
1
|
+
class Rpush420Updates < ActiveRecord::Migration["#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"]
|
2
2
|
def self.up
|
3
3
|
add_column :rpush_notifications, :sound_is_json, :boolean, null: true, default: false
|
4
4
|
end
|
@@ -7,29 +7,13 @@ module Rpush
|
|
7
7
|
base.instance_eval do
|
8
8
|
validates :environment, presence: true, inclusion: { in: %w(development production sandbox) }
|
9
9
|
validates :certificate, presence: true
|
10
|
-
|
10
|
+
validates_with Rpush::Client::ActiveModel::CertificatePrivateKeyValidator
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
14
|
def service_name
|
15
15
|
'apns'
|
16
16
|
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def certificate_has_matching_private_key
|
21
|
-
result = false
|
22
|
-
if certificate.present?
|
23
|
-
begin
|
24
|
-
x509 = OpenSSL::X509::Certificate.new(certificate)
|
25
|
-
pkey = OpenSSL::PKey::RSA.new(certificate, password)
|
26
|
-
result = x509 && pkey
|
27
|
-
rescue OpenSSL::OpenSSLError
|
28
|
-
errors.add :certificate, 'value must contain a certificate and a private key.'
|
29
|
-
end
|
30
|
-
end
|
31
|
-
result
|
32
|
-
end
|
33
17
|
end
|
34
18
|
end
|
35
19
|
end
|
@@ -52,6 +52,10 @@ module Rpush
|
|
52
52
|
self.data = (data || {}).merge(CONTENT_AVAILABLE_KEY => true)
|
53
53
|
end
|
54
54
|
|
55
|
+
def content_available?
|
56
|
+
(self.data || {})[CONTENT_AVAILABLE_KEY]
|
57
|
+
end
|
58
|
+
|
55
59
|
def as_json(options = nil) # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
|
56
60
|
json = ActiveSupport::OrderedHash.new
|
57
61
|
|
@@ -3,7 +3,13 @@ module Rpush
|
|
3
3
|
module ActiveModel
|
4
4
|
module Apns2
|
5
5
|
module App
|
6
|
-
|
6
|
+
def self.included(base)
|
7
|
+
base.instance_eval do
|
8
|
+
validates :environment, presence: true, inclusion: { in: %w(development production sandbox) }
|
9
|
+
validates :certificate, presence: true
|
10
|
+
validates_with Rpush::Client::ActiveModel::CertificatePrivateKeyValidator
|
11
|
+
end
|
12
|
+
end
|
7
13
|
|
8
14
|
def service_name
|
9
15
|
'apns2'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Rpush
|
2
|
+
module Client
|
3
|
+
module ActiveModel
|
4
|
+
class CertificatePrivateKeyValidator < ::ActiveModel::Validator
|
5
|
+
def validate(record)
|
6
|
+
if record.certificate.present?
|
7
|
+
begin
|
8
|
+
x509 = OpenSSL::X509::Certificate.new(record.certificate)
|
9
|
+
pkey = OpenSSL::PKey::RSA.new(record.certificate, record.password)
|
10
|
+
x509 && pkey
|
11
|
+
rescue OpenSSL::OpenSSLError
|
12
|
+
record.errors.add :certificate, 'value must contain a certificate and a private key.'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -11,7 +11,7 @@ module Rpush
|
|
11
11
|
return if record.registration_ids.size > 1
|
12
12
|
reg = record.registration_ids.first
|
13
13
|
unless reg.is_a?(Hash) &&
|
14
|
-
reg.keys.
|
14
|
+
(KEYS-reg.keys).empty? &&
|
15
15
|
reg[:endpoint].is_a?(String) &&
|
16
16
|
reg[:keys].is_a?(Hash)
|
17
17
|
record.errors.add(:base, 'Registration must have :endpoint (String) and :keys (Hash) keys')
|
@@ -3,6 +3,7 @@ require 'active_model'
|
|
3
3
|
require 'rpush/client/active_model/notification'
|
4
4
|
require 'rpush/client/active_model/payload_data_size_validator'
|
5
5
|
require 'rpush/client/active_model/registration_ids_count_validator'
|
6
|
+
require 'rpush/client/active_model/certificate_private_key_validator'
|
6
7
|
|
7
8
|
require 'rpush/client/active_model/apns/device_token_format_validator'
|
8
9
|
require 'rpush/client/active_model/apns/app'
|
@@ -112,6 +112,7 @@ module Rpush
|
|
112
112
|
headers['apns-expiration'] = '0'
|
113
113
|
headers['apns-priority'] = '10'
|
114
114
|
headers['apns-topic'] = @app.bundle_id
|
115
|
+
headers['apns-push-type'] = 'background' if notification.content_available?
|
115
116
|
|
116
117
|
headers.merge notification_data(notification)[HTTP2_HEADERS_KEY] || {}
|
117
118
|
end
|
@@ -8,6 +8,7 @@ module Rpush
|
|
8
8
|
class Delivery < Rpush::Daemon::Delivery
|
9
9
|
RETRYABLE_CODES = [ 429, 500, 503 ]
|
10
10
|
CLIENT_JOIN_TIMEOUT = 60
|
11
|
+
DEFAULT_MAX_CONCURRENT_STREAMS = 100
|
11
12
|
|
12
13
|
def initialize(app, http2_client, token_provider, batch)
|
13
14
|
@app = app
|
@@ -85,7 +86,11 @@ module Rpush
|
|
85
86
|
def remote_max_concurrent_streams
|
86
87
|
# 0x7fffffff is the default value from http-2 gem (2^31)
|
87
88
|
if @client.remote_settings[:settings_max_concurrent_streams] == 0x7fffffff
|
88
|
-
|
89
|
+
# Ideally we'd fall back to `#local_settings` here, but `NetHttp2::Client`
|
90
|
+
# doesn't expose that attr from the `HTTP2::Client` it wraps. Instead, we
|
91
|
+
# chose a hard-coded value matching the default local setting from the
|
92
|
+
# `HTTP2::Client` class
|
93
|
+
DEFAULT_MAX_CONCURRENT_STREAMS
|
89
94
|
else
|
90
95
|
@client.remote_settings[:settings_max_concurrent_streams]
|
91
96
|
end
|
@@ -144,6 +149,7 @@ module Rpush
|
|
144
149
|
headers['apns-priority'] = '10'
|
145
150
|
headers['apns-topic'] = @app.bundle_id
|
146
151
|
headers['authorization'] = "bearer #{jwt_token}"
|
152
|
+
headers['apns-push-type'] = 'background' if notification.content_available?
|
147
153
|
|
148
154
|
headers.merge notification_data(notification)[HTTP2_HEADERS_KEY] || {}
|
149
155
|
end
|
@@ -181,6 +181,17 @@ module Rpush
|
|
181
181
|
id
|
182
182
|
end
|
183
183
|
|
184
|
+
def adapter_name
|
185
|
+
env = (defined?(Rails) && Rails.env) ? Rails.env : 'development'
|
186
|
+
if ::ActiveRecord::VERSION::MAJOR > 6
|
187
|
+
::ActiveRecord::Base.configurations.configs_for(env_name: env).first.configuration_hash[:adapter]
|
188
|
+
else
|
189
|
+
config = ::ActiveRecord::Base.configurations[env]
|
190
|
+
return '' unless config
|
191
|
+
Hash[config.map { |k, v| [k.to_sym, v] }][:adapter]
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
184
195
|
private
|
185
196
|
|
186
197
|
def create_gcm_like_notification(notification, attrs, data, registration_ids, deliver_after, app) # rubocop:disable Metrics/ParameterLists
|
@@ -199,13 +210,6 @@ module Rpush
|
|
199
210
|
relation = Rpush::Client::ActiveRecord::Notification.where('processing = ? AND delivered = ? AND failed = ? AND (deliver_after IS NULL OR deliver_after < ?)', false, false, false, Time.now)
|
200
211
|
relation.order('deliver_after ASC, created_at ASC')
|
201
212
|
end
|
202
|
-
|
203
|
-
def adapter_name
|
204
|
-
env = (defined?(Rails) && Rails.env) ? Rails.env : 'development'
|
205
|
-
config = ::ActiveRecord::Base.configurations[env]
|
206
|
-
return '' unless config
|
207
|
-
Hash[config.map { |k, v| [k.to_sym, v] }][:adapter]
|
208
|
-
end
|
209
213
|
end
|
210
214
|
end
|
211
215
|
end
|
@@ -152,10 +152,10 @@ module Rpush
|
|
152
152
|
retryable_ns = Rpush::Client::Redis::Notification.absolute_retryable_namespace
|
153
153
|
|
154
154
|
Modis.with_connection do |redis|
|
155
|
-
retryable_results = redis.multi do
|
155
|
+
retryable_results = redis.multi do |transaction|
|
156
156
|
now = Time.now.to_i
|
157
|
-
|
158
|
-
|
157
|
+
transaction.zrangebyscore(retryable_ns, 0, now)
|
158
|
+
transaction.zremrangebyscore(retryable_ns, 0, now)
|
159
159
|
end
|
160
160
|
|
161
161
|
retryable_results.first
|
@@ -167,9 +167,9 @@ module Rpush
|
|
167
167
|
pending_ns = Rpush::Client::Redis::Notification.absolute_pending_namespace
|
168
168
|
|
169
169
|
Modis.with_connection do |redis|
|
170
|
-
pending_results = redis.multi do
|
171
|
-
|
172
|
-
|
170
|
+
pending_results = redis.multi do |transaction|
|
171
|
+
transaction.zrange(pending_ns, 0, limit)
|
172
|
+
transaction.zremrangebyrank(pending_ns, 0, limit)
|
173
173
|
end
|
174
174
|
|
175
175
|
pending_results.first
|
data/lib/rpush/logger.rb
CHANGED
@@ -69,7 +69,7 @@ module Rpush
|
|
69
69
|
msg = "#{msg.class.name}, #{msg.message}\n#{formatted_backtrace}"
|
70
70
|
end
|
71
71
|
|
72
|
-
formatted_msg = "[#{Time.now.
|
72
|
+
formatted_msg = "[#{Time.now.to_formatted_s(:db)}]"
|
73
73
|
formatted_msg << '[rpush] ' if Rpush.config.embedded
|
74
74
|
formatted_msg << "[#{prefix}] " if prefix
|
75
75
|
formatted_msg << msg
|
data/lib/rpush/version.rb
CHANGED
@@ -79,7 +79,8 @@ describe 'APNs http2 adapter' do
|
|
79
79
|
headers: {
|
80
80
|
'apns-expiration' => '0',
|
81
81
|
'apns-priority' => '10',
|
82
|
-
'apns-topic' => 'com.example.app'
|
82
|
+
'apns-topic' => 'com.example.app',
|
83
|
+
'apns-push-type' => 'background'
|
83
84
|
}
|
84
85
|
}
|
85
86
|
)
|
@@ -113,7 +114,8 @@ describe 'APNs http2 adapter' do
|
|
113
114
|
headers: {
|
114
115
|
'apns-topic' => bundle_id,
|
115
116
|
'apns-expiration' => '0',
|
116
|
-
'apns-priority' => '10'
|
117
|
+
'apns-priority' => '10',
|
118
|
+
'apns-push-type' => 'background'
|
117
119
|
}
|
118
120
|
}
|
119
121
|
).and_return(fake_http2_request)
|
@@ -8,6 +8,7 @@ describe 'Webpush' do
|
|
8
8
|
|
9
9
|
let(:device_reg) {
|
10
10
|
{ endpoint: 'https://webpush-provider.example.org/push/some-id',
|
11
|
+
expirationTime: nil,
|
11
12
|
keys: {'auth' => 'DgN9EBia1o057BdhCOGURA', 'p256dh' => 'BAtxJ--7vHq9IVm8utUB3peJ4lpxRqk1rukCIkVJOomS83QkCnrQ4EyYQsSaCRgy_c8XPytgXxuyAvRJdnTPK4A'} }
|
12
13
|
}
|
13
14
|
let(:notification) { Rpush::Webpush::Notification.create!(app: app, registration_ids: [device_reg], data: { message: 'test' }) }
|
data/spec/spec_helper.rb
CHANGED
@@ -6,14 +6,15 @@ SPEC_ADAPTER = ENV['ADAPTER'] || 'postgresql'
|
|
6
6
|
SPEC_ADAPTER = 'jdbc' + SPEC_ADAPTER if jruby
|
7
7
|
|
8
8
|
require 'yaml'
|
9
|
-
|
9
|
+
db_config_path = File.expand_path("config/database.yml", File.dirname(__FILE__))
|
10
|
+
db_config = YAML.load(ERB.new(File.read(db_config_path)).result)
|
10
11
|
|
11
12
|
if db_config[SPEC_ADAPTER].nil?
|
12
13
|
puts "No such adapter '#{SPEC_ADAPTER}'. Valid adapters are #{db_config.keys.join(', ')}."
|
13
14
|
exit 1
|
14
15
|
end
|
15
16
|
|
16
|
-
if ENV['
|
17
|
+
if ENV['CI']
|
17
18
|
db_config[SPEC_ADAPTER]['username'] = 'postgres'
|
18
19
|
else
|
19
20
|
require 'etc'
|
@@ -62,7 +63,7 @@ migrations = [
|
|
62
63
|
Rpush420Updates
|
63
64
|
]
|
64
65
|
|
65
|
-
unless ENV['
|
66
|
+
unless ENV['CI']
|
66
67
|
migrations.reverse_each do |m|
|
67
68
|
begin
|
68
69
|
m.down
|
@@ -2,10 +2,10 @@
|
|
2
2
|
|
3
3
|
postgresql:
|
4
4
|
adapter: postgresql
|
5
|
-
database: rpush_test
|
6
|
-
host: localhost
|
7
|
-
username: postgres
|
8
|
-
password:
|
5
|
+
database: <%= ENV.fetch('POSTGRES_DB', 'rpush_test') %>
|
6
|
+
host: <%= ENV.fetch('POSTGRES_HOST', 'localhost') %>
|
7
|
+
username: <%= ENV.fetch('POSTGRES_USER', 'postgres') %>
|
8
|
+
password: <%= ENV.fetch('PGPASSWORD', '') %>
|
9
9
|
|
10
10
|
jdbcpostgresql:
|
11
11
|
adapter: jdbcpostgresql
|
@@ -8,7 +8,7 @@ describe Rpush::Client::ActiveRecord::Apns::Notification do
|
|
8
8
|
|
9
9
|
it "should validate the length of the binary conversion of the notification" do
|
10
10
|
notification = described_class.new
|
11
|
-
notification.app = Rpush::Apns2::App.create(name: 'test', environment: 'development')
|
11
|
+
notification.app = Rpush::Apns2::App.create(name: 'test', environment: 'development', certificate: TEST_CERT)
|
12
12
|
notification.device_token = "a" * 108
|
13
13
|
notification.alert = ""
|
14
14
|
|
@@ -8,7 +8,7 @@ describe Rpush::Client::ActiveRecord::Apns2::Notification do
|
|
8
8
|
|
9
9
|
it "should validate the length of the binary conversion of the notification" do
|
10
10
|
notification = described_class.new
|
11
|
-
notification.app = Rpush::Apns2::App.create(name: 'test', environment: 'development')
|
11
|
+
notification.app = Rpush::Apns2::App.create(name: 'test', environment: 'development', certificate: TEST_CERT)
|
12
12
|
notification.device_token = "a" * 108
|
13
13
|
notification.alert = ""
|
14
14
|
|
@@ -7,7 +7,7 @@ describe Rpush::Client::Redis::Apns::Notification do
|
|
7
7
|
|
8
8
|
it "should validate the length of the binary conversion of the notification" do
|
9
9
|
notification = described_class.new
|
10
|
-
notification.app = Rpush::Apns2::App.create(name: 'test', environment: 'development')
|
10
|
+
notification.app = Rpush::Apns2::App.create(name: 'test', environment: 'development', certificate: TEST_CERT)
|
11
11
|
notification.device_token = "a" * 108
|
12
12
|
notification.alert = ""
|
13
13
|
|
@@ -7,7 +7,7 @@ describe Rpush::Client::Redis::Apns2::Notification do
|
|
7
7
|
|
8
8
|
it "should validate the length of the binary conversion of the notification" do
|
9
9
|
notification = described_class.new
|
10
|
-
notification.app = Rpush::Apns2::App.create(name: 'test', environment: 'development')
|
10
|
+
notification.app = Rpush::Apns2::App.create(name: 'test', environment: 'development', certificate: TEST_CERT)
|
11
11
|
notification.device_token = "a" * 108
|
12
12
|
notification.alert = ""
|
13
13
|
|
@@ -165,6 +165,21 @@ shared_examples 'Rpush::Client::Apns::Notification' do
|
|
165
165
|
end
|
166
166
|
end
|
167
167
|
|
168
|
+
describe 'content_available?' do
|
169
|
+
context 'if not set' do
|
170
|
+
it 'should be false' do
|
171
|
+
expect(notification.content_available?).to be_falsey
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
context 'if set' do
|
176
|
+
it 'should be true' do
|
177
|
+
notification.content_available = true
|
178
|
+
expect(notification.content_available?).to be_truthy
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
168
183
|
describe 'url-args' do
|
169
184
|
it 'includes url-args in the payload' do
|
170
185
|
notification.url_args = ['url-arg-1']
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'unit_spec_helper'
|
2
|
+
|
3
|
+
describe Rpush::Daemon::Apnsp8::Delivery do
|
4
|
+
subject(:delivery) { described_class.new(app, http2_client, token_provider, batch) }
|
5
|
+
|
6
|
+
let(:app) { double(bundle_id: 'MY BUNDLE ID') }
|
7
|
+
let(:notification1) { double('Notification 1', data: {}, as_json: {}).as_null_object }
|
8
|
+
let(:notification2) { double('Notification 2', data: {}, as_json: {}).as_null_object }
|
9
|
+
|
10
|
+
let(:token_provider) { double(token: 'MY JWT TOKEN') }
|
11
|
+
let(:max_concurrent_streams) { 100 }
|
12
|
+
let(:remote_settings) { { settings_max_concurrent_streams: max_concurrent_streams } }
|
13
|
+
let(:http_request) { double(on: nil) }
|
14
|
+
let(:http2_client) do
|
15
|
+
double(
|
16
|
+
stream_count: 0,
|
17
|
+
call_async: nil,
|
18
|
+
join: nil,
|
19
|
+
prepare_request: http_request,
|
20
|
+
remote_settings: remote_settings
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
let(:batch) { double(mark_delivered: nil, all_processed: nil) }
|
25
|
+
let(:logger) { double(info: nil) }
|
26
|
+
|
27
|
+
before do
|
28
|
+
allow(batch).to receive(:each_notification) do |&blk|
|
29
|
+
[notification1, notification2].each(&blk)
|
30
|
+
end
|
31
|
+
allow(Rpush).to receive_messages(logger: logger)
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#perform' do
|
35
|
+
context 'with an HTTP2 client where max concurrent streams is not set' do
|
36
|
+
let(:max_concurrent_streams) { 0x7fffffff }
|
37
|
+
|
38
|
+
it 'does not fall into an infinite loop on notifications after the first' do
|
39
|
+
start = Time.now
|
40
|
+
thread = Thread.new { delivery.perform }
|
41
|
+
|
42
|
+
loop do
|
43
|
+
break unless thread.alive?
|
44
|
+
|
45
|
+
if Time.now - start > 0.5
|
46
|
+
thread.kill
|
47
|
+
fail 'Stuck in an infinite loop'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -66,4 +66,11 @@ describe Rpush::Daemon::Store::ActiveRecord do
|
|
66
66
|
expect(store.deliverable_notifications(Rpush.config.batch_size)).to be_empty
|
67
67
|
end
|
68
68
|
end
|
69
|
+
|
70
|
+
describe "#adapter_name" do
|
71
|
+
it "should return the adapter name" do
|
72
|
+
adapter = ENV["ADAPTER"] || "postgresql"
|
73
|
+
expect(store.adapter_name).to eq(adapter)
|
74
|
+
end
|
75
|
+
end
|
69
76
|
end if active_record?
|