rpush 4.2.0 → 7.0.1

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 (154) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +307 -163
  3. data/README.md +105 -19
  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 +5 -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/cli.rb +1 -1
  32. data/lib/rpush/client/active_model/adm/data_validator.rb +1 -1
  33. data/lib/rpush/client/active_model/apns/app.rb +1 -17
  34. data/lib/rpush/client/active_model/apns/device_token_format_validator.rb +2 -2
  35. data/lib/rpush/client/active_model/apns/notification.rb +13 -1
  36. data/lib/rpush/client/active_model/apns/notification_payload_size_validator.rb +15 -0
  37. data/lib/rpush/client/active_model/apns2/app.rb +7 -1
  38. data/lib/rpush/client/active_model/apns2/notification.rb +14 -0
  39. data/lib/rpush/client/active_model/certificate_private_key_validator.rb +19 -0
  40. data/lib/rpush/client/active_model/gcm/expiry_collapse_key_mutual_inclusion_validator.rb +1 -1
  41. data/lib/rpush/client/active_model/gcm/notification.rb +2 -2
  42. data/lib/rpush/client/active_model/payload_data_size_validator.rb +1 -1
  43. data/lib/rpush/client/active_model/registration_ids_count_validator.rb +1 -1
  44. data/lib/rpush/client/active_model/webpush/app.rb +41 -0
  45. data/lib/rpush/client/active_model/webpush/notification.rb +66 -0
  46. data/lib/rpush/client/active_model.rb +5 -1
  47. data/lib/rpush/client/active_record/apns/active_record_serializable_notification.rb +65 -0
  48. data/lib/rpush/client/active_record/apns/notification.rb +1 -57
  49. data/lib/rpush/client/active_record/apns2/notification.rb +4 -1
  50. data/lib/rpush/client/active_record/apnsp8/notification.rb +1 -0
  51. data/lib/rpush/client/active_record/webpush/app.rb +11 -0
  52. data/lib/rpush/client/active_record/webpush/notification.rb +12 -0
  53. data/lib/rpush/client/active_record.rb +4 -0
  54. data/lib/rpush/client/redis/apns2/notification.rb +1 -0
  55. data/lib/rpush/client/redis/apnsp8/notification.rb +2 -0
  56. data/lib/rpush/client/redis/pushy/notification.rb +0 -1
  57. data/lib/rpush/client/redis/webpush/app.rb +15 -0
  58. data/lib/rpush/client/redis/webpush/notification.rb +15 -0
  59. data/lib/rpush/client/redis.rb +3 -0
  60. data/lib/rpush/configuration.rb +3 -2
  61. data/lib/rpush/daemon/apns/feedback_receiver.rb +1 -1
  62. data/lib/rpush/daemon/apns2/delivery.rb +14 -2
  63. data/lib/rpush/daemon/apnsp8/delivery.rb +14 -3
  64. data/lib/rpush/daemon/app_runner.rb +1 -1
  65. data/lib/rpush/daemon/batch.rb +12 -5
  66. data/lib/rpush/daemon/delivery.rb +1 -2
  67. data/lib/rpush/daemon/store/active_record/reconnectable.rb +1 -1
  68. data/lib/rpush/daemon/store/active_record.rb +11 -7
  69. data/lib/rpush/daemon/store/redis.rb +6 -6
  70. data/lib/rpush/daemon/string_helpers.rb +1 -1
  71. data/lib/rpush/daemon/webpush/delivery.rb +114 -0
  72. data/lib/rpush/daemon/webpush.rb +10 -0
  73. data/lib/rpush/daemon.rb +4 -1
  74. data/lib/rpush/logger.rb +2 -1
  75. data/lib/rpush/version.rb +3 -3
  76. data/spec/functional/apns2_spec.rb +99 -2
  77. data/spec/functional/gcm_priority_spec.rb +40 -0
  78. data/spec/functional/retry_spec.rb +1 -1
  79. data/spec/functional/webpush_spec.rb +31 -0
  80. data/spec/spec_helper.rb +3 -1
  81. data/spec/support/active_record_setup.rb +4 -3
  82. data/spec/support/config/database.yml +4 -4
  83. data/spec/support/simplecov_helper.rb +2 -2
  84. data/spec/unit/client/active_record/adm/app_spec.rb +2 -54
  85. data/spec/unit/client/active_record/adm/notification_spec.rb +2 -39
  86. data/spec/unit/client/active_record/apns/app_spec.rb +3 -26
  87. data/spec/unit/client/active_record/apns/feedback_spec.rb +1 -5
  88. data/spec/unit/client/active_record/apns/notification_spec.rb +29 -293
  89. data/spec/unit/client/active_record/apns2/app_spec.rb +5 -0
  90. data/spec/unit/client/active_record/apns2/notification_spec.rb +65 -0
  91. data/spec/unit/client/active_record/apnsp8/notification_spec.rb +28 -0
  92. data/spec/unit/client/active_record/app_spec.rb +1 -26
  93. data/spec/unit/client/active_record/gcm/app_spec.rb +3 -1
  94. data/spec/unit/client/active_record/gcm/notification_spec.rb +6 -88
  95. data/spec/unit/client/active_record/notification_spec.rb +3 -11
  96. data/spec/unit/client/active_record/pushy/app_spec.rb +2 -13
  97. data/spec/unit/client/active_record/pushy/notification_spec.rb +2 -55
  98. data/spec/unit/client/active_record/shared/app.rb +14 -0
  99. data/spec/unit/{notification_shared.rb → client/active_record/shared/notification.rb} +12 -7
  100. data/spec/unit/client/active_record/webpush/app_spec.rb +6 -0
  101. data/spec/unit/client/active_record/webpush/notification_spec.rb +6 -0
  102. data/spec/unit/client/active_record/wns/badge_notification_spec.rb +1 -11
  103. data/spec/unit/client/active_record/wns/raw_notification_spec.rb +3 -12
  104. data/spec/unit/client/active_record/wpns/app_spec.rb +3 -1
  105. data/spec/unit/client/active_record/wpns/notification_spec.rb +2 -17
  106. data/spec/unit/client/redis/adm/app_spec.rb +5 -0
  107. data/spec/unit/client/redis/adm/notification_spec.rb +5 -0
  108. data/spec/unit/client/redis/apns/app_spec.rb +5 -0
  109. data/spec/unit/client/redis/apns/feedback_spec.rb +5 -0
  110. data/spec/unit/client/redis/apns/notification_spec.rb +50 -0
  111. data/spec/unit/client/redis/apns2/app_spec.rb +4 -0
  112. data/spec/unit/client/redis/apns2/notification_spec.rb +50 -0
  113. data/spec/unit/client/redis/apnsp8/notification_spec.rb +29 -0
  114. data/spec/unit/client/redis/app_spec.rb +5 -0
  115. data/spec/unit/client/redis/gcm/app_spec.rb +5 -0
  116. data/spec/unit/client/redis/gcm/notification_spec.rb +5 -0
  117. data/spec/unit/client/redis/notification_spec.rb +5 -0
  118. data/spec/unit/client/redis/pushy/app_spec.rb +5 -0
  119. data/spec/unit/client/redis/pushy/notification_spec.rb +5 -0
  120. data/spec/unit/client/redis/webpush/app_spec.rb +5 -0
  121. data/spec/unit/client/redis/webpush/notification_spec.rb +5 -0
  122. data/spec/unit/client/redis/wns/badge_notification_spec.rb +5 -0
  123. data/spec/unit/client/redis/wns/raw_notification_spec.rb +22 -0
  124. data/spec/unit/client/redis/wpns/app_spec.rb +5 -0
  125. data/spec/unit/client/redis/wpns/notification_spec.rb +5 -0
  126. data/spec/unit/client/shared/adm/app.rb +51 -0
  127. data/spec/unit/client/shared/adm/notification.rb +39 -0
  128. data/spec/unit/client/shared/apns/app.rb +29 -0
  129. data/spec/unit/client/shared/apns/feedback.rb +9 -0
  130. data/spec/unit/client/shared/apns/notification.rb +277 -0
  131. data/spec/unit/client/shared/app.rb +17 -0
  132. data/spec/unit/client/shared/gcm/app.rb +4 -0
  133. data/spec/unit/client/shared/gcm/notification.rb +77 -0
  134. data/spec/unit/client/shared/notification.rb +10 -0
  135. data/spec/unit/client/shared/pushy/app.rb +17 -0
  136. data/spec/unit/client/shared/pushy/notification.rb +55 -0
  137. data/spec/unit/client/shared/webpush/app.rb +33 -0
  138. data/spec/unit/client/shared/webpush/notification.rb +83 -0
  139. data/spec/unit/client/shared/wns/badge_notification.rb +15 -0
  140. data/spec/unit/client/shared/wns/raw_notification.rb +21 -0
  141. data/spec/unit/client/shared/wpns/app.rb +4 -0
  142. data/spec/unit/client/shared/wpns/notification.rb +18 -0
  143. data/spec/unit/daemon/apnsp8/delivery_spec.rb +53 -0
  144. data/spec/unit/daemon/batch_spec.rb +50 -2
  145. data/spec/unit/daemon/delivery_spec.rb +10 -0
  146. data/spec/unit/daemon/pushy/delivery_spec.rb +5 -3
  147. data/spec/unit/daemon/shared/store.rb +312 -0
  148. data/spec/unit/daemon/store/active_record/reconnectable_spec.rb +7 -7
  149. data/spec/unit/daemon/store/active_record_spec.rb +6 -287
  150. data/spec/unit/daemon/store/redis_spec.rb +2 -291
  151. data/spec/unit/daemon/webpush/delivery_spec.rb +144 -0
  152. data/spec/unit_spec_helper.rb +3 -0
  153. metadata +145 -18
  154. data/lib/rpush/client/active_model/apns/binary_notification_validator.rb +0 -16
