rpush 1.0.0-java → 2.0.0-java
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 +15 -0
- data/README.md +37 -22
- data/bin/rpush +13 -4
- data/lib/generators/rpush_generator.rb +2 -0
- data/lib/generators/templates/add_adm.rb +5 -5
- data/lib/generators/templates/add_alert_is_json_to_rapns_notifications.rb +1 -1
- data/lib/generators/templates/add_app_to_rapns.rb +2 -2
- data/lib/generators/templates/add_fail_after_to_rpush_notifications.rb +1 -1
- data/lib/generators/templates/add_gcm.rb +32 -32
- data/lib/generators/templates/add_rpush.rb +67 -67
- data/lib/generators/templates/add_wpns.rb +2 -2
- data/lib/generators/templates/create_rapns_apps.rb +5 -5
- data/lib/generators/templates/create_rapns_feedback.rb +2 -2
- data/lib/generators/templates/create_rapns_notifications.rb +15 -15
- data/lib/generators/templates/rpush.rb +28 -7
- data/lib/generators/templates/rpush_2_0_0_updates.rb +42 -0
- data/lib/rpush/client/active_model/adm/app.rb +23 -0
- data/lib/rpush/client/active_model/adm/data_validator.rb +14 -0
- data/lib/rpush/client/active_model/adm/notification.rb +28 -0
- data/lib/rpush/client/active_model/apns/app.rb +37 -0
- data/lib/rpush/client/active_model/apns/binary_notification_validator.rb +16 -0
- data/lib/rpush/client/active_model/apns/device_token_format_validator.rb +14 -0
- data/lib/rpush/client/active_model/apns/notification.rb +90 -0
- data/lib/rpush/client/active_model/gcm/app.rb +19 -0
- data/lib/rpush/client/active_model/gcm/expiry_collapse_key_mutual_inclusion_validator.rb +14 -0
- data/lib/rpush/client/active_model/gcm/notification.rb +31 -0
- data/lib/rpush/client/active_model/notification.rb +26 -0
- data/lib/rpush/client/active_model/payload_data_size_validator.rb +13 -0
- data/lib/rpush/client/active_model/registration_ids_count_validator.rb +13 -0
- data/lib/rpush/client/active_model/wpns/app.rb +13 -0
- data/lib/rpush/client/active_model/wpns/notification.rb +17 -0
- data/lib/rpush/client/active_model.rb +21 -0
- data/lib/rpush/client/active_record/adm/app.rb +11 -0
- data/lib/rpush/client/active_record/adm/notification.rb +11 -0
- data/lib/rpush/client/active_record/apns/app.rb +11 -0
- data/lib/rpush/client/active_record/apns/feedback.rb +22 -0
- data/lib/rpush/client/active_record/apns/notification.rb +46 -0
- data/lib/rpush/client/active_record/app.rb +17 -0
- data/lib/rpush/client/active_record/gcm/app.rb +11 -0
- data/lib/rpush/client/active_record/gcm/notification.rb +11 -0
- data/lib/rpush/client/active_record/notification.rb +38 -0
- data/lib/rpush/client/active_record/wpns/app.rb +11 -0
- data/lib/rpush/client/active_record/wpns/notification.rb +11 -0
- data/lib/rpush/client/active_record.rb +19 -0
- data/lib/rpush/client/redis/adm/app.rb +14 -0
- data/lib/rpush/client/redis/adm/notification.rb +11 -0
- data/lib/rpush/client/redis/apns/app.rb +11 -0
- data/lib/rpush/client/redis/apns/feedback.rb +20 -0
- data/lib/rpush/client/redis/apns/notification.rb +11 -0
- data/lib/rpush/client/redis/app.rb +24 -0
- data/lib/rpush/client/redis/gcm/app.rb +11 -0
- data/lib/rpush/client/redis/gcm/notification.rb +11 -0
- data/lib/rpush/client/redis/notification.rb +68 -0
- data/lib/rpush/client/redis/wpns/app.rb +11 -0
- data/lib/rpush/client/redis/wpns/notification.rb +11 -0
- data/lib/rpush/client/redis.rb +35 -0
- data/lib/rpush/configuration.rb +27 -6
- data/lib/rpush/daemon/adm/delivery.rb +56 -55
- data/lib/rpush/daemon/apns/delivery.rb +20 -44
- data/lib/rpush/daemon/apns/feedback_receiver.rb +11 -8
- data/lib/rpush/daemon/apns.rb +6 -5
- data/lib/rpush/daemon/app_runner.rb +103 -99
- data/lib/rpush/daemon/batch.rb +54 -40
- data/lib/rpush/daemon/delivery.rb +13 -3
- data/lib/rpush/daemon/delivery_error.rb +10 -2
- data/lib/rpush/daemon/dispatcher/apns_tcp.rb +114 -0
- data/lib/rpush/daemon/dispatcher/http.rb +3 -3
- data/lib/rpush/daemon/dispatcher/tcp.rb +3 -3
- data/lib/rpush/daemon/dispatcher_loop.rb +37 -23
- data/lib/rpush/daemon/errors.rb +18 -0
- data/lib/rpush/daemon/feeder.rb +28 -39
- data/lib/rpush/daemon/gcm/delivery.rb +19 -20
- data/lib/rpush/daemon/interruptible_sleep.rb +26 -45
- data/lib/rpush/daemon/loggable.rb +2 -4
- data/lib/rpush/daemon/proc_title.rb +16 -0
- data/lib/rpush/daemon/queue_payload.rb +12 -0
- data/lib/rpush/daemon/reflectable.rb +3 -5
- data/lib/rpush/daemon/retry_header_parser.rb +6 -6
- data/lib/rpush/daemon/retryable_error.rb +2 -0
- data/lib/rpush/daemon/ring_buffer.rb +16 -0
- data/lib/rpush/daemon/service_config_methods.rb +23 -7
- data/lib/rpush/daemon/signal_handler.rb +56 -0
- data/lib/rpush/daemon/store/active_record/reconnectable.rb +21 -17
- data/lib/rpush/daemon/store/active_record.rb +71 -38
- data/lib/rpush/daemon/store/interface.rb +19 -0
- data/lib/rpush/daemon/store/redis.rb +149 -0
- data/lib/rpush/daemon/string_helpers.rb +15 -0
- data/lib/rpush/daemon/synchronizer.rb +60 -0
- data/lib/rpush/daemon/tcp_connection.rb +6 -11
- data/lib/rpush/daemon/wpns/delivery.rb +21 -30
- data/lib/rpush/daemon.rb +40 -60
- data/lib/rpush/deprecatable.rb +4 -3
- data/lib/rpush/deprecation.rb +7 -10
- data/lib/rpush/embed.rb +8 -3
- data/lib/rpush/logger.rb +11 -15
- data/lib/rpush/push.rb +1 -2
- data/lib/rpush/reflection.rb +8 -12
- data/lib/rpush/version.rb +1 -1
- data/lib/rpush.rb +5 -29
- data/lib/tasks/quality.rake +35 -0
- data/lib/tasks/test.rake +1 -5
- data/spec/.rubocop.yml +4 -0
- data/spec/functional/adm_spec.rb +3 -6
- data/spec/functional/apns_spec.rb +117 -24
- data/spec/functional/embed_spec.rb +20 -20
- data/spec/functional/gcm_spec.rb +4 -7
- data/spec/functional/new_app_spec.rb +59 -0
- data/spec/functional/retry_spec.rb +46 -0
- data/spec/functional/synchronization_spec.rb +68 -0
- data/spec/functional/wpns_spec.rb +3 -6
- data/spec/functional_spec_helper.rb +26 -0
- data/spec/integration/rpush_spec.rb +13 -0
- data/spec/integration/support/gcm_success_response.json +1 -0
- data/spec/spec_helper.rb +60 -0
- data/spec/support/active_record_setup.rb +48 -0
- data/{config → spec/support/config}/database.yml +0 -0
- data/spec/support/install.sh +43 -7
- data/spec/support/simplecov_helper.rb +9 -5
- data/spec/support/simplecov_quality_formatter.rb +10 -6
- data/spec/unit/apns_feedback_spec.rb +3 -3
- data/spec/unit/{adm → client/active_record/adm}/app_spec.rb +3 -3
- data/spec/unit/{adm → client/active_record/adm}/notification_spec.rb +5 -7
- data/spec/unit/client/active_record/apns/app_spec.rb +29 -0
- data/spec/unit/client/active_record/apns/feedback_spec.rb +9 -0
- data/spec/unit/client/active_record/apns/notification_spec.rb +231 -0
- data/spec/unit/client/active_record/app_spec.rb +30 -0
- data/spec/unit/client/active_record/gcm/app_spec.rb +4 -0
- data/spec/unit/{gcm → client/active_record/gcm}/notification_spec.rb +5 -7
- data/spec/unit/client/active_record/notification_spec.rb +21 -0
- data/spec/unit/client/active_record/wpns/app_spec.rb +4 -0
- data/spec/unit/client/active_record/wpns/notification_spec.rb +21 -0
- data/spec/unit/configuration_spec.rb +12 -5
- data/spec/unit/daemon/adm/delivery_spec.rb +66 -55
- data/spec/unit/daemon/apns/certificate_expired_error_spec.rb +3 -3
- data/spec/unit/daemon/apns/delivery_spec.rb +90 -83
- data/spec/unit/daemon/apns/feedback_receiver_spec.rb +22 -17
- data/spec/unit/daemon/app_runner_spec.rb +78 -186
- data/spec/unit/daemon/batch_spec.rb +52 -115
- data/spec/unit/daemon/delivery_spec.rb +15 -1
- data/spec/unit/daemon/dispatcher/http_spec.rb +3 -2
- data/spec/unit/daemon/dispatcher/tcp_spec.rb +10 -9
- data/spec/unit/daemon/dispatcher_loop_spec.rb +6 -24
- data/spec/unit/daemon/feeder_spec.rb +38 -39
- data/spec/unit/daemon/gcm/delivery_spec.rb +122 -101
- data/spec/unit/daemon/reflectable_spec.rb +2 -2
- data/spec/unit/daemon/retryable_error_spec.rb +1 -1
- data/spec/unit/daemon/service_config_methods_spec.rb +6 -3
- data/spec/unit/daemon/signal_handler_spec.rb +95 -0
- data/spec/unit/daemon/store/active_record/reconnectable_spec.rb +48 -27
- data/spec/unit/daemon/store/active_record_spec.rb +38 -47
- data/spec/unit/daemon/tcp_connection_spec.rb +22 -34
- data/spec/unit/daemon/wpns/delivery_spec.rb +58 -50
- data/spec/unit/daemon_spec.rb +48 -82
- data/spec/unit/embed_spec.rb +6 -4
- data/spec/unit/logger_spec.rb +35 -43
- data/spec/unit/notification_shared.rb +9 -79
- data/spec/unit/push_spec.rb +6 -10
- data/spec/unit/reflection_spec.rb +25 -25
- data/spec/unit/rpush_spec.rb +1 -2
- data/spec/unit_spec_helper.rb +33 -88
- metadata +126 -76
- data/lib/rpush/TODO +0 -3
- data/lib/rpush/adm/app.rb +0 -15
- data/lib/rpush/adm/data_validator.rb +0 -11
- data/lib/rpush/adm/notification.rb +0 -29
- data/lib/rpush/apns/app.rb +0 -29
- data/lib/rpush/apns/binary_notification_validator.rb +0 -12
- data/lib/rpush/apns/device_token_format_validator.rb +0 -12
- data/lib/rpush/apns/feedback.rb +0 -16
- data/lib/rpush/apns/notification.rb +0 -84
- data/lib/rpush/app.rb +0 -18
- data/lib/rpush/daemon/apns/certificate_expired_error.rb +0 -20
- data/lib/rpush/daemon/apns/disconnection_error.rb +0 -20
- data/lib/rpush/daemon/dispatcher_loop_collection.rb +0 -33
- data/lib/rpush/daemon/too_many_requests_error.rb +0 -20
- data/lib/rpush/gcm/app.rb +0 -11
- data/lib/rpush/gcm/expiry_collapse_key_mutual_inclusion_validator.rb +0 -11
- data/lib/rpush/gcm/notification.rb +0 -30
- data/lib/rpush/notification.rb +0 -69
- data/lib/rpush/notifier.rb +0 -52
- data/lib/rpush/payload_data_size_validator.rb +0 -10
- data/lib/rpush/railtie.rb +0 -11
- data/lib/rpush/registration_ids_count_validator.rb +0 -10
- data/lib/rpush/wpns/app.rb +0 -9
- data/lib/rpush/wpns/notification.rb +0 -26
- data/lib/tasks/cane.rake +0 -18
- data/lib/tasks/rpush.rake +0 -16
- data/spec/unit/apns/app_spec.rb +0 -29
- data/spec/unit/apns/feedback_spec.rb +0 -9
- data/spec/unit/apns/notification_spec.rb +0 -208
- data/spec/unit/app_spec.rb +0 -30
- data/spec/unit/daemon/apns/disconnection_error_spec.rb +0 -18
- data/spec/unit/daemon/dispatcher_loop_collection_spec.rb +0 -37
- data/spec/unit/daemon/interruptible_sleep_spec.rb +0 -68
- data/spec/unit/daemon/too_many_requests_error_spec.rb +0 -14
- data/spec/unit/gcm/app_spec.rb +0 -4
- data/spec/unit/notification_spec.rb +0 -15
- data/spec/unit/notifier_spec.rb +0 -49
- data/spec/unit/wpns/app_spec.rb +0 -4
- data/spec/unit/wpns/notification_spec.rb +0 -30
@@ -2,20 +2,15 @@ require 'unit_spec_helper'
|
|
2
2
|
require 'rpush/daemon/store/active_record'
|
3
3
|
|
4
4
|
describe Rpush::Daemon::Store::ActiveRecord do
|
5
|
-
let(:app) { Rpush::Apns::App.create!(:
|
6
|
-
let(:notification) { Rpush::Apns::Notification.create!(:
|
5
|
+
let(:app) { Rpush::Client::ActiveRecord::Apns::App.create!(name: 'my_app', environment: 'development', certificate: TEST_CERT) }
|
6
|
+
let(:notification) { Rpush::Client::ActiveRecord::Apns::Notification.create!(device_token: "a" * 64, app: app) }
|
7
7
|
let(:store) { Rpush::Daemon::Store::ActiveRecord.new }
|
8
8
|
let(:time) { Time.now.utc }
|
9
9
|
let(:logger) { double(Rpush::Logger, error: nil) }
|
10
10
|
|
11
11
|
before do
|
12
12
|
Rpush.stub(logger: logger)
|
13
|
-
Time.stub(:
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'reconnects after daemonize' do
|
17
|
-
store.should_receive(:reconnect_database)
|
18
|
-
store.after_daemonize
|
13
|
+
Time.stub(now: time)
|
19
14
|
end
|
20
15
|
|
21
16
|
it 'can update a notification' do
|
@@ -29,13 +24,13 @@ describe Rpush::Daemon::Store::ActiveRecord do
|
|
29
24
|
end
|
30
25
|
|
31
26
|
it 'can release a connection' do
|
32
|
-
ActiveRecord::Base.
|
27
|
+
ActiveRecord::Base.connection.should_receive(:close)
|
33
28
|
store.release_connection
|
34
29
|
end
|
35
30
|
|
36
31
|
it 'logs errors raised when trying to release the connection' do
|
37
32
|
e = StandardError.new
|
38
|
-
ActiveRecord::Base.
|
33
|
+
ActiveRecord::Base.connection.stub(:close).and_raise(e)
|
39
34
|
Rpush.logger.should_receive(:error).with(e)
|
40
35
|
store.release_connection
|
41
36
|
end
|
@@ -43,7 +38,7 @@ describe Rpush::Daemon::Store::ActiveRecord do
|
|
43
38
|
describe 'deliverable_notifications' do
|
44
39
|
it 'checks for new notifications with the ability to reconnect the database' do
|
45
40
|
store.should_receive(:with_database_reconnect_and_retry)
|
46
|
-
store.deliverable_notifications(
|
41
|
+
store.deliverable_notifications(Rpush.config.batch_size)
|
47
42
|
end
|
48
43
|
|
49
44
|
it 'loads notifications in batches' do
|
@@ -51,46 +46,42 @@ describe Rpush::Daemon::Store::ActiveRecord do
|
|
51
46
|
Rpush.config.push = false
|
52
47
|
relation = double.as_null_object
|
53
48
|
relation.should_receive(:limit).with(5000)
|
54
|
-
|
55
|
-
store.
|
49
|
+
relation.stub(to_a: [])
|
50
|
+
store.stub(ready_for_delivery: relation)
|
51
|
+
store.deliverable_notifications(Rpush.config.batch_size)
|
56
52
|
end
|
57
53
|
|
58
54
|
it 'does not load notification in batches if in push mode' do
|
59
55
|
Rpush.config.push = true
|
60
56
|
relation = double.as_null_object
|
61
57
|
relation.should_not_receive(:limit)
|
62
|
-
Rpush::Notification.stub(:
|
63
|
-
store.deliverable_notifications(
|
58
|
+
Rpush::Notification.stub(ready_for_delivery: relation)
|
59
|
+
store.deliverable_notifications(Rpush.config.batch_size)
|
64
60
|
end
|
65
61
|
|
66
62
|
it 'loads an undelivered notification without deliver_after set' do
|
67
|
-
notification.update_attributes!(:
|
68
|
-
store.deliverable_notifications(
|
63
|
+
notification.update_attributes!(delivered: false, deliver_after: nil)
|
64
|
+
store.deliverable_notifications(Rpush.config.batch_size).should eq [notification]
|
69
65
|
end
|
70
66
|
|
71
67
|
it 'loads an notification with a deliver_after time in the past' do
|
72
|
-
notification.update_attributes!(:
|
73
|
-
store.deliverable_notifications(
|
68
|
+
notification.update_attributes!(delivered: false, deliver_after: 1.hour.ago)
|
69
|
+
store.deliverable_notifications(Rpush.config.batch_size).should eq [notification]
|
74
70
|
end
|
75
71
|
|
76
72
|
it 'does not load an notification with a deliver_after time in the future' do
|
77
|
-
notification.update_attributes!(:
|
78
|
-
store.deliverable_notifications(
|
73
|
+
notification.update_attributes!(delivered: false, deliver_after: 1.hour.from_now)
|
74
|
+
store.deliverable_notifications(Rpush.config.batch_size).should be_empty
|
79
75
|
end
|
80
76
|
|
81
77
|
it 'does not load a previously delivered notification' do
|
82
|
-
notification.update_attributes!(:
|
83
|
-
store.deliverable_notifications(
|
78
|
+
notification.update_attributes!(delivered: true, delivered_at: time)
|
79
|
+
store.deliverable_notifications(Rpush.config.batch_size).should be_empty
|
84
80
|
end
|
85
81
|
|
86
82
|
it "does not enqueue a notification that has previously failed delivery" do
|
87
|
-
notification.update_attributes!(:
|
88
|
-
store.deliverable_notifications(
|
89
|
-
end
|
90
|
-
|
91
|
-
it 'does not load notifications for apps that are still processing the previous batch' do
|
92
|
-
notification
|
93
|
-
store.deliverable_notifications([]).should be_empty
|
83
|
+
notification.update_attributes!(delivered: false, failed: true)
|
84
|
+
store.deliverable_notifications(Rpush.config.batch_size).should be_empty
|
94
85
|
end
|
95
86
|
end
|
96
87
|
|
@@ -109,13 +100,13 @@ describe Rpush::Daemon::Store::ActiveRecord do
|
|
109
100
|
end
|
110
101
|
|
111
102
|
it 'saves the notification without validation' do
|
112
|
-
notification.should_receive(:save!).with(:
|
103
|
+
notification.should_receive(:save!).with(validate: false)
|
113
104
|
store.mark_retryable(notification, time)
|
114
105
|
end
|
115
106
|
|
116
|
-
it 'does not save the notification if :
|
107
|
+
it 'does not save the notification if persist: false' do
|
117
108
|
notification.should_not_receive(:save!)
|
118
|
-
store.mark_retryable(notification, time, :
|
109
|
+
store.mark_retryable(notification, time, persist: false)
|
119
110
|
end
|
120
111
|
end
|
121
112
|
|
@@ -158,13 +149,13 @@ describe Rpush::Daemon::Store::ActiveRecord do
|
|
158
149
|
end
|
159
150
|
|
160
151
|
it 'saves the notification without validation' do
|
161
|
-
notification.should_receive(:save!).with(:
|
152
|
+
notification.should_receive(:save!).with(validate: false)
|
162
153
|
store.mark_delivered(notification, time)
|
163
154
|
end
|
164
155
|
|
165
|
-
it 'does not save the notification if :
|
156
|
+
it 'does not save the notification if persist: false' do
|
166
157
|
notification.should_not_receive(:save!)
|
167
|
-
store.mark_delivered(notification, time, :
|
158
|
+
store.mark_delivered(notification, time, persist: false)
|
168
159
|
end
|
169
160
|
end
|
170
161
|
|
@@ -223,13 +214,13 @@ describe Rpush::Daemon::Store::ActiveRecord do
|
|
223
214
|
end
|
224
215
|
|
225
216
|
it 'saves the notification without validation' do
|
226
|
-
notification.should_receive(:save!).with(:
|
217
|
+
notification.should_receive(:save!).with(validate: false)
|
227
218
|
store.mark_failed(notification, nil, '', time)
|
228
219
|
end
|
229
220
|
|
230
|
-
it 'does not save the notification if :
|
221
|
+
it 'does not save the notification if persist: false' do
|
231
222
|
notification.should_not_receive(:save!)
|
232
|
-
store.mark_failed(notification, nil, '', time, :
|
223
|
+
store.mark_failed(notification, nil, '', time, persist: false)
|
233
224
|
end
|
234
225
|
end
|
235
226
|
|
@@ -281,16 +272,16 @@ describe Rpush::Daemon::Store::ActiveRecord do
|
|
281
272
|
|
282
273
|
describe 'create_apns_feedback' do
|
283
274
|
it 'creates the Feedback record' do
|
284
|
-
Rpush::Apns::Feedback.should_receive(:create!).with(
|
285
|
-
:
|
275
|
+
Rpush::Client::ActiveRecord::Apns::Feedback.should_receive(:create!).with(
|
276
|
+
failed_at: time, device_token: 'ab' * 32, app_id: app.id)
|
286
277
|
store.create_apns_feedback(time, 'ab' * 32, app)
|
287
278
|
end
|
288
279
|
end
|
289
280
|
|
290
281
|
describe 'create_gcm_notification' do
|
291
|
-
let(:data) { { :
|
292
|
-
let(:attributes) { { :
|
293
|
-
let(:registration_ids) {
|
282
|
+
let(:data) { { data: true } }
|
283
|
+
let(:attributes) { { device_token: 'ab' * 32 } }
|
284
|
+
let(:registration_ids) { %w(123 456) }
|
294
285
|
let(:deliver_after) { time + 10.seconds }
|
295
286
|
let(:args) { [attributes, data, registration_ids, deliver_after, app] }
|
296
287
|
|
@@ -321,9 +312,9 @@ describe Rpush::Daemon::Store::ActiveRecord do
|
|
321
312
|
end
|
322
313
|
|
323
314
|
describe 'create_adm_notification' do
|
324
|
-
let(:data) { { :
|
325
|
-
let(:attributes) { {:
|
326
|
-
let(:registration_ids) {
|
315
|
+
let(:data) { { data: true } }
|
316
|
+
let(:attributes) { { app_id: app.id, collapse_key: 'ckey', delay_while_idle: true } }
|
317
|
+
let(:registration_ids) { %w(123 456) }
|
327
318
|
let(:deliver_after) { time + 10.seconds }
|
328
319
|
let(:args) { [attributes, data, registration_ids, deliver_after, app] }
|
329
320
|
|
@@ -5,22 +5,22 @@ describe Rpush::Daemon::TcpConnection do
|
|
5
5
|
let(:certificate) { double }
|
6
6
|
let(:password) { double }
|
7
7
|
let(:x509_certificate) { OpenSSL::X509::Certificate.new(TEST_CERT) }
|
8
|
-
let(:ssl_context) { double(:key= => nil, :cert= => nil, :
|
8
|
+
let(:ssl_context) { double(:key= => nil, :cert= => nil, cert: x509_certificate) }
|
9
9
|
let(:host) { 'gateway.push.apple.com' }
|
10
10
|
let(:port) { '2195' }
|
11
|
-
let(:tcp_socket) { double(:
|
12
|
-
let(:ssl_socket) { double(:sync= => nil, :
|
13
|
-
let(:logger) { double(:
|
14
|
-
let(:app) { double(:
|
11
|
+
let(:tcp_socket) { double(setsockopt: nil, close: nil) }
|
12
|
+
let(:ssl_socket) { double(:sync= => nil, connect: nil, close: nil, write: nil, flush: nil) }
|
13
|
+
let(:logger) { double(info: nil, error: nil, warn: nil) }
|
14
|
+
let(:app) { double(name: 'Connection 0', certificate: certificate, password: password) }
|
15
15
|
let(:connection) { Rpush::Daemon::TcpConnection.new(app, host, port) }
|
16
16
|
|
17
17
|
before do
|
18
|
-
OpenSSL::SSL::SSLContext.stub(:
|
19
|
-
OpenSSL::PKey::RSA.stub(:
|
20
|
-
OpenSSL::X509::Certificate.stub(:
|
21
|
-
TCPSocket.stub(:
|
22
|
-
OpenSSL::SSL::SSLSocket.stub(:
|
23
|
-
Rpush.stub(:
|
18
|
+
OpenSSL::SSL::SSLContext.stub(new: ssl_context)
|
19
|
+
OpenSSL::PKey::RSA.stub(new: rsa_key)
|
20
|
+
OpenSSL::X509::Certificate.stub(new: x509_certificate)
|
21
|
+
TCPSocket.stub(new: tcp_socket)
|
22
|
+
OpenSSL::SSL::SSLSocket.stub(new: ssl_socket)
|
23
|
+
Rpush.stub(logger: logger)
|
24
24
|
connection.stub(:reflect)
|
25
25
|
end
|
26
26
|
|
@@ -103,13 +103,13 @@ describe Rpush::Daemon::TcpConnection do
|
|
103
103
|
it 'logs that the certificate has expired' do
|
104
104
|
cert = OpenSSL::X509::Certificate.new(app.certificate)
|
105
105
|
logger.should_receive(:error).with("[#{app.name}] Certificate expired at 2022-09-07 03:18:32 UTC.")
|
106
|
-
Timecop.freeze(cert.not_after + 1.day) { connection.connect rescue Rpush::
|
106
|
+
Timecop.freeze(cert.not_after + 1.day) { connection.connect rescue Rpush::CertificateExpiredError }
|
107
107
|
end
|
108
108
|
|
109
109
|
it 'raises an error if the certificate has expired' do
|
110
110
|
cert = OpenSSL::X509::Certificate.new(app.certificate)
|
111
111
|
Timecop.freeze(cert.not_after + 1.day) do
|
112
|
-
expect { connection.connect }.to raise_error(Rpush::
|
112
|
+
expect { connection.connect }.to raise_error(Rpush::CertificateExpiredError)
|
113
113
|
end
|
114
114
|
end
|
115
115
|
end
|
@@ -158,26 +158,17 @@ describe Rpush::Daemon::TcpConnection do
|
|
158
158
|
|
159
159
|
it 'reflects the connection has been lost' do
|
160
160
|
connection.should_receive(:reflect).with(:tcp_connection_lost, app, kind_of(error_type))
|
161
|
-
|
162
|
-
connection.write(nil)
|
163
|
-
rescue Rpush::Daemon::TcpConnectionError
|
164
|
-
end
|
161
|
+
expect { connection.write(nil) }.to raise_error(Rpush::Daemon::TcpConnectionError)
|
165
162
|
end
|
166
163
|
|
167
164
|
it "logs that the connection has been lost once only" do
|
168
165
|
logger.should_receive(:error).with("[Connection 0] Lost connection to gateway.push.apple.com:2195 (#{error_type.name}), reconnecting...").once
|
169
|
-
|
170
|
-
connection.write(nil)
|
171
|
-
rescue Rpush::Daemon::TcpConnectionError
|
172
|
-
end
|
166
|
+
expect { connection.write(nil) }.to raise_error(Rpush::Daemon::TcpConnectionError)
|
173
167
|
end
|
174
168
|
|
175
169
|
it "retries to make a connection 3 times" do
|
176
170
|
connection.should_receive(:reconnect).exactly(3).times
|
177
|
-
|
178
|
-
connection.write(nil)
|
179
|
-
rescue Rpush::Daemon::TcpConnectionError
|
180
|
-
end
|
171
|
+
expect { connection.write(nil) }.to raise_error(Rpush::Daemon::TcpConnectionError)
|
181
172
|
end
|
182
173
|
|
183
174
|
it "raises a TcpConnectionError after 3 attempts at reconnecting" do
|
@@ -188,10 +179,7 @@ describe Rpush::Daemon::TcpConnection do
|
|
188
179
|
|
189
180
|
it "sleeps 1 second before retrying the connection" do
|
190
181
|
connection.should_receive(:sleep).with(1)
|
191
|
-
|
192
|
-
connection.write(nil)
|
193
|
-
rescue Rpush::Daemon::TcpConnectionError
|
194
|
-
end
|
182
|
+
expect { connection.write(nil) }.to raise_error(Rpush::Daemon::TcpConnectionError)
|
195
183
|
end
|
196
184
|
end
|
197
185
|
|
@@ -259,15 +247,15 @@ describe Rpush::Daemon::TcpConnection do
|
|
259
247
|
before { connection.connect }
|
260
248
|
|
261
249
|
it 'reconnects if the connection has been idle for more than the defined period' do
|
262
|
-
Rpush::Daemon::TcpConnection.stub(:
|
263
|
-
Time.stub(:
|
250
|
+
Rpush::Daemon::TcpConnection.stub(idle_period: 60)
|
251
|
+
Time.stub(now: Time.now + 61)
|
264
252
|
connection.should_receive(:reconnect)
|
265
253
|
connection.write('blah')
|
266
254
|
end
|
267
255
|
|
268
256
|
it 'resets the last write time' do
|
269
257
|
now = Time.now
|
270
|
-
Time.stub(:
|
258
|
+
Time.stub(now: now)
|
271
259
|
connection.write('blah')
|
272
260
|
connection.last_write.should eq now
|
273
261
|
end
|
@@ -278,8 +266,8 @@ describe Rpush::Daemon::TcpConnection do
|
|
278
266
|
end
|
279
267
|
|
280
268
|
it 'logs the the connection is idle' do
|
281
|
-
Rpush::Daemon::TcpConnection.stub(:
|
282
|
-
Time.stub(:
|
269
|
+
Rpush::Daemon::TcpConnection.stub(idle_period: 60)
|
270
|
+
Time.stub(now: Time.now + 61)
|
283
271
|
Rpush.logger.should_receive(:info).with('[Connection 0] Idle period exceeded, reconnecting...')
|
284
272
|
connection.write('blah')
|
285
273
|
end
|
@@ -1,37 +1,41 @@
|
|
1
1
|
require 'unit_spec_helper'
|
2
2
|
|
3
3
|
describe Rpush::Daemon::Wpns::Delivery do
|
4
|
-
let(:app) { Rpush::Wpns::App.
|
5
|
-
let(:notification) { Rpush::Wpns::Notification.create!(:app
|
6
|
-
|
7
|
-
|
8
|
-
let(:
|
9
|
-
let(:response) { double(:code => 200, :header => {}) }
|
10
|
-
let(:http) { double(:shutdown => nil, :request => response) }
|
4
|
+
let(:app) { Rpush::Wpns::App.create!(name: "MyApp") }
|
5
|
+
let(:notification) { Rpush::Wpns::Notification.create!(app: app, alert: "test", uri: "http://some.example/", deliver_after: Time.now) }
|
6
|
+
let(:logger) { double(error: nil, info: nil, warn: nil) }
|
7
|
+
let(:response) { double(code: 200, header: {}) }
|
8
|
+
let(:http) { double(shutdown: nil, request: response) }
|
11
9
|
let(:now) { Time.parse('2012-10-14 00:00:00') }
|
12
|
-
let(:batch) { double(mark_failed: nil, mark_delivered: nil, mark_retryable: nil) }
|
10
|
+
let(:batch) { double(mark_failed: nil, mark_delivered: nil, mark_retryable: nil, notification_processed: nil) }
|
13
11
|
let(:delivery) { Rpush::Daemon::Wpns::Delivery.new(app, http, notification, batch) }
|
14
|
-
let(:store) { double(:
|
12
|
+
let(:store) { double(create_wpns_notification: double(id: 2)) }
|
15
13
|
|
16
14
|
def perform
|
17
15
|
delivery.perform
|
18
16
|
end
|
19
17
|
|
18
|
+
def perform_with_rescue
|
19
|
+
expect { perform }.to raise_error
|
20
|
+
end
|
21
|
+
|
20
22
|
before do
|
21
|
-
delivery.stub(:
|
22
|
-
Rpush::Daemon.stub(:
|
23
|
-
Time.stub(:
|
24
|
-
Rpush.stub(:
|
23
|
+
delivery.stub(reflect: nil)
|
24
|
+
Rpush::Daemon.stub(store: store)
|
25
|
+
Time.stub(now: now)
|
26
|
+
Rpush.stub(logger: logger)
|
25
27
|
end
|
26
28
|
|
27
29
|
shared_examples_for "an notification with some delivery faliures" do
|
28
30
|
let(:new_notification) { Rpush::Wpns::Notification.where('id != ?', notification.id).first }
|
29
31
|
|
30
|
-
before { response.stub(:
|
32
|
+
before { response.stub(body: JSON.dump(body)) }
|
31
33
|
|
32
34
|
it "marks the original notification falied" do
|
33
|
-
delivery.should_receive(:mark_failed)
|
34
|
-
|
35
|
+
delivery.should_receive(:mark_failed) do |error|
|
36
|
+
error.message.should =~ error_description
|
37
|
+
end
|
38
|
+
perform_with_rescue
|
35
39
|
end
|
36
40
|
|
37
41
|
it "raises a DeliveryError" do
|
@@ -41,99 +45,102 @@ describe Rpush::Daemon::Wpns::Delivery do
|
|
41
45
|
|
42
46
|
describe "an 200 response" do
|
43
47
|
before do
|
44
|
-
response.stub(:
|
48
|
+
response.stub(code: 200)
|
45
49
|
end
|
46
50
|
|
47
51
|
it "marks the notification as delivered if delivered successfully to all devices" do
|
48
|
-
response.stub(:
|
49
|
-
response.stub(:
|
52
|
+
response.stub(body: JSON.dump("failure" => 0))
|
53
|
+
response.stub(to_hash: { "x-notificationstatus" => ["Received"] })
|
50
54
|
batch.should_receive(:mark_delivered).with(notification)
|
51
55
|
perform
|
52
56
|
end
|
53
57
|
|
54
58
|
it "retries the notification when the queue is full" do
|
55
|
-
response.stub(:
|
56
|
-
response.stub(:
|
57
|
-
batch.should_receive(:mark_retryable).with(notification, Time.now + (60*10))
|
59
|
+
response.stub(body: JSON.dump("failure" => 0))
|
60
|
+
response.stub(to_hash: { "x-notificationstatus" => ["QueueFull"] })
|
61
|
+
batch.should_receive(:mark_retryable).with(notification, Time.now + (60 * 10))
|
58
62
|
perform
|
59
63
|
end
|
60
64
|
|
61
65
|
it "marks the notification as failed if the notification is suppressed" do
|
62
|
-
response.stub(:
|
63
|
-
response.stub(:
|
64
|
-
|
65
|
-
|
66
|
+
response.stub(body: JSON.dump("faliure" => 0))
|
67
|
+
response.stub(to_hash: { "x-notificationstatus" => ["Suppressed"] })
|
68
|
+
error = Rpush::DeliveryError.new(200, notification.id, 'Notification was received but suppressed by the service.')
|
69
|
+
delivery.should_receive(:mark_failed).with(error)
|
70
|
+
perform_with_rescue
|
66
71
|
end
|
67
72
|
end
|
68
73
|
|
69
74
|
describe "an 400 response" do
|
70
|
-
before { response.stub(:
|
75
|
+
before { response.stub(code: 400) }
|
71
76
|
it "marks notifications as failed" do
|
72
|
-
|
73
|
-
|
74
|
-
|
77
|
+
error = Rpush::DeliveryError.new(400, notification.id, 'Bad XML or malformed notification URI.')
|
78
|
+
delivery.should_receive(:mark_failed).with(error)
|
79
|
+
perform_with_rescue
|
75
80
|
end
|
76
81
|
end
|
77
82
|
|
78
83
|
describe "an 401 response" do
|
79
|
-
before { response.stub(:
|
84
|
+
before { response.stub(code: 401) }
|
80
85
|
it "marks notifications as failed" do
|
81
|
-
|
82
|
-
|
83
|
-
|
86
|
+
error = Rpush::DeliveryError.new(401, notification.id, 'Unauthorized to send a notification to this app.')
|
87
|
+
delivery.should_receive(:mark_failed).with(error)
|
88
|
+
perform_with_rescue
|
84
89
|
end
|
85
90
|
end
|
86
91
|
|
87
92
|
describe "an 404 response" do
|
88
|
-
before { response.stub(:
|
93
|
+
before { response.stub(code: 404) }
|
89
94
|
it "marks notifications as failed" do
|
90
|
-
|
91
|
-
|
95
|
+
error = Rpush::DeliveryError.new(404, notification.id, 'Not Found')
|
96
|
+
delivery.should_receive(:mark_failed).with(error)
|
97
|
+
perform_with_rescue
|
92
98
|
end
|
93
99
|
end
|
94
100
|
|
95
101
|
describe "an 405 response" do
|
96
|
-
before { response.stub(:
|
102
|
+
before { response.stub(code: 405) }
|
97
103
|
it "marks notifications as failed" do
|
98
|
-
|
99
|
-
|
104
|
+
error = Rpush::DeliveryError.new(405, notification.id, 'Method Not Allowed')
|
105
|
+
delivery.should_receive(:mark_failed).with(error)
|
106
|
+
perform_with_rescue
|
100
107
|
end
|
101
108
|
end
|
102
109
|
|
103
110
|
describe "an 406 response" do
|
104
|
-
before { response.stub(:
|
111
|
+
before { response.stub(code: 406) }
|
105
112
|
|
106
113
|
it "retries the notification" do
|
107
|
-
batch.should_receive(:mark_retryable).with(notification, Time.now + (60*60))
|
114
|
+
batch.should_receive(:mark_retryable).with(notification, Time.now + (60 * 60))
|
108
115
|
perform
|
109
116
|
end
|
110
117
|
|
111
118
|
it "logs a warning that the notification will be retried" do
|
112
119
|
notification.retries = 1
|
113
120
|
notification.deliver_after = now + 2
|
114
|
-
logger.should_receive(:warn).with("[MyApp] Per-day throttling limit reached. Notification
|
121
|
+
logger.should_receive(:warn).with("[MyApp] Per-day throttling limit reached. Notification #{notification.id} will be retried after 2012-10-14 00:00:02 (retry 1).")
|
115
122
|
perform
|
116
123
|
end
|
117
124
|
end
|
118
125
|
|
119
126
|
describe "an 412 response" do
|
120
|
-
before { response.stub(:
|
127
|
+
before { response.stub(code: 412) }
|
121
128
|
|
122
129
|
it "retries the notification" do
|
123
|
-
batch.should_receive(:mark_retryable).with(notification, Time.now + (60*60))
|
130
|
+
batch.should_receive(:mark_retryable).with(notification, Time.now + (60 * 60))
|
124
131
|
perform
|
125
132
|
end
|
126
133
|
|
127
134
|
it "logs a warning that the notification will be retried" do
|
128
135
|
notification.retries = 1
|
129
136
|
notification.deliver_after = now + 2
|
130
|
-
logger.should_receive(:warn).with("[MyApp] Device unreachable. Notification
|
137
|
+
logger.should_receive(:warn).with("[MyApp] Device unreachable. Notification #{notification.id} will be retried after 2012-10-14 00:00:02 (retry 1).")
|
131
138
|
perform
|
132
139
|
end
|
133
140
|
end
|
134
141
|
|
135
142
|
describe "an 503 response" do
|
136
|
-
before { response.stub(:
|
143
|
+
before { response.stub(code: 503) }
|
137
144
|
|
138
145
|
it "retries the notification exponentially" do
|
139
146
|
delivery.should_receive(:mark_retryable_exponential).with(notification)
|
@@ -149,11 +156,12 @@ describe Rpush::Daemon::Wpns::Delivery do
|
|
149
156
|
end
|
150
157
|
|
151
158
|
describe 'an un-handled response' do
|
152
|
-
before { response.stub(:
|
159
|
+
before { response.stub(code: 418) }
|
153
160
|
|
154
161
|
it 'marks the notification as failed' do
|
155
|
-
|
156
|
-
|
162
|
+
error = Rpush::DeliveryError.new(418, notification.id, "I'm a Teapot")
|
163
|
+
delivery.should_receive(:mark_failed).with(error)
|
164
|
+
perform_with_rescue
|
157
165
|
end
|
158
166
|
end
|
159
167
|
end
|