rpush_extended 3.2.5
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 +7 -0
- data/CHANGELOG.md +365 -0
- data/LICENSE +7 -0
- data/README.md +393 -0
- data/bin/rpush +4 -0
- data/lib/generators/rpush_config_generator.rb +7 -0
- data/lib/generators/rpush_migration_generator.rb +66 -0
- data/lib/generators/templates/add_adm.rb +23 -0
- data/lib/generators/templates/add_alert_is_json_to_rapns_notifications.rb +9 -0
- data/lib/generators/templates/add_app_to_rapns.rb +11 -0
- data/lib/generators/templates/add_fail_after_to_rpush_notifications.rb +9 -0
- data/lib/generators/templates/add_gcm.rb +117 -0
- data/lib/generators/templates/add_rpush.rb +402 -0
- data/lib/generators/templates/add_wpns.rb +16 -0
- data/lib/generators/templates/create_rapns_apps.rb +16 -0
- data/lib/generators/templates/create_rapns_feedback.rb +25 -0
- data/lib/generators/templates/create_rapns_notifications.rb +36 -0
- data/lib/generators/templates/rename_rapns_to_rpush.rb +87 -0
- data/lib/generators/templates/rpush.rb +135 -0
- data/lib/generators/templates/rpush_2_0_0_updates.rb +79 -0
- data/lib/generators/templates/rpush_2_1_0_updates.rb +11 -0
- data/lib/generators/templates/rpush_2_6_0_updates.rb +10 -0
- data/lib/generators/templates/rpush_2_7_0_updates.rb +12 -0
- data/lib/generators/templates/rpush_3_0_0_updates.rb +11 -0
- data/lib/generators/templates/rpush_3_0_1_updates.rb +13 -0
- data/lib/generators/templates/rpush_3_1_0_add_pushy.rb +9 -0
- data/lib/generators/templates/rpush_3_1_1_updates.rb +15 -0
- data/lib/generators/templates/rpush_3_2_0_add_apns_p8.rb +15 -0
- data/lib/generators/templates/rpush_3_2_4_updates.rb +9 -0
- data/lib/generators/templates/rpush_3_3_0_updates.rb +9 -0
- data/lib/generators/templates/rpush_3_3_1_updates.rb +11 -0
- data/lib/rpush/apns_feedback.rb +17 -0
- data/lib/rpush/cli.rb +213 -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 +104 -0
- data/lib/rpush/client/active_model/apns2/app.rb +15 -0
- data/lib/rpush/client/active_model/apns2/notification.rb +9 -0
- data/lib/rpush/client/active_model/apnsp8/app.rb +23 -0
- data/lib/rpush/client/active_model/apnsp8/notification.rb +9 -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 +59 -0
- data/lib/rpush/client/active_model/notification.rb +22 -0
- data/lib/rpush/client/active_model/payload_data_size_validator.rb +13 -0
- data/lib/rpush/client/active_model/pushy/app.rb +20 -0
- data/lib/rpush/client/active_model/pushy/notification.rb +31 -0
- data/lib/rpush/client/active_model/pushy/time_to_live_validator.rb +14 -0
- data/lib/rpush/client/active_model/registration_ids_count_validator.rb +13 -0
- data/lib/rpush/client/active_model/wns/app.rb +23 -0
- data/lib/rpush/client/active_model/wns/notification.rb +32 -0
- data/lib/rpush/client/active_model/wpns/app.rb +13 -0
- data/lib/rpush/client/active_model/wpns/notification.rb +28 -0
- data/lib/rpush/client/active_model.rb +34 -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 +18 -0
- data/lib/rpush/client/active_record/apns/notification.rb +40 -0
- data/lib/rpush/client/active_record/apns2/app.rb +11 -0
- data/lib/rpush/client/active_record/apns2/notification.rb +10 -0
- data/lib/rpush/client/active_record/apnsp8/app.rb +11 -0
- data/lib/rpush/client/active_record/apnsp8/notification.rb +10 -0
- data/lib/rpush/client/active_record/app.rb +13 -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 +42 -0
- data/lib/rpush/client/active_record/pushy/app.rb +11 -0
- data/lib/rpush/client/active_record/pushy/notification.rb +11 -0
- data/lib/rpush/client/active_record/wns/app.rb +11 -0
- data/lib/rpush/client/active_record/wns/badge_notification.rb +15 -0
- data/lib/rpush/client/active_record/wns/notification.rb +11 -0
- data/lib/rpush/client/active_record/wns/raw_notification.rb +13 -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 +33 -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/apns2/app.rb +11 -0
- data/lib/rpush/client/redis/apns2/notification.rb +11 -0
- data/lib/rpush/client/redis/apnsp8/app.rb +11 -0
- data/lib/rpush/client/redis/apnsp8/notification.rb +11 -0
- data/lib/rpush/client/redis/app.rb +29 -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 +74 -0
- data/lib/rpush/client/redis/pushy/app.rb +16 -0
- data/lib/rpush/client/redis/pushy/notification.rb +18 -0
- data/lib/rpush/client/redis/wns/app.rb +14 -0
- data/lib/rpush/client/redis/wns/badge_notification.rb +15 -0
- data/lib/rpush/client/redis/wns/notification.rb +11 -0
- data/lib/rpush/client/redis/wns/raw_notification.rb +11 -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 +56 -0
- data/lib/rpush/configuration.rb +115 -0
- data/lib/rpush/daemon/adm/delivery.rb +226 -0
- data/lib/rpush/daemon/adm.rb +9 -0
- data/lib/rpush/daemon/apns/delivery.rb +43 -0
- data/lib/rpush/daemon/apns/feedback_receiver.rb +90 -0
- data/lib/rpush/daemon/apns.rb +17 -0
- data/lib/rpush/daemon/apns2/delivery.rb +127 -0
- data/lib/rpush/daemon/apns2.rb +10 -0
- data/lib/rpush/daemon/apnsp8/delivery.rb +166 -0
- data/lib/rpush/daemon/apnsp8/token.rb +43 -0
- data/lib/rpush/daemon/apnsp8.rb +10 -0
- data/lib/rpush/daemon/app_runner.rb +190 -0
- data/lib/rpush/daemon/batch.rb +138 -0
- data/lib/rpush/daemon/constants.rb +59 -0
- data/lib/rpush/daemon/delivery.rb +46 -0
- data/lib/rpush/daemon/delivery_error.rb +27 -0
- data/lib/rpush/daemon/dispatcher/apns_http2.rb +51 -0
- data/lib/rpush/daemon/dispatcher/apns_tcp.rb +152 -0
- data/lib/rpush/daemon/dispatcher/apnsp8_http2.rb +33 -0
- data/lib/rpush/daemon/dispatcher/http.rb +21 -0
- data/lib/rpush/daemon/dispatcher/tcp.rb +22 -0
- data/lib/rpush/daemon/dispatcher_loop.rb +73 -0
- data/lib/rpush/daemon/errors.rb +18 -0
- data/lib/rpush/daemon/feeder.rb +69 -0
- data/lib/rpush/daemon/gcm/delivery.rb +241 -0
- data/lib/rpush/daemon/gcm.rb +9 -0
- data/lib/rpush/daemon/interruptible_sleep.rb +24 -0
- data/lib/rpush/daemon/loggable.rb +33 -0
- data/lib/rpush/daemon/proc_title.rb +17 -0
- data/lib/rpush/daemon/pushy/delivery.rb +90 -0
- data/lib/rpush/daemon/pushy.rb +9 -0
- data/lib/rpush/daemon/queue_payload.rb +12 -0
- data/lib/rpush/daemon/retry_header_parser.rb +23 -0
- data/lib/rpush/daemon/retryable_error.rb +22 -0
- data/lib/rpush/daemon/ring_buffer.rb +16 -0
- data/lib/rpush/daemon/rpc/client.rb +27 -0
- data/lib/rpush/daemon/rpc/server.rb +82 -0
- data/lib/rpush/daemon/rpc.rb +9 -0
- data/lib/rpush/daemon/service_config_methods.rb +51 -0
- data/lib/rpush/daemon/signal_handler.rb +75 -0
- data/lib/rpush/daemon/store/active_record/reconnectable.rb +80 -0
- data/lib/rpush/daemon/store/active_record.rb +214 -0
- data/lib/rpush/daemon/store/interface.rb +20 -0
- data/lib/rpush/daemon/store/redis.rb +166 -0
- data/lib/rpush/daemon/string_helpers.rb +15 -0
- data/lib/rpush/daemon/synchronizer.rb +62 -0
- data/lib/rpush/daemon/tcp_connection.rb +190 -0
- data/lib/rpush/daemon/wns/badge_request.rb +32 -0
- data/lib/rpush/daemon/wns/delivery.rb +178 -0
- data/lib/rpush/daemon/wns/post_request.rb +33 -0
- data/lib/rpush/daemon/wns/raw_request.rb +22 -0
- data/lib/rpush/daemon/wns/toast_request.rb +54 -0
- data/lib/rpush/daemon/wns.rb +9 -0
- data/lib/rpush/daemon/wpns/delivery.rb +132 -0
- data/lib/rpush/daemon/wpns.rb +9 -0
- data/lib/rpush/daemon.rb +179 -0
- data/lib/rpush/deprecatable.rb +24 -0
- data/lib/rpush/deprecation.rb +26 -0
- data/lib/rpush/embed.rb +41 -0
- data/lib/rpush/logger.rb +92 -0
- data/lib/rpush/multi_json_helper.rb +16 -0
- data/lib/rpush/plugin.rb +44 -0
- data/lib/rpush/push.rb +11 -0
- data/lib/rpush/reflectable.rb +13 -0
- data/lib/rpush/reflection_collection.rb +44 -0
- data/lib/rpush/reflection_public_methods.rb +11 -0
- data/lib/rpush/version.rb +14 -0
- data/lib/rpush.rb +43 -0
- data/lib/tasks/quality.rake +35 -0
- data/lib/tasks/test.rake +69 -0
- data/spec/.rubocop.yml +4 -0
- data/spec/functional/adm_spec.rb +50 -0
- data/spec/functional/apns2_spec.rb +232 -0
- data/spec/functional/apns_spec.rb +162 -0
- data/spec/functional/cli_spec.rb +36 -0
- data/spec/functional/embed_spec.rb +49 -0
- data/spec/functional/gcm_spec.rb +46 -0
- data/spec/functional/new_app_spec.rb +44 -0
- data/spec/functional/pushy_spec.rb +22 -0
- data/spec/functional/retry_spec.rb +42 -0
- data/spec/functional/synchronization_spec.rb +97 -0
- data/spec/functional/wpns_spec.rb +71 -0
- data/spec/functional_spec_helper.rb +32 -0
- data/spec/spec_helper.rb +69 -0
- data/spec/support/active_record_setup.rb +73 -0
- data/spec/support/cert_with_password.pem +90 -0
- data/spec/support/cert_without_password.pem +59 -0
- data/spec/support/config/database.yml +44 -0
- data/spec/support/simplecov_helper.rb +24 -0
- data/spec/support/simplecov_quality_formatter.rb +12 -0
- data/spec/tmp/.gitkeep +0 -0
- data/spec/unit/apns_feedback_spec.rb +28 -0
- data/spec/unit/client/active_record/adm/app_spec.rb +58 -0
- data/spec/unit/client/active_record/adm/notification_spec.rb +43 -0
- 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 +324 -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/client/active_record/gcm/notification_spec.rb +67 -0
- data/spec/unit/client/active_record/notification_spec.rb +21 -0
- data/spec/unit/client/active_record/pushy/app_spec.rb +17 -0
- data/spec/unit/client/active_record/pushy/notification_spec.rb +65 -0
- data/spec/unit/client/active_record/wns/badge_notification_spec.rb +15 -0
- data/spec/unit/client/active_record/wns/raw_notification_spec.rb +26 -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 +46 -0
- data/spec/unit/daemon/adm/delivery_spec.rb +253 -0
- data/spec/unit/daemon/apns/certificate_expired_error_spec.rb +11 -0
- data/spec/unit/daemon/apns/delivery_spec.rb +108 -0
- data/spec/unit/daemon/apns/feedback_receiver_spec.rb +119 -0
- data/spec/unit/daemon/app_runner_spec.rb +188 -0
- data/spec/unit/daemon/batch_spec.rb +169 -0
- data/spec/unit/daemon/delivery_error_spec.rb +13 -0
- data/spec/unit/daemon/delivery_spec.rb +51 -0
- data/spec/unit/daemon/dispatcher/http_spec.rb +34 -0
- data/spec/unit/daemon/dispatcher/tcp_spec.rb +32 -0
- data/spec/unit/daemon/dispatcher_loop_spec.rb +53 -0
- data/spec/unit/daemon/feeder_spec.rb +96 -0
- data/spec/unit/daemon/gcm/delivery_spec.rb +387 -0
- data/spec/unit/daemon/proc_title_spec.rb +11 -0
- data/spec/unit/daemon/pushy/delivery_spec.rb +159 -0
- data/spec/unit/daemon/retryable_error_spec.rb +14 -0
- data/spec/unit/daemon/service_config_methods_spec.rb +36 -0
- data/spec/unit/daemon/signal_handler_spec.rb +99 -0
- data/spec/unit/daemon/store/active_record/reconnectable_spec.rb +165 -0
- data/spec/unit/daemon/store/active_record_spec.rb +357 -0
- data/spec/unit/daemon/store/redis_spec.rb +365 -0
- data/spec/unit/daemon/tcp_connection_spec.rb +292 -0
- data/spec/unit/daemon/wns/delivery_spec.rb +176 -0
- data/spec/unit/daemon/wns/post_request_spec.rb +117 -0
- data/spec/unit/daemon/wpns/delivery_spec.rb +167 -0
- data/spec/unit/daemon_spec.rb +138 -0
- data/spec/unit/deprecatable_spec.rb +32 -0
- data/spec/unit/deprecation_spec.rb +15 -0
- data/spec/unit/embed_spec.rb +47 -0
- data/spec/unit/logger_spec.rb +127 -0
- data/spec/unit/notification_shared.rb +53 -0
- data/spec/unit/plugin_spec.rb +36 -0
- data/spec/unit/push_spec.rb +34 -0
- data/spec/unit/reflectable_spec.rb +27 -0
- data/spec/unit/reflection_collection_spec.rb +26 -0
- data/spec/unit/rpush_spec.rb +8 -0
- data/spec/unit_spec_helper.rb +26 -0
- metadata +709 -0
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
require 'unit_spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Rpush::Daemon::Gcm::Delivery do
|
|
4
|
+
let(:app) { Rpush::Gcm::App.create!(name: 'MyApp', auth_key: 'abc123') }
|
|
5
|
+
let(:notification) { Rpush::Gcm::Notification.create!(app: app, registration_ids: ['xyz'], 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) }
|
|
9
|
+
let(:now) { Time.parse('2012-10-14 00:00:00') }
|
|
10
|
+
let(:batch) { double(mark_failed: nil, mark_delivered: nil, mark_retryable: nil, notification_processed: nil) }
|
|
11
|
+
let(:delivery) { Rpush::Daemon::Gcm::Delivery.new(app, http, notification, batch) }
|
|
12
|
+
let(:store) { double(create_gcm_notification: double(id: 2)) }
|
|
13
|
+
|
|
14
|
+
def perform
|
|
15
|
+
delivery.perform
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def perform_with_rescue
|
|
19
|
+
expect { perform }.to raise_error(StandardError)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
before do
|
|
23
|
+
allow(delivery).to receive_messages(reflect: nil)
|
|
24
|
+
allow(Rpush::Daemon).to receive_messages(store: store)
|
|
25
|
+
allow(Time).to receive_messages(now: now)
|
|
26
|
+
allow(Rpush).to receive_messages(logger: logger)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
shared_examples_for 'a notification with some delivery failures' do
|
|
30
|
+
let(:new_notification) { Rpush::Gcm::Notification.where('id != ?', notification.id).first }
|
|
31
|
+
|
|
32
|
+
before { allow(response).to receive_messages(body: JSON.dump(body)) }
|
|
33
|
+
|
|
34
|
+
it 'marks the original notification as failed' do
|
|
35
|
+
# error = Rpush::DeliveryError.new(nil, notification.id, error_description)
|
|
36
|
+
expect(delivery).to receive(:mark_failed) do |error|
|
|
37
|
+
expect(error.to_s).to match(error_description)
|
|
38
|
+
end
|
|
39
|
+
perform_with_rescue
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'creates a new notification for the unavailable devices' do
|
|
43
|
+
notification.update_attributes(registration_ids: %w(id_0 id_1 id_2), data: { 'one' => 1 }, collapse_key: 'thing', delay_while_idle: true)
|
|
44
|
+
allow(response).to receive_messages(header: { 'retry-after' => 10 })
|
|
45
|
+
attrs = { 'collapse_key' => 'thing', 'delay_while_idle' => true, 'app_id' => app.id }
|
|
46
|
+
expect(store).to receive(:create_gcm_notification).with(attrs, notification.data,
|
|
47
|
+
%w(id_0 id_2), now + 10.seconds, notification.app)
|
|
48
|
+
perform_with_rescue
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'raises a DeliveryError' do
|
|
52
|
+
expect { perform }.to raise_error(Rpush::DeliveryError)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
describe 'a 200 response' do
|
|
57
|
+
before do
|
|
58
|
+
allow(response).to receive_messages(code: 200)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it 'reflects on any IDs which successfully received the notification' do
|
|
62
|
+
body = {
|
|
63
|
+
'failure' => 1,
|
|
64
|
+
'success' => 1,
|
|
65
|
+
'results' => [
|
|
66
|
+
{ 'message_id' => '1:000' },
|
|
67
|
+
{ 'error' => 'Err' }
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
allow(response).to receive_messages(body: JSON.dump(body))
|
|
72
|
+
allow(notification).to receive_messages(registration_ids: %w(1 2))
|
|
73
|
+
expect(delivery).to receive(:reflect).with(:gcm_delivered_to_recipient, notification, '1')
|
|
74
|
+
expect(delivery).not_to receive(:reflect).with(:gcm_delivered_to_recipient, notification, '2')
|
|
75
|
+
perform_with_rescue
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it 'reflects on any IDs which failed to receive the notification' do
|
|
79
|
+
body = {
|
|
80
|
+
'failure' => 1,
|
|
81
|
+
'success' => 1,
|
|
82
|
+
'results' => [
|
|
83
|
+
{ 'error' => 'Err' },
|
|
84
|
+
{ 'message_id' => '1:000' }
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
allow(response).to receive_messages(body: JSON.dump(body))
|
|
89
|
+
allow(notification).to receive_messages(registration_ids: %w(1 2))
|
|
90
|
+
expect(delivery).to receive(:reflect).with(:gcm_failed_to_recipient, notification, 'Err', '1')
|
|
91
|
+
expect(delivery).not_to receive(:reflect).with(:gcm_failed_to_recipient, notification, anything, '2')
|
|
92
|
+
perform_with_rescue
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it 'reflects on canonical IDs' do
|
|
96
|
+
body = {
|
|
97
|
+
'failure' => 0,
|
|
98
|
+
'success' => 3,
|
|
99
|
+
'canonical_ids' => 1,
|
|
100
|
+
'results' => [
|
|
101
|
+
{ 'message_id' => '1:000' },
|
|
102
|
+
{ 'message_id' => '1:000', 'registration_id' => 'canonical123' },
|
|
103
|
+
{ 'message_id' => '1:000' }
|
|
104
|
+
] }
|
|
105
|
+
|
|
106
|
+
allow(response).to receive_messages(body: JSON.dump(body))
|
|
107
|
+
allow(notification).to receive_messages(registration_ids: %w(1 2 3))
|
|
108
|
+
expect(delivery).to receive(:reflect).with(:gcm_canonical_id, '2', 'canonical123')
|
|
109
|
+
perform
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it 'reflects on invalid IDs' do
|
|
113
|
+
body = {
|
|
114
|
+
'failure' => 1,
|
|
115
|
+
'success' => 2,
|
|
116
|
+
'canonical_ids' => 0,
|
|
117
|
+
'results' => [
|
|
118
|
+
{ 'message_id' => '1:000' },
|
|
119
|
+
{ 'error' => 'NotRegistered' },
|
|
120
|
+
{ 'message_id' => '1:000' }
|
|
121
|
+
]
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
allow(response).to receive_messages(body: JSON.dump(body))
|
|
125
|
+
allow(notification).to receive_messages(registration_ids: %w(1 2 3))
|
|
126
|
+
expect(delivery).to receive(:reflect).with(:gcm_invalid_registration_id, app, 'NotRegistered', '2')
|
|
127
|
+
perform_with_rescue
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
describe 'when delivered successfully to all devices' do
|
|
131
|
+
let(:body) do
|
|
132
|
+
{
|
|
133
|
+
'failure' => 0,
|
|
134
|
+
'success' => 1,
|
|
135
|
+
'results' => [{ 'message_id' => '1:000' }]
|
|
136
|
+
}
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
before { allow(response).to receive_messages(body: JSON.dump(body)) }
|
|
140
|
+
|
|
141
|
+
it 'marks the notification as delivered' do
|
|
142
|
+
expect(delivery).to receive(:mark_delivered)
|
|
143
|
+
perform
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
it 'logs that the notification was delivered' do
|
|
147
|
+
expect(logger).to receive(:info).with("[MyApp] #{notification.id} sent to xyz")
|
|
148
|
+
perform
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it 'marks a notification as failed if any ids are invalid' do
|
|
153
|
+
body = {
|
|
154
|
+
'failure' => 1,
|
|
155
|
+
'success' => 2,
|
|
156
|
+
'canonical_ids' => 0,
|
|
157
|
+
'results' => [
|
|
158
|
+
{ 'message_id' => '1:000' },
|
|
159
|
+
{ 'error' => 'NotRegistered' },
|
|
160
|
+
{ 'message_id' => '1:000' }
|
|
161
|
+
]
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
allow(response).to receive_messages(body: JSON.dump(body))
|
|
165
|
+
expect(delivery).to receive(:mark_failed)
|
|
166
|
+
expect(delivery).not_to receive(:mark_retryable)
|
|
167
|
+
expect(store).not_to receive(:create_gcm_notification)
|
|
168
|
+
perform_with_rescue
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it 'marks a notification as failed if any deliveries failed that cannot be retried' do
|
|
172
|
+
body = {
|
|
173
|
+
'failure' => 1,
|
|
174
|
+
'success' => 1,
|
|
175
|
+
'results' => [
|
|
176
|
+
{ 'message_id' => '1:000' },
|
|
177
|
+
{ 'error' => 'InvalidDataKey' }
|
|
178
|
+
] }
|
|
179
|
+
allow(response).to receive_messages(body: JSON.dump(body))
|
|
180
|
+
error = Rpush::DeliveryError.new(nil, notification.id, 'Failed to deliver to all recipients. Errors: InvalidDataKey.')
|
|
181
|
+
expect(delivery).to receive(:mark_failed).with(error)
|
|
182
|
+
perform_with_rescue
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
describe 'all deliveries failed with Unavailable or InternalServerError' do
|
|
186
|
+
let(:body) do
|
|
187
|
+
{
|
|
188
|
+
'failure' => 2,
|
|
189
|
+
'success' => 0,
|
|
190
|
+
'results' => [
|
|
191
|
+
{ 'error' => 'Unavailable' },
|
|
192
|
+
{ 'error' => 'Unavailable' }
|
|
193
|
+
]
|
|
194
|
+
}
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
before do
|
|
198
|
+
allow(response).to receive_messages(body: JSON.dump(body))
|
|
199
|
+
allow(notification).to receive_messages(registration_ids: %w(1 2))
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
it 'retries the notification respecting the Retry-After header' do
|
|
203
|
+
allow(response).to receive_messages(header: { 'retry-after' => 10 })
|
|
204
|
+
expect(delivery).to receive(:mark_retryable).with(notification, now + 10.seconds)
|
|
205
|
+
perform
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
it 'retries the notification using exponential back-off if the Retry-After header is not present' do
|
|
209
|
+
expect(delivery).to receive(:mark_retryable).with(notification, now + 2)
|
|
210
|
+
perform
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
it 'does not mark the notification as failed' do
|
|
214
|
+
expect(delivery).not_to receive(:mark_failed)
|
|
215
|
+
perform
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
it 'logs that the notification will be retried' do
|
|
219
|
+
notification.retries = 1
|
|
220
|
+
notification.deliver_after = now + 2
|
|
221
|
+
expect(Rpush.logger).to receive(:warn).with("[MyApp] All recipients unavailable. Notification #{notification.id} will be retried after 2012-10-14 00:00:02 (retry 1).")
|
|
222
|
+
perform
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
describe 'all deliveries failed with some as Unavailable or InternalServerError' do
|
|
227
|
+
let(:body) do
|
|
228
|
+
{ 'failure' => 3,
|
|
229
|
+
'success' => 0,
|
|
230
|
+
'results' => [
|
|
231
|
+
{ 'error' => 'Unavailable' },
|
|
232
|
+
{ 'error' => 'InvalidDataKey' },
|
|
233
|
+
{ 'error' => 'Unavailable' }
|
|
234
|
+
]
|
|
235
|
+
}
|
|
236
|
+
end
|
|
237
|
+
let(:error_description) { /#{Regexp.escape("Failed to deliver to recipients 0, 1, 2. Errors: Unavailable, InvalidDataKey, Unavailable. 0, 2 will be retried as notification")} [\d]+\./ }
|
|
238
|
+
it_should_behave_like 'a notification with some delivery failures'
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
describe 'some deliveries failed with Unavailable or InternalServerError' do
|
|
242
|
+
let(:body) do
|
|
243
|
+
{ 'failure' => 2,
|
|
244
|
+
'success' => 1,
|
|
245
|
+
'results' => [
|
|
246
|
+
{ 'error' => 'Unavailable' },
|
|
247
|
+
{ 'message_id' => '1:000' },
|
|
248
|
+
{ 'error' => 'InternalServerError' }
|
|
249
|
+
]
|
|
250
|
+
}
|
|
251
|
+
end
|
|
252
|
+
let(:error_description) { /#{Regexp.escape("Failed to deliver to recipients 0, 2. Errors: Unavailable, InternalServerError. 0, 2 will be retried as notification")} [\d]+\./ }
|
|
253
|
+
it_should_behave_like 'a notification with some delivery failures'
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
describe 'a 503 response' do
|
|
258
|
+
before { allow(response).to receive_messages(code: 503) }
|
|
259
|
+
|
|
260
|
+
it 'logs a warning that the notification will be retried.' do
|
|
261
|
+
notification.retries = 1
|
|
262
|
+
notification.deliver_after = now + 2
|
|
263
|
+
expect(logger).to receive(:warn).with("[MyApp] GCM responded with an Service Unavailable Error. Notification #{notification.id} will be retried after 2012-10-14 00:00:02 (retry 1).")
|
|
264
|
+
perform
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
it 'respects an integer Retry-After header' do
|
|
268
|
+
allow(response).to receive_messages(header: { 'retry-after' => 10 })
|
|
269
|
+
expect(delivery).to receive(:mark_retryable).with(notification, now + 10.seconds)
|
|
270
|
+
perform
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
it 'respects a HTTP-date Retry-After header' do
|
|
274
|
+
allow(response).to receive_messages(header: { 'retry-after' => 'Wed, 03 Oct 2012 20:55:11 GMT' })
|
|
275
|
+
expect(delivery).to receive(:mark_retryable).with(notification, Time.parse('Wed, 03 Oct 2012 20:55:11 GMT'))
|
|
276
|
+
perform
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
it 'defaults to exponential back-off if the Retry-After header is not present' do
|
|
280
|
+
expect(delivery).to receive(:mark_retryable).with(notification, now + 2**1)
|
|
281
|
+
perform
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
describe 'a 502 response' do
|
|
286
|
+
before { allow(response).to receive_messages(code: 502) }
|
|
287
|
+
|
|
288
|
+
it 'logs a warning that the notification will be retried.' do
|
|
289
|
+
notification.retries = 1
|
|
290
|
+
notification.deliver_after = now + 2
|
|
291
|
+
expect(logger).to receive(:warn).with("[MyApp] GCM responded with a Bad Gateway Error. Notification #{notification.id} will be retried after 2012-10-14 00:00:02 (retry 1).")
|
|
292
|
+
perform
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
it 'respects an integer Retry-After header' do
|
|
296
|
+
allow(response).to receive_messages(header: { 'retry-after' => 10 })
|
|
297
|
+
expect(delivery).to receive(:mark_retryable).with(notification, now + 10.seconds)
|
|
298
|
+
perform
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
it 'respects a HTTP-date Retry-After header' do
|
|
302
|
+
allow(response).to receive_messages(header: { 'retry-after' => 'Wed, 03 Oct 2012 20:55:11 GMT' })
|
|
303
|
+
expect(delivery).to receive(:mark_retryable).with(notification, Time.parse('Wed, 03 Oct 2012 20:55:11 GMT'))
|
|
304
|
+
perform
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
it 'defaults to exponential back-off if the Retry-After header is not present' do
|
|
308
|
+
expect(delivery).to receive(:mark_retryable).with(notification, now + 2**1)
|
|
309
|
+
perform
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
describe 'a 500 response' do
|
|
314
|
+
before do
|
|
315
|
+
notification.update_attribute(:retries, 2)
|
|
316
|
+
allow(response).to receive_messages(code: 500)
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
it 'logs a warning that the notification has been re-queued.' do
|
|
320
|
+
notification.retries = 3
|
|
321
|
+
notification.deliver_after = now + 2**3
|
|
322
|
+
expect(Rpush.logger).to receive(:warn).with("[MyApp] GCM responded with an Internal Error. Notification #{notification.id} will be retried after #{(now + 2**3).strftime('%Y-%m-%d %H:%M:%S')} (retry 3).")
|
|
323
|
+
perform
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
it 'retries the notification in accordance with the exponential back-off strategy.' do
|
|
327
|
+
expect(delivery).to receive(:mark_retryable).with(notification, now + 2**3)
|
|
328
|
+
perform
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
describe 'a 5xx response' do
|
|
333
|
+
before { allow(response).to receive_messages(code: 555) }
|
|
334
|
+
|
|
335
|
+
it 'logs a warning that the notification will be retried.' do
|
|
336
|
+
notification.retries = 1
|
|
337
|
+
notification.deliver_after = now + 2
|
|
338
|
+
expect(logger).to receive(:warn).with("[MyApp] GCM responded with a 5xx Error. Notification #{notification.id} will be retried after 2012-10-14 00:00:02 (retry 1).")
|
|
339
|
+
perform
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
it 'respects an integer Retry-After header' do
|
|
343
|
+
allow(response).to receive_messages(header: { 'retry-after' => 10 })
|
|
344
|
+
expect(delivery).to receive(:mark_retryable).with(notification, now + 10.seconds)
|
|
345
|
+
perform
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
it 'respects a HTTP-date Retry-After header' do
|
|
349
|
+
allow(response).to receive_messages(header: { 'retry-after' => 'Wed, 03 Oct 2012 20:55:11 GMT' })
|
|
350
|
+
expect(delivery).to receive(:mark_retryable).with(notification, Time.parse('Wed, 03 Oct 2012 20:55:11 GMT'))
|
|
351
|
+
perform
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
it 'defaults to exponential back-off if the Retry-After header is not present' do
|
|
355
|
+
expect(delivery).to receive(:mark_retryable).with(notification, now + 2**1)
|
|
356
|
+
perform
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
describe 'a 401 response' do
|
|
361
|
+
before { allow(response).to receive_messages(code: 401) }
|
|
362
|
+
|
|
363
|
+
it 'raises an error' do
|
|
364
|
+
expect { perform }.to raise_error(Rpush::DeliveryError)
|
|
365
|
+
end
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
describe 'a 400 response' do
|
|
369
|
+
before { allow(response).to receive_messages(code: 400) }
|
|
370
|
+
|
|
371
|
+
it 'marks the notification as failed' do
|
|
372
|
+
error = Rpush::DeliveryError.new(400, notification.id, 'GCM failed to parse the JSON request. Possibly an Rpush bug, please open an issue.')
|
|
373
|
+
expect(delivery).to receive(:mark_failed).with(error)
|
|
374
|
+
perform_with_rescue
|
|
375
|
+
end
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
describe 'an un-handled response' do
|
|
379
|
+
before { allow(response).to receive_messages(code: 418) }
|
|
380
|
+
|
|
381
|
+
it 'marks the notification as failed' do
|
|
382
|
+
error = Rpush::DeliveryError.new(418, notification.id, "I'm a Teapot")
|
|
383
|
+
expect(delivery).to receive(:mark_failed).with(error)
|
|
384
|
+
perform_with_rescue
|
|
385
|
+
end
|
|
386
|
+
end
|
|
387
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require 'unit_spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Rpush::Daemon::ProcTitle do
|
|
4
|
+
it 'sets the process title' do
|
|
5
|
+
Rpush.config.embedded = false
|
|
6
|
+
Rpush.config.push = false
|
|
7
|
+
allow(Rpush::Daemon::AppRunner).to receive_messages(total_dispatchers: 2, total_queued: 10)
|
|
8
|
+
expect(Process).to receive(:setproctitle).with('rpush | 10 queued | 2 dispatchers')
|
|
9
|
+
Rpush::Daemon::ProcTitle.update
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
require 'unit_spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Rpush::Daemon::Pushy::Delivery do
|
|
4
|
+
let(:app) { Rpush::Pushy::App.create!(name: 'MyApp', api_key: 'my_api_key') }
|
|
5
|
+
let(:token) { 'device token' }
|
|
6
|
+
let(:data) { { message: 'some message' } }
|
|
7
|
+
let(:notification) { Rpush::Pushy::Notification.create!(app: app, registration_ids: [token], data: data) }
|
|
8
|
+
let(:batch) { instance_double('Rpush::Daemon::Batch', notification_processed: nil) }
|
|
9
|
+
let(:response) { instance_double('Net::HTTPResponse', code: response_code, header: response_header) }
|
|
10
|
+
let(:response_code) { 200 }
|
|
11
|
+
let(:response_header) { {} }
|
|
12
|
+
let(:http) { instance_double('Net::HTTP::Persistent', request: response) }
|
|
13
|
+
let(:logger) { instance_double('Rpush::Logger', error: nil, info: nil, warn: nil, internal_logger: nil) }
|
|
14
|
+
let(:now) { Time.parse('2018-01-19 00:00:00 UTC') }
|
|
15
|
+
|
|
16
|
+
before do
|
|
17
|
+
allow(Rpush).to receive_messages(logger: logger)
|
|
18
|
+
allow(Time).to receive_messages(now: now)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
subject(:delivery) { described_class.new(app, http, notification, batch) }
|
|
22
|
+
|
|
23
|
+
describe '#pushy_uri' do
|
|
24
|
+
it { expect(subject.pushy_uri).to eq URI.parse('https://api.pushy.me/push?api_key=my_api_key') }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
describe '#perform' do
|
|
28
|
+
shared_examples 'process notification' do
|
|
29
|
+
it 'invoke batch.notification_processed' do
|
|
30
|
+
subject.perform rescue nil
|
|
31
|
+
expect(batch).to have_received(:notification_processed)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
context 'when response code is 200' do
|
|
36
|
+
let(:external_device_id) { '5a60ca7f6ad08477b5070dd3' }
|
|
37
|
+
|
|
38
|
+
before do
|
|
39
|
+
allow(batch).to receive(:mark_delivered)
|
|
40
|
+
response_body = {
|
|
41
|
+
success: true,
|
|
42
|
+
id: external_device_id
|
|
43
|
+
}
|
|
44
|
+
allow(response).to receive(:body) { response_body.to_json }
|
|
45
|
+
Rpush::Daemon.store = Rpush::Daemon::Store.const_get(Rpush.config.client.to_s.camelcase).new
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'marks the notification as delivered' do
|
|
49
|
+
delivery.perform
|
|
50
|
+
expect(batch).to have_received(:mark_delivered).with(notification)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it { expect { delivery.perform }.to change { notification.external_device_id }.to(external_device_id) }
|
|
54
|
+
|
|
55
|
+
it 'logs than notification received an external id' do
|
|
56
|
+
delivery.perform
|
|
57
|
+
expected = "#{notification.id} received an external id=5a60ca7f6ad08477b5070dd3"
|
|
58
|
+
expect(logger).to have_received(:info).with(expected)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it_behaves_like 'process notification'
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
shared_examples 'retry delivery' do |response_code:|
|
|
65
|
+
let(:response_code) { response_code }
|
|
66
|
+
|
|
67
|
+
shared_examples 'logs' do |deliver_after:|
|
|
68
|
+
let(:expected_log_message) do
|
|
69
|
+
"Pushy responded with a #{response_code} error. Notification #{notification.id} " \
|
|
70
|
+
"will be retried after #{deliver_after} (retry 1)."
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'logs that the notification will be retried' do
|
|
74
|
+
delivery.perform
|
|
75
|
+
expect(logger).to have_received(:warn).with(expected_log_message)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
context 'when Retry-After header is present' do
|
|
80
|
+
let(:response_header) { { 'retry-after' => 10 } }
|
|
81
|
+
|
|
82
|
+
before do
|
|
83
|
+
allow(delivery).to receive(:mark_retryable) do
|
|
84
|
+
notification.deliver_after = now + 10.seconds
|
|
85
|
+
notification.retries += 1
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it 'retry the notification' do
|
|
90
|
+
delivery.perform
|
|
91
|
+
expect(delivery).to have_received(:mark_retryable).with(notification, now + 10.seconds)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it_behaves_like 'logs', deliver_after: '2018-01-19 00:00:10'
|
|
95
|
+
it_behaves_like 'process notification'
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
context 'when Retry-After header is not present' do
|
|
99
|
+
before do
|
|
100
|
+
allow(delivery).to receive(:mark_retryable_exponential) do
|
|
101
|
+
notification.deliver_after = now + 2.seconds
|
|
102
|
+
notification.retries = 1
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it 'retry the notification' do
|
|
107
|
+
delivery.perform
|
|
108
|
+
expect(delivery).to have_received(:mark_retryable_exponential).with(notification)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it_behaves_like 'logs', deliver_after: '2018-01-19 00:00:02'
|
|
112
|
+
it_behaves_like 'process notification'
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it_behaves_like 'retry delivery', response_code: 429
|
|
117
|
+
it_behaves_like 'retry delivery', response_code: 500
|
|
118
|
+
it_behaves_like 'retry delivery', response_code: 502
|
|
119
|
+
it_behaves_like 'retry delivery', response_code: 503
|
|
120
|
+
it_behaves_like 'retry delivery', response_code: 504
|
|
121
|
+
|
|
122
|
+
context 'when delivery failed' do
|
|
123
|
+
let(:response_code) { 400 }
|
|
124
|
+
let(:fail_message) { 'No devices matched the specified condition.' }
|
|
125
|
+
before do
|
|
126
|
+
allow(response).to receive(:body) { { error: fail_message }.to_json }
|
|
127
|
+
allow(batch).to receive(:mark_failed)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it 'logs that the notifications failed' do
|
|
131
|
+
expect { delivery.perform }.to raise_error(Rpush::DeliveryError)
|
|
132
|
+
expect(logger).to have_received(:error).with("#{notification.id} failed: #{fail_message}")
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
it 'marks the notification as failed' do
|
|
136
|
+
expect { delivery.perform }.to raise_error(Rpush::DeliveryError)
|
|
137
|
+
expected_message = "Unable to deliver notification #{notification.id}, " \
|
|
138
|
+
"received error 400 (#{fail_message})"
|
|
139
|
+
expect(batch).to have_received(:mark_failed).with(notification, 400, expected_message)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
it_behaves_like 'process notification'
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
context 'when SocketError raised' do
|
|
146
|
+
before do
|
|
147
|
+
allow(http).to receive(:request) { raise SocketError }
|
|
148
|
+
allow(delivery).to receive(:mark_retryable)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it 'retry delivery after 10 seconds' do
|
|
152
|
+
expect { delivery.perform }.to raise_error(SocketError)
|
|
153
|
+
expect(delivery).to have_received(:mark_retryable).with(notification, now + 10.seconds, SocketError)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
it_behaves_like 'process notification'
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require "unit_spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Rpush::RetryableError do
|
|
4
|
+
let(:response) { double(code: 401, header: { 'retry-after' => 3600 }) }
|
|
5
|
+
let(:error) { Rpush::RetryableError.new(401, 12, "Unauthorized", response) }
|
|
6
|
+
|
|
7
|
+
it "returns an informative message" do
|
|
8
|
+
expect(error.to_s).to eq "Retryable error for 12, received error 401 (Unauthorized) - retry after 3600"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "returns the error code" do
|
|
12
|
+
expect(error.code).to eq 401
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'unit_spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Rpush::Daemon::ServiceConfigMethods do
|
|
4
|
+
module ServiceConfigMethodsSpec
|
|
5
|
+
extend Rpush::Daemon::ServiceConfigMethods
|
|
6
|
+
class Delivery; end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it 'returns the delivery class' do
|
|
10
|
+
expect(ServiceConfigMethodsSpec.delivery_class).to eq ServiceConfigMethodsSpec::Delivery
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'instantiates loops' do
|
|
14
|
+
loop_class = Class.new
|
|
15
|
+
app = double
|
|
16
|
+
loop_instance = loop_class.new
|
|
17
|
+
expect(loop_class).to receive(:new).with(app).and_return(loop_instance)
|
|
18
|
+
ServiceConfigMethodsSpec.loops loop_class
|
|
19
|
+
expect(ServiceConfigMethodsSpec.loop_instances(app)).to eq [loop_instance]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'returns a new dispatcher' do
|
|
23
|
+
ServiceConfigMethodsSpec.dispatcher :http, an: :option
|
|
24
|
+
app = double
|
|
25
|
+
dispatcher = double
|
|
26
|
+
expect(Rpush::Daemon::Dispatcher::Http).to receive(:new).with(app, ServiceConfigMethodsSpec::Delivery, an: :option).and_return(dispatcher)
|
|
27
|
+
expect(ServiceConfigMethodsSpec.new_dispatcher(app)).to eq dispatcher
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'raises a NotImplementedError for an unknown dispatcher type' do
|
|
31
|
+
expect do
|
|
32
|
+
ServiceConfigMethodsSpec.dispatcher :unknown
|
|
33
|
+
ServiceConfigMethodsSpec.dispatcher_class
|
|
34
|
+
end.to raise_error(NotImplementedError)
|
|
35
|
+
end
|
|
36
|
+
end
|