rpush 5.3.0 → 7.0.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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +60 -0
  3. data/README.md +4 -4
  4. data/lib/generators/templates/add_adm.rb +1 -1
  5. data/lib/generators/templates/add_alert_is_json_to_rapns_notifications.rb +2 -2
  6. data/lib/generators/templates/add_app_to_rapns.rb +2 -2
  7. data/lib/generators/templates/add_fail_after_to_rpush_notifications.rb +1 -1
  8. data/lib/generators/templates/add_gcm.rb +11 -25
  9. data/lib/generators/templates/add_rpush.rb +33 -83
  10. data/lib/generators/templates/add_wpns.rb +1 -1
  11. data/lib/generators/templates/create_rapns_apps.rb +1 -1
  12. data/lib/generators/templates/create_rapns_feedback.rb +3 -9
  13. data/lib/generators/templates/create_rapns_notifications.rb +3 -9
  14. data/lib/generators/templates/rename_rapns_to_rpush.rb +9 -33
  15. data/lib/generators/templates/rpush.rb +1 -4
  16. data/lib/generators/templates/rpush_2_0_0_updates.rb +10 -18
  17. data/lib/generators/templates/rpush_2_1_0_updates.rb +1 -1
  18. data/lib/generators/templates/rpush_2_6_0_updates.rb +1 -1
  19. data/lib/generators/templates/rpush_2_7_0_updates.rb +1 -1
  20. data/lib/generators/templates/rpush_3_0_0_updates.rb +1 -1
  21. data/lib/generators/templates/rpush_3_0_1_updates.rb +1 -1
  22. data/lib/generators/templates/rpush_3_1_0_add_pushy.rb +1 -1
  23. data/lib/generators/templates/rpush_3_1_1_updates.rb +1 -1
  24. data/lib/generators/templates/rpush_3_2_0_add_apns_p8.rb +1 -1
  25. data/lib/generators/templates/rpush_3_2_4_updates.rb +1 -1
  26. data/lib/generators/templates/rpush_3_3_0_updates.rb +1 -1
  27. data/lib/generators/templates/rpush_3_3_1_updates.rb +3 -3
  28. data/lib/generators/templates/rpush_4_1_0_updates.rb +1 -1
  29. data/lib/generators/templates/rpush_4_1_1_updates.rb +1 -1
  30. data/lib/generators/templates/rpush_4_2_0_updates.rb +1 -1
  31. data/lib/rpush/client/active_model/apns/app.rb +1 -17
  32. data/lib/rpush/client/active_model/apns/notification.rb +4 -0
  33. data/lib/rpush/client/active_model/apns2/app.rb +7 -1
  34. data/lib/rpush/client/active_model/certificate_private_key_validator.rb +19 -0
  35. data/lib/rpush/client/active_model/webpush/notification.rb +1 -1
  36. data/lib/rpush/client/active_model.rb +1 -0
  37. data/lib/rpush/daemon/apns2/delivery.rb +1 -0
  38. data/lib/rpush/daemon/apnsp8/delivery.rb +7 -1
  39. data/lib/rpush/daemon/store/active_record.rb +11 -7
  40. data/lib/rpush/daemon/string_helpers.rb +1 -1
  41. data/lib/rpush/logger.rb +1 -1
  42. data/lib/rpush/version.rb +2 -2
  43. data/spec/functional/apns2_spec.rb +4 -2
  44. data/spec/functional/retry_spec.rb +1 -1
  45. data/spec/functional/webpush_spec.rb +1 -0
  46. data/spec/spec_helper.rb +1 -1
  47. data/spec/support/active_record_setup.rb +4 -3
  48. data/spec/support/config/database.yml +4 -4
  49. data/spec/support/simplecov_helper.rb +1 -1
  50. data/spec/unit/client/active_record/apns/notification_spec.rb +1 -1
  51. data/spec/unit/client/active_record/apns2/app_spec.rb +1 -0
  52. data/spec/unit/client/active_record/apns2/notification_spec.rb +1 -1
  53. data/spec/unit/client/redis/apns/notification_spec.rb +1 -1
  54. data/spec/unit/client/redis/apns2/notification_spec.rb +1 -1
  55. data/spec/unit/client/shared/apns/notification.rb +15 -0
  56. data/spec/unit/daemon/apnsp8/delivery_spec.rb +53 -0
  57. data/spec/unit/daemon/pushy/delivery_spec.rb +5 -3
  58. data/spec/unit/daemon/store/active_record_spec.rb +7 -0
  59. data/spec/unit/daemon/webpush/delivery_spec.rb +5 -3
  60. metadata +15 -11
@@ -1,4 +1,4 @@
1
- class Rpush200Updates < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
1
+ class Rpush200Updates < ActiveRecord::Migration[5.0]
2
2
  module Rpush
3
3
  class App < ActiveRecord::Base
