rapns 3.2.0-java → 3.3.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.
- data/CHANGELOG.md +5 -0
- data/README.md +9 -18
- data/lib/generators/templates/rapns.rb +5 -0
- data/lib/rapns.rb +4 -0
- data/lib/rapns/apns_feedback.rb +1 -0
- data/lib/rapns/configuration.rb +4 -3
- data/lib/rapns/daemon.rb +20 -4
- data/lib/rapns/daemon/apns/feedback_receiver.rb +9 -11
- data/lib/rapns/daemon/delivery.rb +3 -20
- data/lib/rapns/daemon/delivery_queue.rb +2 -2
- data/lib/rapns/daemon/feeder.rb +5 -10
- data/lib/rapns/daemon/gcm/delivery.rb +19 -9
- data/lib/rapns/daemon/store/active_record.rb +74 -0
- data/lib/rapns/daemon/store/active_record/reconnectable.rb +61 -0
- data/lib/rapns/gcm/notification.rb +5 -4
- data/lib/rapns/gcm/registration_ids_count_validator.rb +1 -1
- data/lib/rapns/logger.rb +6 -2
- data/lib/rapns/push.rb +1 -0
- data/lib/rapns/reflection.rb +1 -1
- data/lib/rapns/version.rb +1 -1
- data/spec/unit/apns/notification_spec.rb +2 -0
- data/spec/unit/apns_feedback_spec.rb +5 -0
- data/spec/unit/configuration_spec.rb +1 -1
- data/spec/unit/daemon/apns/delivery_spec.rb +7 -64
- data/spec/unit/daemon/apns/feedback_receiver_spec.rb +2 -2
- data/spec/unit/daemon/feeder_spec.rb +6 -58
- data/spec/unit/daemon/gcm/delivery_spec.rb +49 -57
- data/spec/unit/daemon/{database_reconnectable_spec.rb → store/active_record/reconnectable_spec.rb} +4 -3
- data/spec/unit/daemon/store/active_record_spec.rb +181 -0
- data/spec/unit/daemon_spec.rb +27 -7
- data/spec/unit/gcm/notification_spec.rb +2 -9
- data/spec/unit/push_spec.rb +5 -0
- data/spec/unit/reflection_spec.rb +0 -4
- data/spec/unit_spec_helper.rb +4 -1
- metadata +28 -25
- data/lib/rapns/daemon/database_reconnectable.rb +0 -57
@@ -5,7 +5,7 @@ module Rapns
|
|
5
5
|
|
6
6
|
def validate(record)
|
7
7
|
if record.registration_ids && record.registration_ids.size > LIMIT
|
8
|
-
record.errors[:base] << "GCM notification
|
8
|
+
record.errors[:base] << "GCM notification number of registration_ids cannot be larger than #{LIMIT}."
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
data/lib/rapns/logger.rb
CHANGED
@@ -6,8 +6,12 @@ module Rapns
|
|
6
6
|
begin
|
7
7
|
log = File.open(File.join(Rails.root, 'log', 'rapns.log'), 'a')
|
8
8
|
log.sync = true
|
9
|
-
|
10
|
-
|
9
|
+
if defined?(ActiveSupport::BufferedLogger)
|
10
|
+
@logger = ActiveSupport::BufferedLogger.new(log, Rails.logger.level)
|
11
|
+
@logger.auto_flushing = Rails.logger.respond_to?(:auto_flushing) ? Rails.logger.auto_flushing : true
|
12
|
+
else
|
13
|
+
@logger = ActiveSupport::Logger.new(log, Rails.logger.level)
|
14
|
+
end
|
11
15
|
rescue Errno::ENOENT, Errno::EPERM => e
|
12
16
|
@logger = nil
|
13
17
|
error(e)
|
data/lib/rapns/push.rb
CHANGED
data/lib/rapns/reflection.rb
CHANGED
data/lib/rapns/version.rb
CHANGED
@@ -8,6 +8,11 @@ describe Rapns, 'apns_feedback' do
|
|
8
8
|
Rapns::Daemon::Apns::FeedbackReceiver.stub(:new => receiver)
|
9
9
|
end
|
10
10
|
|
11
|
+
it 'initializes the store' do
|
12
|
+
Rapns::Daemon.should_receive(:initialize_store)
|
13
|
+
Rapns.apns_feedback
|
14
|
+
end
|
15
|
+
|
11
16
|
it 'checks feedback for each app' do
|
12
17
|
Rapns::Daemon::Apns::FeedbackReceiver.should_receive(:new).with(app, 0).and_return(receiver)
|
13
18
|
receiver.should_receive(:check_for_feedback)
|
@@ -40,7 +40,7 @@ describe Rapns::Configuration do
|
|
40
40
|
|
41
41
|
it 'does not allow foreground to be set to false if the platform is JRuby' do
|
42
42
|
config.foreground = true
|
43
|
-
|
43
|
+
Rapns.stub(:jruby? => true)
|
44
44
|
config.foreground = false
|
45
45
|
config.foreground.should be_true
|
46
46
|
end
|
@@ -7,6 +7,7 @@ describe Rapns::Daemon::Apns::Delivery do
|
|
7
7
|
let(:config) { stub(:check_for_errors => true) }
|
8
8
|
let(:connection) { stub(:select => false, :write => nil, :reconnect => nil, :close => nil, :connect => nil) }
|
9
9
|
let(:delivery) { Rapns::Daemon::Apns::Delivery.new(app, connection, notification) }
|
10
|
+
let(:store) { stub(:mark_failed => nil, :mark_delivered => nil) }
|
10
11
|
|
11
12
|
def perform
|
12
13
|
begin
|
@@ -16,6 +17,7 @@ describe Rapns::Daemon::Apns::Delivery do
|
|
16
17
|
end
|
17
18
|
|
18
19
|
before do
|
20
|
+
Rapns::Daemon.stub(:store => store)
|
19
21
|
Rapns.stub(:config => config, :logger => logger)
|
20
22
|
end
|
21
23
|
|
@@ -32,7 +34,7 @@ describe Rapns::Daemon::Apns::Delivery do
|
|
32
34
|
end
|
33
35
|
|
34
36
|
it "marks the notification as delivered" do
|
35
|
-
|
37
|
+
store.should_receive(:mark_delivered).with(notification)
|
36
38
|
perform
|
37
39
|
end
|
38
40
|
|
@@ -41,23 +43,6 @@ describe Rapns::Daemon::Apns::Delivery do
|
|
41
43
|
perform
|
42
44
|
end
|
43
45
|
|
44
|
-
it "sets the time the notification was delivered" do
|
45
|
-
now = Time.now
|
46
|
-
Time.stub(:now).and_return(now)
|
47
|
-
notification.should_receive(:delivered_at=).with(now)
|
48
|
-
perform
|
49
|
-
end
|
50
|
-
|
51
|
-
it "does not trigger validations when saving the notification" do
|
52
|
-
notification.should_receive(:save!).with(:validate => false)
|
53
|
-
perform
|
54
|
-
end
|
55
|
-
|
56
|
-
it "updates notification with the ability to reconnect the database" do
|
57
|
-
delivery.should_receive(:with_database_reconnect_and_retry)
|
58
|
-
perform
|
59
|
-
end
|
60
|
-
|
61
46
|
it 'does not check for errors if check_for_errors config option is false' do
|
62
47
|
config.stub(:check_for_errors => false)
|
63
48
|
delivery.should_not_receive(:check_for_error)
|
@@ -67,23 +52,8 @@ describe Rapns::Daemon::Apns::Delivery do
|
|
67
52
|
describe "when delivery fails" do
|
68
53
|
before { connection.stub(:select => true, :read => [8, 4, 69].pack("ccN")) }
|
69
54
|
|
70
|
-
it "
|
71
|
-
|
72
|
-
perform
|
73
|
-
end
|
74
|
-
|
75
|
-
it "sets the notification as not delivered" do
|
76
|
-
notification.should_receive(:delivered=).with(false)
|
77
|
-
perform
|
78
|
-
end
|
79
|
-
|
80
|
-
it "sets the notification delivered_at timestamp to nil" do
|
81
|
-
notification.should_receive(:delivered_at=).with(nil)
|
82
|
-
perform
|
83
|
-
end
|
84
|
-
|
85
|
-
it "sets the notification as failed" do
|
86
|
-
notification.should_receive(:failed=).with(true)
|
55
|
+
it "marks the notification as failed" do
|
56
|
+
store.should_receive(:mark_failed).with(notification, 4, "Missing payload")
|
87
57
|
perform
|
88
58
|
end
|
89
59
|
|
@@ -92,18 +62,6 @@ describe Rapns::Daemon::Apns::Delivery do
|
|
92
62
|
perform
|
93
63
|
end
|
94
64
|
|
95
|
-
it "sets the notification failed_at timestamp" do
|
96
|
-
now = Time.now
|
97
|
-
Time.stub(:now).and_return(now)
|
98
|
-
notification.should_receive(:failed_at=).with(now)
|
99
|
-
perform
|
100
|
-
end
|
101
|
-
|
102
|
-
it "sets the notification error code" do
|
103
|
-
notification.should_receive(:error_code=).with(4)
|
104
|
-
perform
|
105
|
-
end
|
106
|
-
|
107
65
|
it "logs the delivery error" do
|
108
66
|
# checking for the stubbed error doesn't work in jruby, but checking
|
109
67
|
# for the exception by class does.
|
@@ -115,16 +73,6 @@ describe Rapns::Daemon::Apns::Delivery do
|
|
115
73
|
expect { delivery.perform }.to raise_error(Rapns::DeliveryError)
|
116
74
|
end
|
117
75
|
|
118
|
-
it "sets the notification error description" do
|
119
|
-
notification.should_receive(:error_description=).with("Missing payload")
|
120
|
-
perform
|
121
|
-
end
|
122
|
-
|
123
|
-
it "skips validation when saving the notification" do
|
124
|
-
notification.should_receive(:save!).with(:validate => false)
|
125
|
-
perform
|
126
|
-
end
|
127
|
-
|
128
76
|
it "reads 6 bytes from the socket" do
|
129
77
|
connection.should_receive(:read).with(6).and_return(nil)
|
130
78
|
perform
|
@@ -155,13 +103,8 @@ describe Rapns::Daemon::Apns::Delivery do
|
|
155
103
|
expect { delivery.perform }.to raise_error(Rapns::Apns::DisconnectionError)
|
156
104
|
end
|
157
105
|
|
158
|
-
it '
|
159
|
-
|
160
|
-
perform
|
161
|
-
end
|
162
|
-
|
163
|
-
it 'sets the error description on the notification' do
|
164
|
-
notification.should_receive(:error_description=).with("APNs disconnected without returning an error.")
|
106
|
+
it 'marks the notification as failed' do
|
107
|
+
store.should_receive(:mark_failed).with(notification, nil, "APNs disconnected without returning an error.")
|
165
108
|
perform
|
166
109
|
end
|
167
110
|
end
|
@@ -16,8 +16,8 @@ describe Rapns::Daemon::Apns::FeedbackReceiver, 'check_for_feedback' do
|
|
16
16
|
receiver.stub(:interruptible_sleep)
|
17
17
|
Rapns.stub(:logger => logger)
|
18
18
|
Rapns::Daemon::Apns::Connection.stub(:new => connection)
|
19
|
-
Rapns::Apns::Feedback.stub(:create! => feedback)
|
20
19
|
receiver.instance_variable_set("@stop", false)
|
20
|
+
Rapns::Daemon.stub(:store => stub(:create_apns_feedback => feedback))
|
21
21
|
end
|
22
22
|
|
23
23
|
def stub_connection_read_with_tuple
|
@@ -58,8 +58,8 @@ describe Rapns::Daemon::Apns::FeedbackReceiver, 'check_for_feedback' do
|
|
58
58
|
end
|
59
59
|
|
60
60
|
it 'creates the feedback' do
|
61
|
+
Rapns::Daemon.store.should_receive(:create_apns_feedback).with(Time.at(1323533325), '834f786655eb9f84614a05ad7d00af31e5cfe93ac3ea078f1da44d2a4eb0ce17', app)
|
61
62
|
stub_connection_read_with_tuple
|
62
|
-
Rapns::Apns::Feedback.should_receive(:create!).with(:failed_at => Time.at(1323533325), :device_token => '834f786655eb9f84614a05ad7d00af31e5cfe93ac3ea078f1da44d2a4eb0ce17', :app => app)
|
63
63
|
receiver.check_for_feedback
|
64
64
|
end
|
65
65
|
|
@@ -8,10 +8,10 @@ describe Rapns::Daemon::Feeder do
|
|
8
8
|
let(:logger) { stub }
|
9
9
|
|
10
10
|
before do
|
11
|
-
Rapns.stub(:config => config)
|
11
|
+
Rapns.stub(:config => config,:logger => logger)
|
12
|
+
Rapns::Daemon.stub(:store => stub(:deliverable_notifications => [notification]))
|
12
13
|
Rapns::Daemon::Feeder.stub(:stop? => true)
|
13
|
-
Rapns::Daemon::AppRunner.stub(:idle => [stub(:app => app)])
|
14
|
-
Rapns.stub(:logger => logger)
|
14
|
+
Rapns::Daemon::AppRunner.stub(:enqueue => nil, :idle => [stub(:app => app)])
|
15
15
|
end
|
16
16
|
|
17
17
|
def start
|
@@ -25,8 +25,8 @@ describe Rapns::Daemon::Feeder do
|
|
25
25
|
start
|
26
26
|
end
|
27
27
|
|
28
|
-
it
|
29
|
-
Rapns::Daemon
|
28
|
+
it 'loads deliverable notifications' do
|
29
|
+
Rapns::Daemon.store.should_receive(:deliverable_notifications).with([app])
|
30
30
|
start
|
31
31
|
end
|
32
32
|
|
@@ -37,72 +37,20 @@ describe Rapns::Daemon::Feeder do
|
|
37
37
|
start
|
38
38
|
end
|
39
39
|
|
40
|
-
it 'loads notifications in batches' do
|
41
|
-
relation = stub.as_null_object
|
42
|
-
relation.should_receive(:limit).with(5000)
|
43
|
-
Rapns::Notification.stub(:ready_for_delivery => relation)
|
44
|
-
start
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'does not load notification in batches if in push mode' do
|
48
|
-
config.stub(:push => true)
|
49
|
-
relation = stub.as_null_object
|
50
|
-
relation.should_not_receive(:limit)
|
51
|
-
Rapns::Notification.stub(:ready_for_delivery => relation)
|
52
|
-
start
|
53
|
-
end
|
54
|
-
|
55
40
|
it "enqueues the notification" do
|
56
|
-
notification.update_attributes!(:delivered => false)
|
57
41
|
Rapns::Daemon::AppRunner.should_receive(:enqueue).with(notification)
|
58
42
|
start
|
59
43
|
end
|
60
44
|
|
61
45
|
it 'reflects the notification has been enqueued' do
|
62
|
-
notification.update_attributes!(:delivered => false)
|
63
46
|
Rapns::Daemon::AppRunner.stub(:enqueue)
|
64
47
|
Rapns::Daemon::Feeder.should_receive(:reflect).with(:notification_enqueued, notification)
|
65
48
|
start
|
66
49
|
end
|
67
50
|
|
68
|
-
it 'does not enqueue the notification if the app runner is still processing the previous batch' do
|
69
|
-
Rapns::Daemon::AppRunner.should_not_receive(:enqueue)
|
70
|
-
start
|
71
|
-
end
|
72
|
-
|
73
|
-
it "enqueues an undelivered notification without deliver_after set" do
|
74
|
-
notification.update_attributes!(:delivered => false, :deliver_after => nil)
|
75
|
-
Rapns::Daemon::AppRunner.should_receive(:enqueue).with(notification)
|
76
|
-
start
|
77
|
-
end
|
78
|
-
|
79
|
-
it "enqueues a notification with a deliver_after time in the past" do
|
80
|
-
notification.update_attributes!(:delivered => false, :deliver_after => 1.hour.ago)
|
81
|
-
Rapns::Daemon::AppRunner.should_receive(:enqueue).with(notification)
|
82
|
-
start
|
83
|
-
end
|
84
|
-
|
85
|
-
it "does not enqueue a notification with a deliver_after time in the future" do
|
86
|
-
notification.update_attributes!(:delivered => false, :deliver_after => 1.hour.from_now)
|
87
|
-
Rapns::Daemon::AppRunner.should_not_receive(:enqueue)
|
88
|
-
start
|
89
|
-
end
|
90
|
-
|
91
|
-
it "does not enqueue a previously delivered notification" do
|
92
|
-
notification.update_attributes!(:delivered => true, :delivered_at => Time.now)
|
93
|
-
Rapns::Daemon::AppRunner.should_not_receive(:enqueue)
|
94
|
-
start
|
95
|
-
end
|
96
|
-
|
97
|
-
it "does not enqueue a notification that has previously failed delivery" do
|
98
|
-
notification.update_attributes!(:delivered => false, :failed => true)
|
99
|
-
Rapns::Daemon::AppRunner.should_not_receive(:enqueue)
|
100
|
-
start
|
101
|
-
end
|
102
|
-
|
103
51
|
it "logs errors" do
|
104
52
|
e = StandardError.new("bork")
|
105
|
-
Rapns::
|
53
|
+
Rapns::Daemon.store.stub(:deliverable_notifications).and_raise(e)
|
106
54
|
Rapns.logger.should_receive(:error).with(e)
|
107
55
|
start
|
108
56
|
end
|
@@ -2,18 +2,21 @@ require 'unit_spec_helper'
|
|
2
2
|
|
3
3
|
describe Rapns::Daemon::Gcm::Delivery do
|
4
4
|
let(:app) { Rapns::Gcm::App.new(:name => 'MyApp', :auth_key => 'abc123') }
|
5
|
-
let(:notification) { Rapns::Gcm::Notification.create!(:app => app, :registration_ids => ['xyz']) }
|
5
|
+
let(:notification) { Rapns::Gcm::Notification.create!(:app => app, :registration_ids => ['xyz'], :deliver_after => Time.now) }
|
6
6
|
let(:logger) { stub(:error => nil, :info => nil, :warn => nil) }
|
7
7
|
let(:response) { stub(:code => 200, :header => {}) }
|
8
8
|
let(:http) { stub(:shutdown => nil, :request => response)}
|
9
9
|
let(:now) { Time.parse('2012-10-14 00:00:00') }
|
10
10
|
let(:delivery) { Rapns::Daemon::Gcm::Delivery.new(app, http, notification) }
|
11
|
+
let(:store) { stub(:mark_failed => nil, :mark_delivered => nil, :retry_after => nil, :create_gcm_notification => stub(:id => 2)) }
|
11
12
|
|
12
13
|
def perform
|
13
14
|
delivery.perform
|
14
15
|
end
|
15
16
|
|
16
17
|
before do
|
18
|
+
delivery.stub(:reflect => nil)
|
19
|
+
Rapns::Daemon.stub(:store => store)
|
17
20
|
Time.stub(:now => now)
|
18
21
|
Rapns.stub(:logger => logger)
|
19
22
|
end
|
@@ -25,9 +28,8 @@ describe Rapns::Daemon::Gcm::Delivery do
|
|
25
28
|
|
26
29
|
it 'marks the notification as delivered if delivered successfully to all devices' do
|
27
30
|
response.stub(:body => JSON.dump({ 'failure' => 0 }))
|
28
|
-
|
29
|
-
|
30
|
-
end.to change(notification, :delivered).to(true)
|
31
|
+
store.should_receive(:mark_delivered).with(notification)
|
32
|
+
perform
|
31
33
|
end
|
32
34
|
|
33
35
|
it 'reflects the notification was delivered' do
|
@@ -51,11 +53,25 @@ describe Rapns::Daemon::Gcm::Delivery do
|
|
51
53
|
{ 'error' => 'NotRegistered' }
|
52
54
|
]}
|
53
55
|
response.stub(:body => JSON.dump(body))
|
56
|
+
store.should_receive(:mark_failed).with(notification, nil, "Failed to deliver to all recipients. Errors: NotRegistered.")
|
54
57
|
perform rescue Rapns::DeliveryError
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'reflects on canonical IDs' do
|
61
|
+
body = {
|
62
|
+
'failure' => 0,
|
63
|
+
'success' => 3,
|
64
|
+
'canonical_ids' => 1,
|
65
|
+
'results' => [
|
66
|
+
{ 'message_id' => '1:000' },
|
67
|
+
{ 'message_id' => '1:000', 'registration_id' => 'canonical123' },
|
68
|
+
{ 'message_id' => '1:000' },
|
69
|
+
]}
|
70
|
+
|
71
|
+
response.stub(:body => JSON.dump(body))
|
72
|
+
notification.stub(:registration_ids => ['1', '2', '3'])
|
73
|
+
delivery.should_receive(:reflect).with(:gcm_canonical_id, '2', 'canonical123')
|
74
|
+
perform
|
59
75
|
end
|
60
76
|
|
61
77
|
describe 'all deliveries returned Unavailable or InternalServerError' do
|
@@ -71,28 +87,23 @@ describe Rapns::Daemon::Gcm::Delivery do
|
|
71
87
|
|
72
88
|
it 'retries the notification respecting the Retry-After header' do
|
73
89
|
response.stub(:header => { 'retry-after' => 10 })
|
90
|
+
store.should_receive(:retry_after).with(notification, now + 10.seconds)
|
74
91
|
perform
|
75
|
-
notification.reload
|
76
|
-
notification.retries.should == 1
|
77
|
-
notification.deliver_after.should == now + 10.seconds
|
78
92
|
end
|
79
93
|
|
80
94
|
it 'retries the notification using exponential back-off if the Retry-After header is not present' do
|
81
|
-
|
95
|
+
store.should_receive(:retry_after).with(notification, now + 2)
|
82
96
|
perform
|
83
|
-
notification.reload
|
84
|
-
notification.retries.should == 9
|
85
|
-
notification.deliver_after.should == now + 2 ** 9
|
86
97
|
end
|
87
98
|
|
88
99
|
it 'does not mark the notification as failed' do
|
89
|
-
|
90
|
-
|
91
|
-
notification.reload
|
92
|
-
end.to_not change(notification, :failed).to(true)
|
100
|
+
store.should_not_receive(:mark_failed)
|
101
|
+
perform
|
93
102
|
end
|
94
103
|
|
95
104
|
it 'logs that the notification will be retried' do
|
105
|
+
notification.retries = 1
|
106
|
+
notification.deliver_after = now + 2
|
96
107
|
Rapns.logger.should_receive(:warn).with("All recipients unavailable. Notification #{notification.id} will be retired after 2012-10-14 00:00:02 (retry 1).")
|
97
108
|
perform
|
98
109
|
end
|
@@ -104,12 +115,8 @@ describe Rapns::Daemon::Gcm::Delivery do
|
|
104
115
|
before { response.stub(:body => JSON.dump(body)) }
|
105
116
|
|
106
117
|
it 'marks the original notification as failed' do
|
118
|
+
store.should_receive(:mark_failed).with(notification, nil, error_description)
|
107
119
|
perform rescue Rapns::DeliveryError
|
108
|
-
notification.reload
|
109
|
-
notification.failed.should be_true
|
110
|
-
notification.failed_at = now
|
111
|
-
notification.error_code.should be_nil
|
112
|
-
notification.error_description.should == error_description
|
113
120
|
end
|
114
121
|
|
115
122
|
it 'reflects the notification delivery failed' do
|
@@ -119,17 +126,11 @@ describe Rapns::Daemon::Gcm::Delivery do
|
|
119
126
|
|
120
127
|
it 'creates a new notification for the unavailable devices' do
|
121
128
|
notification.update_attributes(:registration_ids => ['id_0', 'id_1', 'id_2'], :data => {'one' => 1}, :collapse_key => 'thing', :delay_while_idle => true)
|
122
|
-
perform rescue Rapns::DeliveryError
|
123
|
-
new_notification.registration_ids.should == ['id_0', 'id_2']
|
124
|
-
new_notification.data.should == {'one' => 1}
|
125
|
-
new_notification.collapse_key.should == 'thing'
|
126
|
-
new_notification.delay_while_idle.should be_true
|
127
|
-
end
|
128
|
-
|
129
|
-
it 'sets the delivery time on the new notification to respect the Retry-After header' do
|
130
129
|
response.stub(:header => { 'retry-after' => 10 })
|
130
|
+
attrs = { 'collapse_key' => 'thing', 'delay_while_idle' => true, 'app_id' => app.id }
|
131
|
+
store.should_receive(:create_gcm_notification).with(attrs, notification.data,
|
132
|
+
['id_0', 'id_2'], now + 10.seconds, notification.app)
|
131
133
|
perform rescue Rapns::DeliveryError
|
132
|
-
new_notification.deliver_after.should == now + 10.seconds
|
133
134
|
end
|
134
135
|
|
135
136
|
it 'raises a DeliveryError' do
|
@@ -168,28 +169,27 @@ describe Rapns::Daemon::Gcm::Delivery do
|
|
168
169
|
before { response.stub(:code => 503) }
|
169
170
|
|
170
171
|
it 'logs a warning that the notification will be retried.' do
|
172
|
+
notification.retries = 1
|
173
|
+
notification.deliver_after = now + 2
|
171
174
|
logger.should_receive(:warn).with("GCM responded with an Service Unavailable Error. Notification #{notification.id} will be retired after 2012-10-14 00:00:02 (retry 1).")
|
172
175
|
perform
|
173
176
|
end
|
174
177
|
|
175
178
|
it 'respects an integer Retry-After header' do
|
176
179
|
response.stub(:header => { 'retry-after' => 10 })
|
177
|
-
|
178
|
-
|
179
|
-
end.to change(notification, :deliver_after).to(now + 10)
|
180
|
+
store.should_receive(:retry_after).with(notification, now + 10.seconds)
|
181
|
+
perform
|
180
182
|
end
|
181
183
|
|
182
184
|
it 'respects a HTTP-date Retry-After header' do
|
183
185
|
response.stub(:header => { 'retry-after' => 'Wed, 03 Oct 2012 20:55:11 GMT' })
|
184
|
-
|
185
|
-
|
186
|
-
end.to change(notification, :deliver_after).to(Time.parse('Wed, 03 Oct 2012 20:55:11 GMT'))
|
186
|
+
store.should_receive(:retry_after).with(notification, Time.parse('Wed, 03 Oct 2012 20:55:11 GMT'))
|
187
|
+
perform
|
187
188
|
end
|
188
189
|
|
189
190
|
it 'defaults to exponential back-off if the Retry-After header is not present' do
|
190
|
-
|
191
|
-
|
192
|
-
end.to change(notification, :deliver_after).to(now + 2 ** 1)
|
191
|
+
store.should_receive(:retry_after).with(notification, now + 2 ** 1)
|
192
|
+
perform
|
193
193
|
end
|
194
194
|
|
195
195
|
it 'reflects the notification will be retried' do
|
@@ -205,15 +205,15 @@ describe Rapns::Daemon::Gcm::Delivery do
|
|
205
205
|
end
|
206
206
|
|
207
207
|
it 'logs a warning that the notification has been re-queued.' do
|
208
|
+
notification.retries = 3
|
209
|
+
notification.deliver_after = now + 2 ** 3
|
208
210
|
Rapns.logger.should_receive(:warn).with("GCM responded with an Internal Error. Notification #{notification.id} will be retired after #{(now + 2 ** 3).strftime("%Y-%m-%d %H:%M:%S")} (retry 3).")
|
209
211
|
perform
|
210
212
|
end
|
211
213
|
|
212
|
-
it '
|
213
|
-
|
214
|
-
|
215
|
-
notification.reload
|
216
|
-
end.to change(notification, :deliver_after).to(now + 2 ** 3)
|
214
|
+
it 'retries the notification in accordance with the exponential back-off strategy.' do
|
215
|
+
store.should_receive(:retry_after).with(notification, now + 2 ** 3)
|
216
|
+
perform
|
217
217
|
end
|
218
218
|
|
219
219
|
it 'reflects the notification will be retried' do
|
@@ -234,12 +234,8 @@ describe Rapns::Daemon::Gcm::Delivery do
|
|
234
234
|
before { response.stub(:code => 400) }
|
235
235
|
|
236
236
|
it 'marks the notification as failed' do
|
237
|
+
store.should_receive(:mark_failed).with(notification, 400, 'GCM failed to parse the JSON request. Possibly an rapns bug, please open an issue.')
|
237
238
|
perform rescue Rapns::DeliveryError
|
238
|
-
notification.reload
|
239
|
-
notification.failed.should be_true
|
240
|
-
notification.failed_at.should == now
|
241
|
-
notification.error_code.should == 400
|
242
|
-
notification.error_description.should == 'GCM failed to parse the JSON request. Possibly an rapns bug, please open an issue.'
|
243
239
|
end
|
244
240
|
|
245
241
|
it 'reflects the notification delivery failed' do
|
@@ -252,12 +248,8 @@ describe Rapns::Daemon::Gcm::Delivery do
|
|
252
248
|
before { response.stub(:code => 418) }
|
253
249
|
|
254
250
|
it 'marks the notification as failed' do
|
251
|
+
store.should_receive(:mark_failed).with(notification, 418, "I'm a Teapot")
|
255
252
|
perform rescue Rapns::DeliveryError
|
256
|
-
notification.reload
|
257
|
-
notification.failed.should be_true
|
258
|
-
notification.failed_at.should == now
|
259
|
-
notification.error_code.should == 418
|
260
|
-
notification.error_description.should == "I'm a Teapot"
|
261
253
|
end
|
262
254
|
|
263
255
|
it 'reflects the notification delivery failed' do
|