rpush 7.0.1 → 8.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +28 -4
  3. data/README.md +38 -1
  4. data/lib/generators/rpush_migration_generator.rb +1 -0
  5. data/lib/generators/templates/rpush.rb +17 -0
  6. data/lib/generators/templates/rpush_7_1_0_updates.rb +12 -0
  7. data/lib/rpush/client/active_model/apns/notification.rb +0 -4
  8. data/lib/rpush/client/active_model/fcm/app.rb +20 -0
  9. data/lib/rpush/client/active_model/fcm/expiry_collapse_key_mutual_inclusion_validator.rb +14 -0
  10. data/lib/rpush/client/active_model/fcm/notification.rb +129 -0
  11. data/lib/rpush/client/active_model/fcm/notification_keys_in_allowed_list_validator.rb +20 -0
  12. data/lib/rpush/client/active_model.rb +5 -0
  13. data/lib/rpush/client/active_record/fcm/app.rb +11 -0
  14. data/lib/rpush/client/active_record/fcm/notification.rb +11 -0
  15. data/lib/rpush/client/active_record.rb +3 -0
  16. data/lib/rpush/client/redis/app.rb +2 -0
  17. data/lib/rpush/client/redis/fcm/app.rb +11 -0
  18. data/lib/rpush/client/redis/fcm/notification.rb +11 -0
  19. data/lib/rpush/client/redis.rb +3 -0
  20. data/lib/rpush/configuration.rb +1 -1
  21. data/lib/rpush/daemon/apns2/delivery.rb +0 -1
  22. data/lib/rpush/daemon/apnsp8/delivery.rb +0 -1
  23. data/lib/rpush/daemon/fcm/delivery.rb +162 -0
  24. data/lib/rpush/daemon/fcm.rb +9 -0
  25. data/lib/rpush/daemon/gcm/delivery.rb +1 -1
  26. data/lib/rpush/daemon/google_credential_cache.rb +41 -0
  27. data/lib/rpush/daemon/store/active_record.rb +15 -0
  28. data/lib/rpush/daemon/store/interface.rb +2 -2
  29. data/lib/rpush/daemon/store/redis.rb +13 -0
  30. data/lib/rpush/daemon/webpush/delivery.rb +2 -2
  31. data/lib/rpush/daemon.rb +4 -0
  32. data/lib/rpush/reflection_collection.rb +3 -2
  33. data/lib/rpush/version.rb +2 -2
  34. data/lib/rpush.rb +1 -0
  35. data/spec/functional/apns2_spec.rb +2 -6
  36. data/spec/functional/fcm_priority_spec.rb +46 -0
  37. data/spec/functional/fcm_spec.rb +77 -0
  38. data/spec/functional_spec_helper.rb +1 -1
  39. data/spec/spec_helper.rb +2 -1
  40. data/spec/support/active_record_setup.rb +3 -1
  41. data/spec/unit/client/active_record/fcm/app_spec.rb +6 -0
  42. data/spec/unit/client/active_record/fcm/notification_spec.rb +10 -0
  43. data/spec/unit/client/redis/fcm/app_spec.rb +5 -0
  44. data/spec/unit/client/redis/fcm/notification_spec.rb +5 -0
  45. data/spec/unit/client/shared/apns/notification.rb +0 -15
  46. data/spec/unit/client/shared/fcm/app.rb +4 -0
  47. data/spec/unit/client/shared/fcm/notification.rb +92 -0
  48. data/spec/unit/configuration_spec.rb +1 -1
  49. data/spec/unit/daemon/apnsp8/delivery_spec.rb +1 -1
  50. data/spec/unit/daemon/fcm/delivery_spec.rb +127 -0
  51. data/spec/unit/daemon/service_config_methods_spec.rb +1 -1
  52. data/spec/unit/daemon/tcp_connection_spec.rb +8 -7
  53. data/spec/unit/daemon/wns/delivery_spec.rb +1 -1
  54. data/spec/unit/logger_spec.rb +1 -1
  55. data/spec/unit_spec_helper.rb +1 -1
  56. metadata +81 -17