4
4
  self.table_name = 'rpush_apps'
@@ -17,14 +17,8 @@ class Rpush200Updates < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migrat
17
17
  add_column :rpush_notifications, :processing, :boolean, null: false, default: false
18
18
  add_column :rpush_notifications, :priority, :integer, null: true
19
19
 
20
- if ActiveRecord.version >= Gem::Version.new('5.1')
21
- if index_name_exists?(:rpush_notifications, :index_rpush_notifications_multi)
22
- remove_index :rpush_notifications, name: :index_rpush_notifications_multi
23
- end
24
- else
25
- if index_name_exists?(:rpush_notifications, :index_rpush_notifications_multi, true)
26
- remove_index :rpush_notifications, name: :index_rpush_notifications_multi
27
- end
20
+ if index_name_exists?(:rpush_notifications, :index_rpush_notifications_multi)
21
+ remove_index :rpush_notifications, name: :index_rpush_notifications_multi
28
22
  end
29
23
 
30
24
  add_index :rpush_notifications, [:delivered, :failed], name: 'index_rpush_notifications_multi', where: 'NOT delivered AND NOT failed'
@@ -52,14 +46,8 @@ class Rpush200Updates < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migrat
52
46
  change_column :rpush_feedback, :app_id, :string
53
47
  rename_column :rpush_feedback, :app_id, :app
54
48
 
55
- if ActiveRecord.version >= Gem::Version.new('5.1')
56
- if index_name_exists?(:rpush_notifications, :index_rpush_notifications_multi)
57
- remove_index :rpush_notifications, name: :index_rpush_notifications_multi
58
- end
59
- else
60
- if index_name_exists?(:rpush_notifications, :index_rpush_notifications_multi, true)
61
- remove_index :rpush_notifications, name: :index_rpush_notifications_multi
62
- end
49
+ if index_name_exists?(:rpush_notifications, :index_rpush_notifications_multi)
50
+ remove_index :rpush_notifications, name: :index_rpush_notifications_multi
63
51
  end
64
52
 
65
53
  add_index :rpush_notifications, [:app_id, :delivered, :failed, :deliver_after], name: 'index_rpush_notifications_multi'
@@ -70,7 +58,11 @@ class Rpush200Updates < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migrat
70
58
 
71
59
  def self.adapter_name
72
60
  env = (defined?(Rails) && Rails.env) ? Rails.env : 'development'
73
- Hash[ActiveRecord::Base.configurations[env].map { |k,v| [k.to_sym,v] }][:adapter]
61
+ if ActiveRecord::VERSION::MAJOR > 6
62
+ ActiveRecord::Base.configurations.configs_for(env_name: env).first.configuration_hash[:adapter]
63
+ else
64
+ Hash[ActiveRecord::Base.configurations[env].map { |k,v| [k.to_sym,v] }][:adapter]
65
+ end
74
66
  end
75
67
 
76
68
  def self.postgresql?
@@ -1,4 +1,4 @@
1
- class Rpush210Updates < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
1
+ class Rpush210Updates < ActiveRecord::Migration[5.0]
2
2
  def self.up
3
3
  add_column :rpush_notifications, :url_args, :text, null: true
4
4
  add_column :rpush_notifications, :category, :string, null: true
@@ -1,4 +1,4 @@
1
- class Rpush260Updates < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
1
+ class Rpush260Updates < ActiveRecord::Migration[5.0]
2
2
  def self.up
3
3
  add_column :rpush_notifications, :content_available, :boolean, default: false
4
4
  end
@@ -1,4 +1,4 @@
1
- class Rpush270Updates < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
1
+ class Rpush270Updates < ActiveRecord::Migration[5.0]
2
2
  def self.up
3
3
  change_column :rpush_notifications, :alert, :text
4
4
  add_column :rpush_notifications, :notification, :text
@@ -1,4 +1,4 @@
1
- class Rpush300Updates < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
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::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
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 Rpush310AddPushy < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
1
+ class Rpush310AddPushy < ActiveRecord::Migration[5.0]
2
2
  def self.up
3
3
  add_column :rpush_notifications, :external_device_id, :string, null: true
4
4
  end
@@ -1,4 +1,4 @@
1
- class Rpush311Updates < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
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::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
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 Rpush324Updates < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
1
+ class Rpush324Updates < ActiveRecord::Migration[5.0]
2
2
  def self.up
3
3
  change_column :rpush_apps, :apn_key, :text, null: true
4
4
  end
@@ -1,4 +1,4 @@
1
- class Rpush330Updates < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
1
+ class Rpush330Updates < ActiveRecord::Migration[5.0]
2
2
  def self.up
3
3
  add_column :rpush_notifications, :thread_id, :string, null: true
4
4
  end
@@ -1,11 +1,11 @@
1
- class Rpush331Updates < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
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
5
5
  end