@@ -1,329 +1,65 @@
1
- # encoding: US-ASCII
2
-
3
1
  require "unit_spec_helper"
4
- require 'unit/notification_shared.rb'
5
2
 
6
3
  describe Rpush::Client::ActiveRecord::Apns::Notification do
7
- it_should_behave_like 'an Notification subclass'
8
-
9
- let(:app) { Rpush::Client::ActiveRecord::Apns::App.create!(name: 'my_app', environment: 'development', certificate: TEST_CERT) }
10
- let(:notification_class) { Rpush::Client::ActiveRecord::Apns::Notification }
11
- let(:notification) { notification_class.new }
4
+ subject(:notification) { described_class.new }
12
5
 
13
- it "should validate the format of the device_token" do
14
- notification = Rpush::Client::ActiveRecord::Apns::Notification.new(device_token: "{$%^&*()}")
15
- expect(notification.valid?).to be_falsey
16
- expect(notification.errors[:device_token].include?("is invalid")).to be_truthy
17
- end
6
+ it_behaves_like 'Rpush::Client::Apns::Notification'
7
+ it_behaves_like 'Rpush::Client::ActiveRecord::Notification'
18
8
 
19
9
  it "should validate the length of the binary conversion of the notification" do
10
+ notification = described_class.new
11
+ notification.app = Rpush::Apns2::App.create(name: 'test', environment: 'development', certificate: TEST_CERT)
20
12
  notification.device_token = "a" * 108