@@ -0,0 +1,9 @@
1
+ module Rpush
2
+ module Daemon
3
+ module Fcm
4
+ extend ServiceConfigMethods
5
+
6
+ dispatcher :http
7
+ end
8
+ end
9
+ end
@@ -238,4 +238,4 @@ module Rpush
238
238
  end
239
239
  end
240
240
  end
241
- end
241
+ end
@@ -0,0 +1,41 @@
1
+ require 'singleton'
2
+ module Rpush
3
+ module Daemon
4
+ class GoogleCredentialCache
5
+ include Singleton
6
+ include Loggable
7
+
8
+ # Assuming tokens are valid for 1 hour
9
+ TOKEN_VALID_FOR_SEC = 60 * 59
10
+
11
+ def initialize
12
+ @credentials_cache = {}
13
+ end
14
+
15
+ def access_token(scope, json_key)
16
+ key = hash_key(scope, json_key)
17
+
18
+ if @credentials_cache[key].nil? || Time.now > @credentials_cache[key][:expires_at]
19
+ token = fetch_fresh_token(scope, json_key)
20
+ expires_at = Time.now + TOKEN_VALID_FOR_SEC
21
+ @credentials_cache[key] = { token: token, expires_at: expires_at }
22
+ end
23
+
24
+ @credentials_cache[key][:token]
25
+ end
26
+
27
+ private
28
+
29
+ def fetch_fresh_token(scope, json_key)
30
+ json_key_io = json_key ? StringIO.new(json_key) : nil
31
+ log_debug("FCM - Obtaining access token.")
32
+ authorizer = Google::Auth::ServiceAccountCredentials.make_creds(scope: scope, json_key_io: json_key_io)
33
+ authorizer.fetch_access_token
34
+ end
35
+
36
+ def hash_key(scope, json_key)
37
+ scope.hash ^ json_key.hash
38
+ end
39
+ end
40
+ end
41
+ end
@@ -145,6 +145,11 @@ module Rpush
145
145
  end
146
146
  end
147
147
 
148
+ def create_fcm_notification(attrs, data, app)
149
+ notification = Rpush::Client::ActiveRecord::Fcm::Notification.new
150
+ create_fcm_like_notification(notification, attrs, data, app)
151
+ end
152
+
148
153
  def create_gcm_notification(attrs, data, registration_ids, deliver_after, app)
149
154
  notification = Rpush::Client::ActiveRecord::Gcm::Notification.new
150
155
  create_gcm_like_notification(notification, attrs, data, registration_ids, deliver_after, app)
@@ -194,6 +199,16 @@ module Rpush
194
199
 
195
200
  private
196
201
 
202
+ def create_fcm_like_notification(notification, attrs, data, app) # rubocop:disable Metrics/ParameterLists
203
+ with_database_reconnect_and_retry do
204
+ notification.assign_attributes(attrs)
205
+ notification.data = data
206
+ notification.app = app
207
+ notification.save!
208
+ notification
209
+ end
210
+ end
211
+
197
212
  def create_gcm_like_notification(notification, attrs, data, registration_ids, deliver_after, app) # rubocop:disable Metrics/ParameterLists
198
213
  with_database_reconnect_and_retry do
199
214
  notification.assign_attributes(attrs)
@@ -5,8 +5,8 @@ module Rpush
5
5
  PUBLIC_METHODS = [:deliverable_notifications, :mark_retryable,
6
6
  :mark_batch_retryable, :mark_delivered, :mark_batch_delivered,
7
7
  :mark_failed, :mark_batch_failed, :create_apns_feedback,
8
- :create_gcm_notification, :create_adm_notification, :update_app,
9
- :update_notification, :release_connection,
8
+ :create_fcm_notification, :create_gcm_notification, :create_adm_notification,
9
+ :update_app, :update_notification, :release_connection,
10
10
  :all_apps, :app, :mark_ids_failed, :mark_ids_retryable,
11
11
  :reopen_log, :pending_delivery_count, :translate_integer_notification_id]
