rpush 7.0.1 → 8.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +28 -4
- data/README.md +38 -1
- data/lib/generators/rpush_migration_generator.rb +1 -0
- data/lib/generators/templates/rpush.rb +17 -0
- data/lib/generators/templates/rpush_7_1_0_updates.rb +12 -0
- data/lib/rpush/client/active_model/apns/notification.rb +0 -4
- data/lib/rpush/client/active_model/fcm/app.rb +20 -0
- data/lib/rpush/client/active_model/fcm/expiry_collapse_key_mutual_inclusion_validator.rb +14 -0
- data/lib/rpush/client/active_model/fcm/notification.rb +129 -0
- data/lib/rpush/client/active_model/fcm/notification_keys_in_allowed_list_validator.rb +20 -0
- data/lib/rpush/client/active_model.rb +5 -0
- data/lib/rpush/client/active_record/fcm/app.rb +11 -0
- data/lib/rpush/client/active_record/fcm/notification.rb +11 -0
- data/lib/rpush/client/active_record.rb +3 -0
- data/lib/rpush/client/redis/app.rb +2 -0
- data/lib/rpush/client/redis/fcm/app.rb +11 -0
- data/lib/rpush/client/redis/fcm/notification.rb +11 -0
- data/lib/rpush/client/redis.rb +3 -0
- data/lib/rpush/configuration.rb +1 -1
- data/lib/rpush/daemon/apns2/delivery.rb +0 -1
- data/lib/rpush/daemon/apnsp8/delivery.rb +0 -1
- data/lib/rpush/daemon/fcm/delivery.rb +162 -0
- data/lib/rpush/daemon/fcm.rb +9 -0
- data/lib/rpush/daemon/gcm/delivery.rb +1 -1
- data/lib/rpush/daemon/google_credential_cache.rb +41 -0
- data/lib/rpush/daemon/store/active_record.rb +15 -0
- data/lib/rpush/daemon/store/interface.rb +2 -2
- data/lib/rpush/daemon/store/redis.rb +13 -0
- data/lib/rpush/daemon/webpush/delivery.rb +2 -2
- data/lib/rpush/daemon.rb +4 -0
- data/lib/rpush/reflection_collection.rb +3 -2
- data/lib/rpush/version.rb +2 -2
- data/lib/rpush.rb +1 -0
- data/spec/functional/apns2_spec.rb +2 -6
- data/spec/functional/fcm_priority_spec.rb +46 -0
- data/spec/functional/fcm_spec.rb +77 -0
- data/spec/functional_spec_helper.rb +1 -1
- data/spec/spec_helper.rb +2 -1
- data/spec/support/active_record_setup.rb +3 -1
- data/spec/unit/client/active_record/fcm/app_spec.rb +6 -0
- data/spec/unit/client/active_record/fcm/notification_spec.rb +10 -0
- data/spec/unit/client/redis/fcm/app_spec.rb +5 -0
- data/spec/unit/client/redis/fcm/notification_spec.rb +5 -0
- data/spec/unit/client/shared/apns/notification.rb +0 -15
- data/spec/unit/client/shared/fcm/app.rb +4 -0
- data/spec/unit/client/shared/fcm/notification.rb +92 -0
- data/spec/unit/configuration_spec.rb +1 -1
- data/spec/unit/daemon/apnsp8/delivery_spec.rb +1 -1
- data/spec/unit/daemon/fcm/delivery_spec.rb +127 -0
- data/spec/unit/daemon/service_config_methods_spec.rb +1 -1
- data/spec/unit/daemon/tcp_connection_spec.rb +8 -7
- data/spec/unit/daemon/wns/delivery_spec.rb +1 -1
- data/spec/unit/logger_spec.rb +1 -1
- data/spec/unit_spec_helper.rb +1 -1
- metadata +81 -17
@@ -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
|
-
:
|
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 "
|
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 < ::
|
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,
|
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
data/lib/rpush.rb
CHANGED
@@ -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 =
|
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,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?
|
@@ -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,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
|