21
- notification.alert = "way too long!" * 200
22
- expect(notification.valid?).to be_falsey
23
- expect(notification.errors[:base].include?("APN notification cannot be larger than 2048 bytes. Try condensing your alert and device attributes.")).to be_truthy
24
- end
13
+ notification.alert = ""
25
14
 
26
- it "should store long alerts" do
27
- notification.app = app
28
- notification.device_token = "a" * 108
29
- notification.alert = "*" * 300
15
+ notification.alert << "a" until notification.payload.bytesize == 2048
30
16
  expect(notification.valid?).to be_truthy
17
+ expect(notification.errors[:base]).to be_empty
31
18
 
32
- notification.save!
33
- notification.reload
34
- expect(notification.alert).to eq("*" * 300)
35
- end
36
-
37
- it "should default the sound to nil" do
38
- expect(notification.sound).to be_nil
39
- end
40
-
41
- it "should default the expiry to 1 day" do
42
- expect(notification.expiry).to eq 1.day.to_i
43
- end
44
- end if active_record?
45
-
46
- describe Rpush::Client::ActiveRecord::Apns::Notification, "when assigning the device token" do
47
- it "should strip spaces from the given string" do
48
- notification = Rpush::Client::ActiveRecord::Apns::Notification.new(device_token: "o m g")
49
- expect(notification.device_token).to eq "omg"
50
- end
51
-
52
- it "should strip chevrons from the given string" do
53
- notification = Rpush::Client::ActiveRecord::Apns::Notification.new(device_token: "<omg>")
54
- expect(notification.device_token).to eq "omg"
55
- end
56
- end if active_record?
57
-
58
- describe Rpush::Client::ActiveRecord::Apns::Notification, "as_json" do
59
- it "should include the alert if present" do
60
- notification = Rpush::Client::ActiveRecord::Apns::Notification.new(alert: "hi mom")
61
- expect(notification.as_json["aps"]["alert"]).to eq "hi mom"
62
- end
63
-
64
- it "should not include the alert key if the alert is not present" do
65
- notification = Rpush::Client::ActiveRecord::Apns::Notification.new(alert: nil)
66
- expect(notification.as_json["aps"].key?("alert")).to be_falsey
67
- end
68
-
69
- it "should encode the alert as JSON if it is a Hash" do
70
- notification = Rpush::Client::ActiveRecord::Apns::Notification.new(alert: { 'body' => "hi mom", 'alert-loc-key' => "View" })
71
- expect(notification.as_json["aps"]["alert"]).to eq('body' => "hi mom", 'alert-loc-key' => "View")
72
- end
73
-
74
- it "should include the badge if present" do
75
- notification = Rpush::Client::ActiveRecord::Apns::Notification.new(badge: 6)
76
- expect(notification.as_json["aps"]["badge"]).to eq 6
77
- end
78
-
79
- it "should not include the badge key if the badge is not present" do
80
- notification = Rpush::Client::ActiveRecord::Apns::Notification.new(badge: nil)
81
- expect(notification.as_json["aps"].key?("badge")).to be_falsey
82
- end
83
-
84
- it "should include the sound if present" do
85
- notification = Rpush::Client::ActiveRecord::Apns::Notification.new(sound: "my_sound.aiff")
86
- expect(notification.as_json["aps"]["sound"]).to eq "my_sound.aiff"
87
- end
88
-
89
- it "should not include the sound key if the sound is not present" do
90
- notification = Rpush::Client::ActiveRecord::Apns::Notification.new(sound: nil)
91
- expect(notification.as_json["aps"].key?("sound")).to be_falsey
92
- end
93
-
94
- it "should encode the sound as JSON if it is a Hash" do
95
- notification = Rpush::Client::ActiveRecord::Apns::Notification.new(sound: { 'name' => "my_sound.aiff", 'critical' => 1, 'volume' => 0.5 })
96
- expect(notification.as_json["aps"]["sound"]).to eq('name' => "my_sound.aiff", 'critical' => 1, 'volume' => 0.5)
97
- end
98
-
99
- it "should include attributes for the device" do
100
- notification = Rpush::Client::ActiveRecord::Apns::Notification.new
101
- notification.data = { omg: :lol, wtf: :dunno }
102
- expect(notification.as_json["omg"]).to eq "lol"
103
- expect(notification.as_json["wtf"]).to eq "dunno"
104
- end
105
-
106
- it "should allow attributes to include a hash" do
107
- notification = Rpush::Client::ActiveRecord::Apns::Notification.new
108
- notification.data = { omg: { ilike: :hashes } }
109
- expect(notification.as_json["omg"]["ilike"]).to eq "hashes"
110
- end
111
- end if active_record?
112
-
113
- describe Rpush::Client::ActiveRecord::Apns::Notification, 'MDM' do
114
- let(:magic) { 'abc123' }
115
- let(:notification) { Rpush::Client::ActiveRecord::Apns::Notification.new }
116
-
117
- before do
118
- notification.device_token = "a" * 108
119
- notification.id = 1234
120
- end
121
-
122
- it 'includes the mdm magic in the payload' do
123
- notification.mdm = magic
124
- expect(notification.as_json).to eq('mdm' => magic)
125
- end
126
-
127
- it 'does not include aps attribute' do
128
- notification.alert = "i'm doomed"
129
- notification.mdm = magic
130
- expect(notification.as_json.key?('aps')).to be_falsey
131
- end
132
-
133
- it 'can be converted to binary' do
134
- notification.mdm = magic
135
- expect(notification.to_binary).to be_present
19
+ notification.alert << "a"
20
+ expect(notification.valid?).to be_falsey
21
+ expect(notification.errors[:base].include?("APN notification cannot be larger than 2048 bytes. Try condensing your alert and device attributes.")).to be_truthy
136
22
  end