12
12
 
@@ -92,6 +92,11 @@ module Rpush
92
92
  Rpush::Client::Redis::Apns::Feedback.create!(failed_at: failed_at, device_token: device_token, app_id: app.id)
93
93
  end
94
94
 
95
+ def create_fcm_notification(attrs, data, app)
96
+ notification = Rpush::Client::Redis::Fcm::Notification.new
97
+ create_fcm_like_notification(notification, attrs, data, app)
98
+ end
99
+
95
100
  def create_gcm_notification(attrs, data, registration_ids, deliver_after, app)
96
101
  notification = Rpush::Client::Redis::Gcm::Notification.new
97
102
  create_gcm_like_notification(notification, attrs, data, registration_ids, deliver_after, app)
@@ -138,6 +143,14 @@ module Rpush
138
143
  nil
139
144
  end
140
145
 
146
+ def create_fcm_like_notification(notification, attrs, data, app) # rubocop:disable Metrics/ParameterLists
147
+ notification.assign_attributes(attrs)
148
+ notification.data = data
149
+ notification.app = app
150
+ notification.save!
151
+ notification
152
+ end
153
+
141
154
  def create_gcm_like_notification(notification, attrs, data, registration_ids, deliver_after, app) # rubocop:disable Metrics/ParameterLists
142
155
  notification.assign_attributes(attrs)
143
156
  notification.data = data
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "webpush"
3
+ require "web-push"
4
4
 
5
5
  module Rpush
6
6
  module Daemon
@@ -10,7 +10,7 @@ module Rpush
10
10
  # We just override #perform to inject the http instance that is managed
11
11
  # by Rpush.
12
12
  #
13
- class Request < ::Webpush::Request
13
+ class Request < ::WebPush::Request
14
14
  def perform(http)
15
15
  req = Net::HTTP::Post.new(uri.request_uri, headers)
16
16
  req.body = body
data/lib/rpush/daemon.rb CHANGED
@@ -49,6 +49,10 @@ require 'rpush/daemon/apnsp8/delivery'
49
49
  require 'rpush/daemon/apnsp8/token'
50
50
  require 'rpush/daemon/apnsp8'
51
51
 
52
+ require 'rpush/daemon/fcm/delivery'
53
+ require 'rpush/daemon/fcm'
54
+ require 'rpush/daemon/google_credential_cache'
55
+
52
56
  require 'rpush/daemon/gcm/delivery'
53
57
  require 'rpush/daemon/gcm'
54
58
 
@@ -4,8 +4,9 @@ module Rpush
4
4
 
5
5
  REFLECTIONS = [
6
6
  :apns_feedback, :notification_enqueued, :notification_delivered,
7
- :notification_failed, :notification_will_retry, :gcm_delivered_to_recipient,
8
- :gcm_failed_to_recipient, :gcm_canonical_id, :gcm_invalid_registration_id,
7
+ :notification_failed, :notification_will_retry,
8
+ :gcm_delivered_to_recipient, :gcm_failed_to_recipient, :gcm_canonical_id, :gcm_invalid_registration_id,
9
+ :fcm_delivered_to_recipient, :fcm_failed_to_recipient, :fcm_canonical_id, :fcm_invalid_device_token,
9
10
  :error, :adm_canonical_id, :adm_failed_to_recipient, :wns_invalid_channel,
10
11
  :tcp_connection_lost, :ssl_certificate_will_expire, :ssl_certificate_revoked,
11
12
  :notification_id_will_retry, :notification_id_failed
data/lib/rpush/version.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  module Rpush
2
2
  module VERSION
3
- MAJOR = 7
3
+ MAJOR = 8
4
4
  MINOR = 0
5
- TINY = 1
5
+ TINY = 0
6
6
  PRE = nil
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".").freeze
data/lib/rpush.rb CHANGED
@@ -3,6 +3,7 @@ require 'multi_json'
3
3
  require 'active_support/all'