6
6
 
7
7
  def self.down
8
- change_column :rpush_notifications, :device_token, :string, { null: true, limit: 64 }
9
- change_column :rpush_feedback, :device_token, :string, { null: true, limit: 64 }
8
+ change_column :rpush_notifications, :device_token, :string, null: true, limit: 64
9
+ change_column :rpush_feedback, :device_token, :string, null: true, limit: 64
10
10
  end
11
11
  end
@@ -1,4 +1,4 @@
1
- class Rpush410Updates < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migration["#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"] : ActiveRecord::Migration
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::VERSION::MAJOR >= 5 ? ActiveRecord::Migration["#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"] : ActiveRecord::Migration
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::VERSION::MAJOR >= 5 ? ActiveRecord::Migration["#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"] : ActiveRecord::Migration
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
- validate :certificate_has_matching_private_key
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
- extend Rpush::Client::ActiveModel::Apns::App
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.sort == 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
- 0
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
@@ -2,7 +2,7 @@ module Rpush
2
2
  module Daemon
3
3
  module StringHelpers
4
4
  def pluralize(count, singular, plural = nil)
5
- if count == 1 || count =~ /^1(\.0+)?$/
5
+ if count == 1
6
6
  word = singular
7
7
  else
8
8
  word = plural || singular.pluralize
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.to_s(:db)}] "
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
@@ -1,7 +1,7 @@
1
1
  module Rpush
2
2
  module VERSION
3
- MAJOR = 5
4
- MINOR = 3
3
+ MAJOR = 7
4
+ MINOR = 0
5
5
  TINY = 0
6
6
  PRE = nil
7
7
 
@@ -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)
@@ -39,4 +39,4 @@ describe 'Retries' do
39
39
  notification.reload
40
40
  expect(notification.delivered).to eq(false)
41
41
  end
42
- end
42
+ end if redis?
@@ -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
@@ -3,7 +3,7 @@ def client
3
3
  (ENV['CLIENT'] || :active_record).to_sym
4
4
  end
5
5
 
6
- if !ENV['TRAVIS'] || (ENV['TRAVIS'] && ENV['QUALITY'] == 'true')
6
+ if !ENV['CI'] || (ENV['CI'] && ENV['QUALITY'] == 'true')
7
7
  begin
8
8
  require './spec/support/simplecov_helper'
9
9
  include SimpleCovHelper
@@ -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
- db_config = YAML.load_file(File.expand_path("config/database.yml", File.dirname(__FILE__)))
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['TRAVIS']
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['TRAVIS']
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
@@ -10,7 +10,7 @@ module SimpleCovHelper
10
10
 
11
11
  formatters = [SimpleCov::Formatter::QualityFormatter]
12
12
 
13
- if ENV['TRAVIS']
13
+ if ENV['CI']
14
14
  require 'codeclimate-test-reporter'
15
15
 
16
16
  if CodeClimate::TestReporter.run?
@@ -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
 
@@ -1,4 +1,5 @@
1
1
  require 'unit_spec_helper'
2
2
 
3
3
  describe Rpush::Client::ActiveRecord::Apns2::App do
4
+ it_behaves_like 'Rpush::Client::Apns::App'
4
5
  end if active_record?
@@ -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
@@ -61,10 +61,12 @@ describe Rpush::Daemon::Pushy::Delivery do
61
61
  it_behaves_like 'process notification'
62
62
  end
63
63
 
64
- shared_examples 'retry delivery' do |response_code:|
65
- let(:response_code) { response_code }
64
+ shared_examples 'retry delivery' do |options|
65
+ let(:response_code) { options[:response_code] }
66
+
67
+ shared_examples 'logs' do |log_options|
68
+ let(:deliver_after) { log_options[:deliver_after] }
66
69
 
67
- shared_examples 'logs' do |deliver_after:|
68
70
  let(:expected_log_message) do
69
71
  "Pushy responded with a #{response_code} error. Notification #{notification.id} " \
70
72
  "will be retried after #{deliver_after} (retry 1)."
@@ -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?
@@ -50,10 +50,12 @@ describe Rpush::Daemon::Webpush::Delivery do
50
50
  it_behaves_like 'process notification'
51
51
  end
52
52
 
53
- shared_examples 'retry delivery' do |response_code:|
54
- let(:response_code) { response_code }
53
+ shared_examples 'retry delivery' do |options|
54
+ let(:response_code) { options[:response_code] }
55
+
56
+ shared_examples 'logs' do |log_options|
57
+ let(:deliver_after) { log_options[:deliver_after] }
55
58
 
56
- shared_examples 'logs' do |deliver_after:|
57
59
  let(:expected_log_message) do
58
60
  "[MyApp] Webpush endpoint responded with a #{response_code} error. Notification #{notification.id} will be retried after #{deliver_after} (retry 1)."
59
61
  end