137
- end if active_record?
138
23
 
139
- describe Rpush::Client::ActiveRecord::Apns::Notification, 'mutable-content' do
140
- let(:notification) { Rpush::Client::ActiveRecord::Apns::Notification.new }
141
-
142
- it 'includes mutable-content in the payload' do
143
- notification.mutable_content = true
144
- expect(notification.as_json['aps']['mutable-content']).to eq 1
145
- end
24
+ describe "multi_json usage" do
25
+ describe "alert" do
26
+ subject(:notification) { described_class.new(alert: { a: 1 }, alert_is_json: true) }
146
27
 
147
- it 'does not include content-available in the payload if not set' do
148
- expect(notification.as_json['aps'].key?('mutable-content')).to be_falsey
149
- end
28
+ it "should call MultiJson.load when multi_json version is 1.3.0" do
29
+ allow(Gem).to receive(:loaded_specs).and_return('multi_json' => Gem::Specification.new('multi_json', '1.3.0'))
30
+ expect(MultiJson).to receive(:load).with(any_args)
31
+ notification.alert
32
+ end
150
33
 
151
- it 'does not include mutable-content as a non-aps attribute' do
152
- notification.mutable_content = true
153
- expect(notification.as_json.key?('mutable-content')).to be_falsey
34
+ it "should call MultiJson.decode when multi_json version is 1.2.9" do
35
+ allow(Gem).to receive(:loaded_specs).and_return('multi_json' => Gem::Specification.new('multi_json', '1.2.9'))
36
+ expect(MultiJson).to receive(:decode).with(any_args)
37
+ notification.alert
38
+ end
39
+ end
154
40
  end
155
41
 
156
- it 'does not overwrite existing attributes for the device' do
157
- notification.data = { hi: :mom }
158
- notification.mutable_content = true
159
- expect(notification.as_json['aps']['mutable-content']).to eq 1
160
- expect(notification.as_json['hi']).to eq 'mom'
42
+ it "should default the sound to nil" do
43
+ expect(notification.sound).to be_nil
161
44
  end
162
45
 
163
46
  it 'does not overwrite the mutable-content flag when setting attributes for the device' do
164
47
  notification.mutable_content = true
165
- notification.data = { hi: :mom }
48
+ notification.data = { 'hi' => 'mom' }
166
49
  expect(notification.as_json['aps']['mutable-content']).to eq 1
167
50
  expect(notification.as_json['hi']).to eq 'mom'
168
51
  end
169
- end if active_record?
170
-
171
- describe Rpush::Client::ActiveRecord::Apns::Notification, 'content-available' do
172
- let(:notification) { Rpush::Client::ActiveRecord::Apns::Notification.new }
173
-
174
- it 'includes content-available in the payload' do
175
- notification.content_available = true
176
- expect(notification.as_json['aps']['content-available']).to eq 1
177
- end
178
-
179
- it 'does not include content-available in the payload if not set' do
180
- expect(notification.as_json['aps'].key?('content-available')).to be_falsey
181
- end
182
-
183
- it 'does not include content-available as a non-aps attribute' do
184
- notification.content_available = true
185
- expect(notification.as_json.key?('content-available')).to be_falsey
186
- end
187
-
188
- it 'does not overwrite existing attributes for the device' do
189
- notification.data = { hi: :mom }
190
- notification.content_available = true
191
- expect(notification.as_json['aps']['content-available']).to eq 1
192
- expect(notification.as_json['hi']).to eq 'mom'
193
- end
194
52
 