4
4
  require 'net-http2'
5
5
  require 'jwt'
6
+ require 'googleauth'
6
7
 
7
8
  require 'rails'
8
9
 
@@ -79,8 +79,7 @@ describe 'APNs http2 adapter' do
79
79
  headers: {
80
80
  'apns-expiration' => '0',
81
81
  'apns-priority' => '10',
82
- 'apns-topic' => 'com.example.app',
83
- 'apns-push-type' => 'background'
82
+ 'apns-topic' => 'com.example.app'
84
83
  }
85
84
  }
86
85
  )
@@ -114,8 +113,7 @@ describe 'APNs http2 adapter' do
114
113
  headers: {
115
114
  'apns-topic' => bundle_id,
116
115
  'apns-expiration' => '0',
117
- 'apns-priority' => '10',
118
- 'apns-push-type' => 'background'
116
+ 'apns-priority' => '10'
119
117
  }
120
118
  }
121
119
  ).and_return(fake_http2_request)
@@ -257,7 +255,6 @@ describe 'APNs http2 adapter' do
257
255
  Rpush.reflect do |on|
258
256
  on.error do |error|
259
257
  expect(error).to be_kind_of(StandardError)
260
- reflector.accept
261
258
  end
262
259
  end
263
260
 
@@ -292,7 +289,6 @@ describe 'APNs http2 adapter' do
292
289
  on.error do |error|
293
290
  reflected_error = true
294
291
  expect(error).to be_kind_of(StandardError)
295
- reflector.accept
296
292
  end
297
293
  end
298
294
 
