rpush 5.3.0 → 7.0.0

Sign up to get free protection for your applications and to get access to all the features.
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