195
53
  it 'does not overwrite the content-available flag when setting attributes for the device' do
196
54
  notification.content_available = true
197
- notification.data = { hi: :mom }
55
+ notification.data = { 'hi' => 'mom' }
198
56
  expect(notification.as_json['aps']['content-available']).to eq 1
199
57
  expect(notification.as_json['hi']).to eq 'mom'
200
58
  end
201
- end if active_record?
202
-
203
- describe Rpush::Client::ActiveRecord::Apns::Notification, 'url-args' do
204
- let(:notification) { Rpush::Client::ActiveRecord::Apns::Notification.new }
205
-
206
- it 'includes url-args in the payload' do
207
- notification.url_args = ['url-arg-1']
208
- expect(notification.as_json['aps']['url-args']).to eq ['url-arg-1']
209
- end
210
-
211
- it 'does not include url-args in the payload if not set' do
212
- expect(notification.as_json['aps'].key?('url-args')).to be_falsey
213
- end
214
- end if active_record?
215
-
216
- describe Rpush::Client::ActiveRecord::Apns::Notification, 'category' do
217
- let(:notification) { Rpush::Client::ActiveRecord::Apns::Notification.new }
218
-
219
- it 'includes category in the payload' do
220
- notification.category = 'INVITE_CATEGORY'
221
- expect(notification.as_json['aps']['category']).to eq 'INVITE_CATEGORY'
222
- end
223
-
224
- it 'does not include category in the payload if not set' do
225
- expect(notification.as_json['aps'].key?('category')).to be_falsey
226
- end
227
- end if active_record?
228
-
229
- describe Rpush::Client::ActiveRecord::Apns::Notification, 'to_binary' do
230
- let(:notification) { Rpush::Client::ActiveRecord::Apns::Notification.new }
231
-
232
- before do
233
- notification.device_token = "a" * 108
234
- notification.id = 1234
235
- end
236
-
237
- it 'uses APNS_PRIORITY_CONSERVE_POWER if content-available is the only key' do
238
- notification.alert = nil
239
- notification.badge = nil
240
- notification.sound = nil
241
- notification.content_available = true
242
- bytes = notification.to_binary.bytes.to_a[-4..-1]
243
- expect(bytes.first).to eq 5 # priority item ID
244
- expect(bytes.last).to eq Rpush::Client::ActiveRecord::Apns::Notification::APNS_PRIORITY_CONSERVE_POWER
245
- end
246
-
247
- it 'uses APNS_PRIORITY_IMMEDIATE if content-available is not the only key' do
248
- notification.alert = "New stuff!"
249
- notification.badge = nil
250
- notification.sound = nil
251
- notification.content_available = true
252
- bytes = notification.to_binary.bytes.to_a[-4..-1]
253
- expect(bytes.first).to eq 5 # priority item ID
254
- expect(bytes.last).to eq Rpush::Client::ActiveRecord::Apns::Notification::APNS_PRIORITY_IMMEDIATE
255
- end
256
-
257
- it "should correctly convert the notification to binary" do
258
- notification.sound = "1.aiff"
259
- notification.badge = 3
260
- notification.alert = "Don't panic Mr Mainwaring, don't panic!"
261
- notification.data = { hi: :mom }
262
- notification.expiry = 86_400 # 1 day
263
- notification.priority = Rpush::Client::ActiveRecord::Apns::Notification::APNS_PRIORITY_IMMEDIATE
264
- notification.app = Rpush::Client::ActiveRecord::Apns::App.new(name: 'my_app', environment: 'development', certificate: TEST_CERT)
265
- now = Time.now
266
- allow(Time).to receive_messages(now: now)
267
- expect(notification.to_binary).to eq "\x02\x00\x00\x00\xAF\x01\x00 \xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\x02\x00a{\"aps\":{\"alert\":\"Don't panic Mr Mainwaring, don't panic!\",\"badge\":3,\"sound\":\"1.aiff\"},\"hi\":\"mom\"}\x03\x00\x04\x00\x00\x04\xD2\x04\x00\x04#{[now.to_i + 86_400].pack('N')}\x05\x00\x01\n"
268
- end
269
- end if active_record?
270
-
271
- describe Rpush::Client::ActiveRecord::Apns::Notification, "bug #31" do
272
- it 'does not confuse a JSON looking string as JSON' do
273
- notification = Rpush::Client::ActiveRecord::Apns::Notification.new
274
- notification.alert = "{\"one\":2}"
275
- expect(notification.alert).to eq "{\"one\":2}"
276
- end
277
59
 
278
60
  it 'does confuse a JSON looking string as JSON if the alert_is_json attribute is not present' do
279
- notification = Rpush::Client::ActiveRecord::Apns::Notification.new
280
61
  allow(notification).to receive_messages(has_attribute?: false)
281
62
  notification.alert = "{\"one\":2}"
282
63
  expect(notification.alert).to eq('one' => 2)
283
64
  end
284
65
  end if active_record?