@@ -0,0 +1,46 @@
1
+ require 'functional_spec_helper'
2
+
3
+ describe 'FCM priority' do
4
+ let(:app) { Rpush::Fcm::App.new }
5
+ let(:notification) { Rpush::Fcm::Notification.new }
6
+ let(:hydrated_notification) { Rpush::Fcm::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
+ let(:fake_device_token) { 'a' * 108 }
11
+
12
+ before do
13
+ app.name = 'test'
14
+ app.auth_key = 'abc123'
15
+ app.save!
16
+
17
+ notification.app_id = app.id
18
+ notification.device_token = fake_device_token
19
+ notification.data = { message: 'test' }
20
+ notification.notification = { title: 'title' }
21
+ notification.priority = priority
22
+ notification.save!
23
+
24
+ allow(Net::HTTP::Persistent).to receive_messages(new: http)
25
+ end
26
+
27
+ it 'supports normal priority' do
28
+ json = hydrated_notification.as_json
29
+ expect(json["message"]["android"]["notification"]["notification_priority"]).to eq('PRIORITY_DEFAULT')
30
+ expect(json["message"]["android"]["priority"]).to eq('normal')
31
+ end
32
+
33
+ context 'high priority' do
34
+ let(:priority) { 'high' }
35
+
36
+ it 'supports high priority' do
37
+ json = hydrated_notification.as_json
38
+ expect(json["message"]["android"]["notification"]["notification_priority"]).to eq('PRIORITY_MAX')
39
+ expect(json["message"]["android"]["priority"]).to eq('high')
40
+ end
41
+ end
42
+
43
+ it 'does not add an error when receiving expected priority' do
44
+ expect(hydrated_notification.errors.messages[:priority]).to be_empty
45
+ end
46
+ end
@@ -0,0 +1,77 @@
1
+ require 'functional_spec_helper'
2
+
3
+ describe 'FCM' do
4
+ let(:app) { Rpush::Fcm::App.new }
5
+ let(:notification) { Rpush::Fcm::Notification.new }
6
+ let(:response) { double(Net::HTTPResponse, code: 200) }
7
+ let(:http) { double(Net::HTTP::Persistent, request: response, shutdown: nil) }
8
+ let(:fake_device_token) { 'a' * 108 }
9
+ let(:creds) {double(Google::Auth::UserRefreshCredentials)}
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.device_token = fake_device_token
18
+ notification.data = { message: 'test' }
19
+ notification.save!
20
+
21
+ allow(Net::HTTP::Persistent).to receive_messages(new: http)
22
+ allow(creds).to receive(:fetch_access_token).and_return({'access_token': 'face_access_token'})
23
+
24
+ allow(::Google::Auth::ServiceAccountCredentials).to receive(:fetch_access_token).and_return({access_token: 'bbbbbb'})
25
+ allow(::Google::Auth::ServiceAccountCredentials).to receive(:make_creds).and_return(creds)
26
+ allow_any_instance_of(::Rpush::Daemon::Fcm::Delivery).to receive(:necessary_data_exists?).and_return(true)
27
+ end
28
+
29
+ it 'delivers a notification successfully' do
30
+ example_success_body = {
31
+ "multicast_id": 108,
32
+ "success": 1,
33
+ "failure": 0,
34
+ "canonical_ids": 0,
35
+ "results": [
36
+ { "message_id": "1:08" }
37
+ ]
38
+ }.to_json
39
+ allow(response).to receive_messages(body: example_success_body)
40
+
41
+ expect do
42
+ Rpush.push
43
+ notification.reload
44
+ end.to change(notification, :delivered).to(true)
45
+ end
46
+
47
+ it 'fails to deliver a notification successfully' do
48
+ example_error_body = {
49
+ "error": {
50
+ "code": 400,
51
+ "message": "The registration token is not a valid FCM registration token",
52
+ "errors": [
53
+ {
54
+ "message": "The registration token is not a valid FCM registration token",
55
+ "domain": "global",
56
+ "reason": "badRequest"
57
+ }
58
+ ],
59
+ "status": "INVALID_ARGUMENT"
60
+ }
61
+ }.to_json
62
+
63
+ allow(response).to receive_messages(code: 400, body: example_error_body)
64
+ Rpush.push
65
+ notification.reload
66
+ expect(notification.delivered).to eq(false)
67
+ end
68
+
69
+ it 'retries notification that fail due to a SocketError' do
70
+ expect(http).to receive(:request).and_raise(SocketError.new)
71
+ expect(notification.deliver_after).to be_nil
72
+ expect do
73
+ Rpush.push
74
+ notification.reload
75
+ end.to change(notification, :deliver_after).to(kind_of(Time))
76
+ end
77
+ end
@@ -21,7 +21,7 @@ RSpec.configure do |config|
21
21
  config.before(:each) do
22
22
  Modis.with_connection do |redis|
23
23
  redis.keys('rpush:*').each { |key| redis.del(key) }
24
- end if redis?
24
+ end if redis? && functional_example?(self.class.metadata)
25
25
 
26
26
  Rpush.config.logger = ::Logger.new(STDOUT) if functional_example?(self.class.metadata)
27
27
  end
data/spec/spec_helper.rb CHANGED
@@ -13,6 +13,7 @@ if !ENV['CI'] || (ENV['CI'] && ENV['QUALITY'] == 'true')
13
13
  end
14
14
  end
15
15
 
16
+ require 'debug'
16
17
  require 'timecop'
17
18
  require 'activerecord-jdbc-adapter' if defined? JRUBY_VERSION
18
19
 
@@ -46,7 +47,7 @@ path = File.join(File.dirname(__FILE__), 'support')
46
47
  TEST_CERT = File.read(File.join(path, 'cert_without_password.pem'))
47
48
  TEST_CERT_WITH_PASSWORD = File.read(File.join(path, 'cert_with_password.pem'))
48
49
 
49
- VAPID_KEYPAIR = Webpush.generate_key.to_hash.merge(subject: 'rpush-test@example.org').to_json
50
+ VAPID_KEYPAIR = WebPush.generate_key.to_hash.merge(subject: 'rpush-test@example.org').to_json
50
51
 
51
52
  def after_example_cleanup
52
53
  Rpush.logger = nil
@@ -43,6 +43,7 @@ require 'generators/templates/rpush_3_3_1_updates'
43
43
  require 'generators/templates/rpush_4_1_0_updates'
44
44
  require 'generators/templates/rpush_4_1_1_updates'
45
45
  require 'generators/templates/rpush_4_2_0_updates'
46
+ require 'generators/templates/rpush_7_1_0_updates'
46
47
 
47
48
  migrations = [
48
49
  AddRpush,
@@ -60,7 +61,8 @@ migrations = [
60
61
  Rpush331Updates,
61
62
  Rpush410Updates,
62
63
  Rpush411Updates,
63
- Rpush420Updates
64
+ Rpush420Updates,
65
+ Rpush710Updates
64
66
  ]
65
67
 
66
68
  unless ENV['CI']
@@ -0,0 +1,6 @@
1
+ require 'unit_spec_helper'
2
+
3
+ describe Rpush::Client::ActiveRecord::Fcm::App do
4
+ it_behaves_like 'Rpush::Client::Fcm::App'
5
+ it_behaves_like 'Rpush::Client::ActiveRecord::App'
6
+ end if active_record?
@@ -0,0 +1,10 @@
1
+ require 'unit_spec_helper'
2
+
3
+ describe Rpush::Client::ActiveRecord::Fcm::Notification do
4
+ it_behaves_like 'Rpush::Client::Fcm::Notification'
5
+ it_behaves_like 'Rpush::Client::ActiveRecord::Notification'
6
+
7
+ subject(:notification) { described_class.new }
8
+ let(:app) { Rpush::Fcm::App.create!(name: 'test', auth_key: 'abc') }
9
+
10
+ end if active_record?
@@ -0,0 +1,5 @@
1
+ require 'unit_spec_helper'
2
+
3
+ describe Rpush::Client::Redis::Fcm::App do
4
+ it_behaves_like 'Rpush::Client::Fcm::App'
5
+ end if redis?
@@ -0,0 +1,5 @@
1
+ require 'unit_spec_helper'
2
+
3
+ describe Rpush::Client::Redis::Fcm::Notification do
4
+ it_behaves_like 'Rpush::Client::Fcm::Notification'
5
+ end if redis?
@@ -165,21 +165,6 @@ 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
-
183
168
  describe 'url-args' do
184
169
  it 'includes url-args in the payload' do
185
170
  notification.url_args = ['url-arg-1']
@@ -0,0 +1,4 @@
1
+ require 'unit_spec_helper'
2
+
3
+ shared_examples 'Rpush::Client::Fcm::App' do
4
+ end
@@ -0,0 +1,92 @@
1
+ require 'unit_spec_helper'
2
+
3
+ shared_examples 'Rpush::Client::Fcm::Notification' do
4
+ let(:app) { Rpush::Fcm::App.create!(name: 'test', auth_key: 'abc') }
5
+ let(:notification) { described_class.new }
6
+
7
+ it "has a 'data' payload limit of 4096 bytes" do
8
+ notification.app = app
9
+ notification.device_token = "valid"
10
+ notification.data = { key: "a" * 4096 }
11
+ expect(notification.valid?).to be_falsey
12
+ expect(notification.errors[:base]).to eq ["Notification payload data cannot be larger than 4096 bytes."]
13
+ end
14
+
15
+ it "validates notification keys" do
16
+ notification.app = app
17
+ notification.device_token = "valid"
18
+ notification.notification = { "title" => "valid", "body" => "valid", "color" => "valid for android", "garbage" => "invalid" }
19
+ expect(notification.valid?).to be_falsey
20
+ expect(notification.errors[:notification]).to eq ["contains invalid keys: garbage"]
21
+ end
22
+
23
+ it "allows notifications with either symbol keys or string keys" do
24
+ notification.app = app
25
+ notification.notification = { "title" => "title", body: "body" }
26
+ expect(notification.as_json['message']['notification']).to eq({"title"=>"title", "body"=>"body"})
27
+ end
28
+
29
+ it "moves notification keys to the correcdt location" do
30
+ notification.app = app
31
+ notification.device_token = "valid"
32
+ notification.notification = { "title" => "valid", "body" => "valid", "color" => "valid for android" }
33
+ expect(notification.valid?).to be_truthy
34
+ expect(notification.as_json['message']['notification']).to eq("title"=>"valid", "body"=>"valid")
35
+ expect(notification.as_json['message']['android']['notification']['color']).to eq('valid for android')
36
+ end
37
+
38
+ it 'validates expiry is present if collapse_key is set' do
39
+ notification.collapse_key = 'test'
40
+ notification.expiry = nil
41
+ expect(notification.valid?).to be_falsey
42
+ expect(notification.errors[:expiry]).to eq ['must be set when using a collapse_key']
43
+ end
44
+
45
+ it 'includes time_to_live in the payload' do
46
+ notification.expiry = 100
47
+ expect(notification.as_json['message']['android']['ttl']).to eq '100s'
48
+ end
49
+
50
+ it 'includes content_available in the payload' do
51
+ notification.content_available = true
52
+ expect(notification.as_json["message"]["apns"]["payload"]["aps"]["content-available"]).to eq 1
53
+ end
54
+
55
+ it 'sets the priority to high when set to high' do
56
+ notification.notification = { title: "Title" }
57
+ notification.priority = 'high'
58
+ expect(notification.as_json['message']['android']['priority']).to eq 'high'
59
+ expect(notification.as_json['message']['android']['notification']['notification_priority']).to eq 'PRIORITY_MAX'
60
+ # TODO Add notification_priority
61
+ end
62
+
63
+ it 'sets the priority to normal when set to normal' do
64
+ notification.notification = { title: "Title" }
65
+ notification.priority = 'normal'
66
+ expect(notification.as_json['message']['android']['priority']).to eq 'normal'
67
+ expect(notification.as_json['message']['android']['notification']['notification_priority']).to eq 'PRIORITY_DEFAULT'
68
+ # TODO Add notification_priority
69
+ end
70
+
71
+ it 'validates the priority is either "normal" or "high"' do
72
+ notification.priority = 'invalid'
73
+ expect(notification.errors[:priority]).to eq ['must be one of either "normal" or "high"']
74
+ end
75
+
76
+ it 'excludes the priority if it is not defined' do
77
+ expect(notification.as_json['message']['android']).not_to have_key 'priority'
78
+ end
79
+
80
+ it 'includes the notification payload if defined' do
81
+ notification.notification = { key: 'any key is allowed' }
82
+ expect(notification.as_json['message']).to have_key 'notification'
83
+ end
84
+
85
+ it 'excludes the notification payload if undefined' do
86
+ expect(notification.as_json['message']).not_to have_key 'notification'
87
+ end
88
+
89
+ it 'fails when trying to set the dry_run option' do
90
+ expect { notification.dry_run = true }.to raise_error(ArgumentError)
91
+ end
92
+ end
@@ -41,6 +41,6 @@ describe Rpush::Configuration do
41
41
  it 'delegate redis_options to Modis' do
42
42
  Rpush.config.client = :redis
43
43
  Rpush.config.redis_options = { hi: :mom }
44
- expect(Modis.redis_options).to eq(hi: :mom)
44
+ expect(Modis.redis_options[:default]).to eq(hi: :mom)
45
45
  end
46
46
  end
@@ -42,7 +42,7 @@ describe Rpush::Daemon::Apnsp8::Delivery do
42
42
  loop do
43
43
  break unless thread.alive?
44
44
 
45
- if Time.now - start > 0.5
45
+ if Time.now - start > 1
46
46
  thread.kill
47
47
  fail 'Stuck in an infinite loop'
48
48
  end