285
-
286
- describe Rpush::Client::ActiveRecord::Apns::Notification, "bug #35" do
287
- it "should limit payload size to 256 bytes but not the entire packet" do
288
- notification = Rpush::Client::ActiveRecord::Apns::Notification.new do |n|
289
- n.device_token = "a" * 108
290
- n.alert = "a" * 210
291
- n.app = Rpush::Client::ActiveRecord::Apns::App.create!(name: 'my_app', environment: 'development', certificate: TEST_CERT)
292
- end
293
-
294
- expect(notification.to_binary(for_validation: true).bytesize).to be > 256
295
- expect(notification.payload.bytesize).to be < 256
296
- expect(notification).to be_valid
297
- end
298
- end if active_record?
299
-
300
- describe Rpush::Client::ActiveRecord::Apns::Notification, "multi_json usage" do
301
- describe Rpush::Client::ActiveRecord::Apns::Notification, "alert" do
302
- it "should call MultiJson.load when multi_json version is 1.3.0" do
303
- notification = Rpush::Client::ActiveRecord::Apns::Notification.new(alert: { a: 1 }, alert_is_json: true)
304
- allow(Gem).to receive(:loaded_specs).and_return('multi_json' => Gem::Specification.new('multi_json', '1.3.0'))
305
- expect(MultiJson).to receive(:load).with(any_args)
306
- notification.alert
307
- end
308
-
309
- it "should call MultiJson.decode when multi_json version is 1.2.9" do
310
- notification = Rpush::Client::ActiveRecord::Apns::Notification.new(alert: { a: 1 }, alert_is_json: true)
311
- allow(Gem).to receive(:loaded_specs).and_return('multi_json' => Gem::Specification.new('multi_json', '1.2.9'))
312
- expect(MultiJson).to receive(:decode).with(any_args)
313
- notification.alert
314
- end
315
- end
316
- end if active_record?
317
-
318
- describe Rpush::Client::ActiveRecord::Apns::Notification, 'thread-id' do
319
- let(:notification) { Rpush::Client::ActiveRecord::Apns::Notification.new }
320
-
321
- it 'includes thread-id in the payload' do
322
- notification.thread_id = 'THREAD-ID'
323
- expect(notification.as_json['aps']['thread-id']).to eq 'THREAD-ID'
324
- end
325
-
326
- it 'does not include thread-id in the payload if not set' do
327
- expect(notification.as_json['aps']).to_not have_key('thread-id')
328
- end
329
- end if active_record?
@@ -0,0 +1,5 @@
1
+ require 'unit_spec_helper'
2
+
3
+ describe Rpush::Client::ActiveRecord::Apns2::App do
4
+ it_behaves_like 'Rpush::Client::Apns::App'
5
+ end if active_record?
@@ -0,0 +1,65 @@
1
+ require "unit_spec_helper"
2
+
3
+ describe Rpush::Client::ActiveRecord::Apns2::Notification do
4
+ subject(:notification) { described_class.new }
5
+
6
+ it_behaves_like 'Rpush::Client::Apns::Notification'
7
+ it_behaves_like 'Rpush::Client::ActiveRecord::Notification'
8
+
9
+ it "should validate the length of the binary conversion of the notification" do
10
+ notification = described_class.new
11
+ notification.app = Rpush::Apns2::App.create(name: 'test', environment: 'development', certificate: TEST_CERT)
12
+ notification.device_token = "a" * 108
13
+ notification.alert = ""
14
+
15
+ notification.alert << "a" until notification.payload.bytesize == 4096
16
+ expect(notification.valid?).to be_truthy
17
+ expect(notification.errors[:base]).to be_empty
18
+
19
+ notification.alert << "a"
20
+ expect(notification.valid?).to be_falsey
21
+ expect(notification.errors[:base].include?("APN notification cannot be larger than 4096 bytes. Try condensing your alert and device attributes.")).to be_truthy
22
+ end
23
+
24
+ describe "multi_json usage" do
25
+ describe "alert" do
26
+ subject(:notification) { described_class.new(alert: { a: 1 }, alert_is_json: true) }
27
+
28
+ it "should call MultiJson.load when multi_json version is 1.3.0" do
29
+ allow(Gem).to receive(:loaded_specs).and_return('multi_json' => Gem::Specification.new('multi_json', '1.3.0'))
30
+ expect(MultiJson).to receive(:load).with(any_args)
31
+ notification.alert
32
+ end
33
+
34
+ it "should call MultiJson.decode when multi_json version is 1.2.9" do
35
+ allow(Gem).to receive(:loaded_specs).and_return('multi_json' => Gem::Specification.new('multi_json', '1.2.9'))
36
+ expect(MultiJson).to receive(:decode).with(any_args)
37
+ notification.alert
38
+ end
39
+ end
40
+ end
41
+
42
+ it "should default the sound to nil" do
43
+ expect(notification.sound).to be_nil
44
+ end
45
+
46
+ it 'does not overwrite the mutable-content flag when setting attributes for the device' do
47
+ notification.mutable_content = true
48
+ notification.data = { 'hi' => 'mom' }
49
+ expect(notification.as_json['aps']['mutable-content']).to eq 1
50
+ expect(notification.as_json['hi']).to eq 'mom'
51
+ end
52
+
53
+ it 'does not overwrite the content-available flag when setting attributes for the device' do
54
+ notification.content_available = true
55
+ notification.data = { 'hi' => 'mom' }
56
+ expect(notification.as_json['aps']['content-available']).to eq 1
57
+ expect(notification.as_json['hi']).to eq 'mom'
58
+ end
59
+
60
+ it 'does confuse a JSON looking string as JSON if the alert_is_json attribute is not present' do
61
+ allow(notification).to receive_messages(has_attribute?: false)
62
+ notification.alert = "{\"one\":2}"
63
+ expect(notification.alert).to eq('one' => 2)
64
+ end
65
+ end if active_record?
@@ -0,0 +1,28 @@
1
+ require "unit_spec_helper"
2
+
3
+ describe Rpush::Client::ActiveRecord::Apnsp8::Notification do
4
+ subject(:notification) { described_class.new }
5
+
6
+ it_behaves_like 'Rpush::Client::Apns::Notification'
7
+ it_behaves_like 'Rpush::Client::ActiveRecord::Notification'
8
+
9
+ it "should validate the length of the binary conversion of the notification", :aggregate_failures do
10
+ notification = described_class.new
11
+ notification.app = Rpush::Apnsp8::App.create(apn_key: "1",
12
+ apn_key_id: "2",
13
+ name: 'test',
14
+ environment: 'development',
15
+ team_id: "3",
16
+ bundle_id: "4")
17
+ notification.device_token = "a" * 108
18
+ notification.alert = ""
19
+
20
+ notification.alert << "a" until notification.payload.bytesize == 4096
21
+ expect(notification.valid?).to be_truthy
22
+ expect(notification.errors[:base]).to be_empty
23
+
24
+ notification.alert << "a"
25
+ expect(notification.valid?).to be_falsey
26
+ expect(notification.errors[:base].include?("APN notification cannot be larger than 4096 bytes. Try condensing your alert and device attributes.")).to be_truthy
27
+ end
28
+ end if active_record?
@@ -1,30 +1,5 @@
1
1
  require 'unit_spec_helper'
2
2
 
3
3
  describe Rpush::Client::ActiveRecord::App do
4
- it 'validates the uniqueness of name within type and environment' do
5
- Rpush::Client::ActiveRecord::Apns::App.create!(name: 'test', environment: 'production', certificate: TEST_CERT)
6
- app = Rpush::Client::ActiveRecord::Apns::App.new(name: 'test', environment: 'production', certificate: TEST_CERT)
7
- expect(app.valid?).to eq(false)
8
- expect(app.errors[:name]).to eq ['has already been taken']
9
-
10
- app = Rpush::Client::ActiveRecord::Apns::App.new(name: 'test', environment: 'development', certificate: TEST_CERT)
11
- expect(app.valid?).to eq(true)
12
-
13
- app = Rpush::Client::ActiveRecord::Gcm::App.new(name: 'test', environment: 'production', auth_key: TEST_CERT)
14
- expect(app.valid?).to eq(true)
15
- end
16
-
17
- context 'validating certificates' do
18
- it 'rescues from certificate error' do
19
- app = Rpush::Client::ActiveRecord::Apns::App.new(name: 'test', environment: 'development', certificate: 'bad')
20
- expect { app.valid? }.not_to raise_error
21
- expect(app.valid?).to eq(false)
22
- end
23
-
24
- it 'raises other errors' do
25
- app = Rpush::Client::ActiveRecord::Apns::App.new(name: 'test', environment: 'development', certificate: 'bad')
26
- allow(OpenSSL::X509::Certificate).to receive(:new).and_raise(NameError, 'simulating no openssl')
27
- expect { app.valid? }.to raise_error(NameError)
28
- end
29
- end
4
+ it_behaves_like 'Rpush::Client::App'
30
5
  end if active_record?
@@ -1,4 +1,6 @@
1
1
  require 'unit_spec_helper'
2
2
 
3
3
  describe Rpush::Client::ActiveRecord::Gcm::App do
4
- end
4
+ it_behaves_like 'Rpush::Client::Gcm::App'
5
+ it_behaves_like 'Rpush::Client::ActiveRecord::App'
6
+ end if active_record?
@@ -1,96 +1,14 @@
1
1
  require 'unit_spec_helper'
2
- require 'unit/notification_shared.rb'
3
2
 
4
3
  describe Rpush::Client::ActiveRecord::Gcm::Notification do
5
- it_should_behave_like 'an Notification subclass'
4
+ it_behaves_like 'Rpush::Client::Gcm::Notification'
5
+ it_behaves_like 'Rpush::Client::ActiveRecord::Notification'
6
6
 
7
- let(:app) { Rpush::Client::ActiveRecord::Gcm::App.create!(name: 'test', auth_key: 'abc') }
8
- let(:notification_class) { Rpush::Client::ActiveRecord::Gcm::Notification }
9
- let(:notification) { notification_class.new }
7
+ subject(:notification) { described_class.new }
8
+ let(:app) { Rpush::Gcm::App.create!(name: 'test', auth_key: 'abc') }
10
9
 
11
- it "has a 'data' payload limit of 4096 bytes" do
12
- notification.data = { key: "a" * 4096 }
13
- expect(notification.valid?).to be_falsey
14
- expect(notification.errors[:base]).to eq ["Notification payload data cannot be larger than 4096 bytes."]
15
- end
16
-
17
- it 'limits the number of registration ids to 1000' do
18
- notification.registration_ids = ['a'] * (1000 + 1)
19
- expect(notification.valid?).to be_falsey
20
- expect(notification.errors[:base]).to eq ["Number of registration_ids cannot be larger than 1000."]
21
- end
22
-
23
- it 'validates expiry is present if collapse_key is set' do
24
- notification.collapse_key = 'test'
25
- notification.expiry = nil
26
- expect(notification.valid?).to be_falsey
27
- expect(notification.errors[:expiry]).to eq ['must be set when using a collapse_key']
28
- end
29
-
30
- it 'includes time_to_live in the payload' do
31
- notification.expiry = 100
32
- expect(notification.as_json['time_to_live']).to eq 100
33
- end
34
-
35
- it 'includes content_available in the payload' do
36
- notification.content_available = true
37
- expect(notification.as_json['content_available']).to eq true
38
- end
39
-
40
- it 'includes mutable_content in the payload' do
41
- notification.mutable_content = true
42
- expect(notification.as_json['mutable_content']).to eq true
43
- end
44
-
45
- it 'sets the priority to high when set to high' do
46
- notification.priority = 'high'
47
- expect(notification.as_json['priority']).to eq 'high'
48
- end
49
-
50
- it 'sets the priority to normal when set to normal' do
51
- notification.priority = 'normal'
52
- expect(notification.as_json['priority']).to eq 'normal'
53
- end
54
-
55
- it 'validates the priority is either "normal" or "high"' do
56
- notification.priority = 'invalid'
57
- expect(notification.errors[:priority]).to eq ['must be one of either "normal" or "high"']
58
- end
59
-
60
- it 'excludes the priority if it is not defined' do
61
- expect(notification.as_json).not_to have_key 'priority'
62
- end
63
-
64
- it 'includes the notification payload if defined' do
65
- notification.notification = { key: 'any key is allowed' }
66
- expect(notification.as_json).to have_key 'notification'
67
- end
68
-
69
- it 'excludes the notification payload if undefined' do
70
- expect(notification.as_json).not_to have_key 'notification'
71
- end
72
-
73
- it 'includes the dry_run payload if defined' do
74
- notification.dry_run = true
10
+ it 'accepts non-booleans as a truthy value' do
11
+ notification.dry_run = 'Not a boolean'
75
12
  expect(notification.as_json['dry_run']).to eq true
76
13
  end
77
-
78
- it 'excludes the dry_run payload if undefined' do
79
- expect(notification.as_json).not_to have_key 'dry_run'
80
- end
81
-
82
- # In Rails 4.2 this value casts to `false` and thus will not be included in
83
- # the payload. This changed to match Ruby's semantics, and will casts to
84
- # `true` in Rails 5 and above.
85
- if ActiveRecord.version <= Gem::Version.new('5')
86
- it 'accepts non-booleans as a falsey value' do
87
- notification.dry_run = 'Not a boolean'
88
- expect(notification.as_json).not_to have_key 'dry_run'
89
- end
90
- else
91
- it 'accepts non-booleans as a truthy value' do
92
- notification.dry_run = 'Not a boolean'
93
- expect(notification.as_json['dry_run']).to eq true
94
- end
95
- end
96
14
  end if active_record?
@@ -1,20 +1,12 @@
1
1
  require 'unit_spec_helper'
2
2
 
3
3
  describe Rpush::Client::ActiveRecord::Notification do
4
- let(:notification) { Rpush::Client::ActiveRecord::Notification.new }
4
+ it_behaves_like 'Rpush::Client::Notification'
5
5
 
6
- it 'allows assignment of many registration IDs' do
7
- notification.registration_ids = %w(a b)
8
- expect(notification.registration_ids).to eq %w(a b)
9
- end
10
-
11
- it 'allows assignment of a single registration ID' do
12
- notification.registration_ids = 'a'
13
- expect(notification.registration_ids).to eq ['a']
14
- end
6
+ subject(:notification) { described_class.new }
15
7
 
16
8
  it 'saves its parent App if required' do
17
- notification.app = Rpush::Client::ActiveRecord::App.new(name: "aname")
9
+ notification.app = Rpush::App.new(name: "aname")
18
10
  expect(notification.app).to be_valid
19
11
  expect(notification).to be_valid
20
12
  end
@@ -1,17 +1,6 @@
1
1
  require 'unit_spec_helper'
2
2
 
3
3
  describe Rpush::Client::ActiveRecord::Pushy::App do
4
- describe 'validates' do
5
- subject { described_class.new }
6
-
7
- it 'validates presence of name' do
8
- is_expected.not_to be_valid
9
- expect(subject.errors[:name]).to eq ["can't be blank"]
10
- end
11
-
12
- it 'validates presence of api_key' do
13
- is_expected.not_to be_valid
14
- expect(subject.errors[:api_key]).to eq ["can't be blank"]
15
- end
16
- end
4
+ it_behaves_like 'Rpush::Client::Pushy::App'
5
+ it_behaves_like 'Rpush::Client::ActiveRecord::App'
17
6
  end if active_record?