rpush 2.3.1 → 2.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +36 -28
- data/lib/rpush/configuration.rb +1 -0
- data/lib/rpush/daemon/feeder.rb +16 -12
- data/lib/rpush/daemon/interruptible_sleep.rb +26 -5
- data/lib/rpush/daemon/store/active_record.rb +4 -0
- data/lib/rpush/daemon/store/interface.rb +1 -1
- data/lib/rpush/daemon/store/redis.rb +10 -0
- data/lib/rpush/embed.rb +1 -0
- data/lib/rpush/logger.rb +1 -0
- data/lib/rpush/push.rb +1 -2
- data/lib/rpush/version.rb +1 -1
- data/spec/functional/adm_spec.rb +6 -8
- data/spec/functional/apns_spec.rb +9 -9
- data/spec/functional/embed_spec.rb +3 -3
- data/spec/functional/gcm_spec.rb +6 -8
- data/spec/functional/new_app_spec.rb +5 -20
- data/spec/functional/retry_spec.rb +8 -12
- data/spec/functional/synchronization_spec.rb +1 -1
- data/spec/functional/wpns_spec.rb +7 -7
- data/spec/functional_spec_helper.rb +4 -5
- data/spec/spec_helper.rb +1 -1
- data/spec/unit/apns_feedback_spec.rb +4 -4
- data/spec/unit/client/active_record/adm/app_spec.rb +12 -12
- data/spec/unit/client/active_record/adm/notification_spec.rb +9 -9
- data/spec/unit/client/active_record/apns/app_spec.rb +4 -4
- data/spec/unit/client/active_record/apns/feedback_spec.rb +2 -2
- data/spec/unit/client/active_record/apns/notification_spec.rb +46 -46
- data/spec/unit/client/active_record/app_spec.rb +6 -6
- data/spec/unit/client/active_record/gcm/notification_spec.rb +7 -7
- data/spec/unit/client/active_record/notification_spec.rb +2 -2
- data/spec/unit/client/active_record/wpns/notification_spec.rb +2 -8
- data/spec/unit/configuration_spec.rb +5 -5
- data/spec/unit/daemon/adm/delivery_spec.rb +69 -69
- data/spec/unit/daemon/apns/delivery_spec.rb +13 -13
- data/spec/unit/daemon/apns/feedback_receiver_spec.rb +24 -26
- data/spec/unit/daemon/app_runner_spec.rb +29 -29
- data/spec/unit/daemon/batch_spec.rb +30 -30
- data/spec/unit/daemon/delivery_error_spec.rb +2 -2
- data/spec/unit/daemon/delivery_spec.rb +6 -6
- data/spec/unit/daemon/dispatcher/http_spec.rb +5 -5
- data/spec/unit/daemon/dispatcher/tcp_spec.rb +4 -4
- data/spec/unit/daemon/dispatcher_loop_spec.rb +9 -9
- data/spec/unit/daemon/feeder_spec.rb +22 -23
- data/spec/unit/daemon/gcm/delivery_spec.rb +56 -56
- data/spec/unit/daemon/retryable_error_spec.rb +2 -2
- data/spec/unit/daemon/service_config_methods_spec.rb +5 -5
- data/spec/unit/daemon/signal_handler_spec.rb +13 -13
- data/spec/unit/daemon/store/active_record/reconnectable_spec.rb +13 -13
- data/spec/unit/daemon/store/active_record_spec.rb +49 -49
- data/spec/unit/daemon/tcp_connection_spec.rb +50 -50
- data/spec/unit/daemon/wpns/delivery_spec.rb +36 -36
- data/spec/unit/daemon_spec.rb +33 -30
- data/spec/unit/deprecatable_spec.rb +3 -3
- data/spec/unit/deprecation_spec.rb +2 -2
- data/spec/unit/embed_spec.rb +7 -7
- data/spec/unit/logger_spec.rb +25 -25
- data/spec/unit/notification_shared.rb +7 -7
- data/spec/unit/plugin_spec.rb +1 -1
- data/spec/unit/push_spec.rb +8 -8
- data/spec/unit/reflectable_spec.rb +5 -5
- data/spec/unit/reflection_collection_spec.rb +2 -2
- data/spec/unit/rpush_spec.rb +1 -1
- data/spec/unit_spec_helper.rb +4 -5
- metadata +10 -4
@@ -15,94 +15,94 @@ describe Rpush::Daemon::TcpConnection do
|
|
15
15
|
let(:connection) { Rpush::Daemon::TcpConnection.new(app, host, port) }
|
16
16
|
|
17
17
|
before do
|
18
|
-
OpenSSL::SSL::SSLContext.
|
19
|
-
OpenSSL::PKey::RSA.
|
20
|
-
OpenSSL::X509::Certificate.
|
21
|
-
TCPSocket.
|
22
|
-
OpenSSL::SSL::SSLSocket.
|
23
|
-
Rpush.
|
24
|
-
connection.
|
18
|
+
allow(OpenSSL::SSL::SSLContext).to receive_messages(new: ssl_context)
|
19
|
+
allow(OpenSSL::PKey::RSA).to receive_messages(new: rsa_key)
|
20
|
+
allow(OpenSSL::X509::Certificate).to receive_messages(new: x509_certificate)
|
21
|
+
allow(TCPSocket).to receive_messages(new: tcp_socket)
|
22
|
+
allow(OpenSSL::SSL::SSLSocket).to receive_messages(new: ssl_socket)
|
23
|
+
allow(Rpush).to receive_messages(logger: logger)
|
24
|
+
allow(connection).to receive(:reflect)
|
25
25
|
end
|
26
26
|
|
27
27
|
it "reads the number of bytes from the SSL socket" do
|
28
|
-
ssl_socket.
|
28
|
+
expect(ssl_socket).to receive(:read).with(123)
|
29
29
|
connection.connect
|
30
30
|
connection.read(123)
|
31
31
|
end
|
32
32
|
|
33
33
|
it "selects on the SSL socket until the given timeout" do
|
34
|
-
IO.
|
34
|
+
expect(IO).to receive(:select).with([ssl_socket], nil, nil, 10)
|
35
35
|
connection.connect
|
36
36
|
connection.select(10)
|
37
37
|
end
|
38
38
|
|
39
39
|
describe "when setting up the SSL context" do
|
40
40
|
it "sets the key on the context" do
|
41
|
-
OpenSSL::PKey::RSA.
|
42
|
-
ssl_context.
|
41
|
+
expect(OpenSSL::PKey::RSA).to receive(:new).with(certificate, password).and_return(rsa_key)
|
42
|
+
expect(ssl_context).to receive(:key=).with(rsa_key)
|
43
43
|
connection.connect
|
44
44
|
end
|
45
45
|
|
46
46
|
it "sets the cert on the context" do
|
47
|
-
OpenSSL::X509::Certificate.
|
48
|
-
ssl_context.
|
47
|
+
expect(OpenSSL::X509::Certificate).to receive(:new).with(certificate).and_return(x509_certificate)
|
48
|
+
expect(ssl_context).to receive(:cert=).with(x509_certificate)
|
49
49
|
connection.connect
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
53
|
describe "when connecting the socket" do
|
54
54
|
it "creates a TCP socket using the configured host and port" do
|
55
|
-
TCPSocket.
|
55
|
+
expect(TCPSocket).to receive(:new).with(host, port).and_return(tcp_socket)
|
56
56
|
connection.connect
|
57
57
|
end
|
58
58
|
|
59
59
|
it "creates a new SSL socket using the TCP socket and SSL context" do
|
60
|
-
OpenSSL::SSL::SSLSocket.
|
60
|
+
expect(OpenSSL::SSL::SSLSocket).to receive(:new).with(tcp_socket, ssl_context).and_return(ssl_socket)
|
61
61
|
connection.connect
|
62
62
|
end
|
63
63
|
|
64
64
|
it "sets the sync option on the SSL socket" do
|
65
|
-
ssl_socket.
|
65
|
+
expect(ssl_socket).to receive(:sync=).with(true)
|
66
66
|
connection.connect
|
67
67
|
end
|
68
68
|
|
69
69
|
it "connects the SSL socket" do
|
70
|
-
ssl_socket.
|
70
|
+
expect(ssl_socket).to receive(:connect)
|
71
71
|
connection.connect
|
72
72
|
end
|
73
73
|
|
74
74
|
it "sets the socket option TCP_NODELAY" do
|
75
|
-
tcp_socket.
|
75
|
+
expect(tcp_socket).to receive(:setsockopt).with(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, true)
|
76
76
|
connection.connect
|
77
77
|
end
|
78
78
|
|
79
79
|
it "sets the socket option SO_KEEPALIVE" do
|
80
|
-
tcp_socket.
|
80
|
+
expect(tcp_socket).to receive(:setsockopt).with(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
|
81
81
|
connection.connect
|
82
82
|
end
|
83
83
|
|
84
84
|
describe 'certificate expiry' do
|
85
85
|
it 'reflects if the certificate will expire soon' do
|
86
86
|
cert = OpenSSL::X509::Certificate.new(app.certificate)
|
87
|
-
connection.
|
87
|
+
expect(connection).to receive(:reflect).with(:ssl_certificate_will_expire, app, cert.not_after)
|
88
88
|
Timecop.freeze(cert.not_after - 3.days) { connection.connect }
|
89
89
|
end
|
90
90
|
|
91
91
|
it 'logs that the certificate will expire soon' do
|
92
92
|
cert = OpenSSL::X509::Certificate.new(app.certificate)
|
93
|
-
logger.
|
93
|
+
expect(logger).to receive(:warn).with("[#{app.name}] Certificate will expire at 2022-09-07 03:18:32 UTC.")
|
94
94
|
Timecop.freeze(cert.not_after - 3.days) { connection.connect }
|
95
95
|
end
|
96
96
|
|
97
97
|
it 'does not reflect if the certificate will not expire soon' do
|
98
98
|
cert = OpenSSL::X509::Certificate.new(app.certificate)
|
99
|
-
connection.
|
99
|
+
expect(connection).not_to receive(:reflect).with(:ssl_certificate_will_expire, app, kind_of(Time))
|
100
100
|
Timecop.freeze(cert.not_after - 2.months) { connection.connect }
|
101
101
|
end
|
102
102
|
|
103
103
|
it 'logs that the certificate has expired' do
|
104
104
|
cert = OpenSSL::X509::Certificate.new(app.certificate)
|
105
|
-
logger.
|
105
|
+
expect(logger).to receive(:error).with("[#{app.name}] Certificate expired at 2022-09-07 03:18:32 UTC.")
|
106
106
|
Timecop.freeze(cert.not_after + 1.day) { connection.connect rescue Rpush::CertificateExpiredError }
|
107
107
|
end
|
108
108
|
|
@@ -117,16 +117,16 @@ describe Rpush::Daemon::TcpConnection do
|
|
117
117
|
describe 'certificate revocation' do
|
118
118
|
let(:cert_revoked_error) { OpenSSL::SSL::SSLError.new('certificate revoked') }
|
119
119
|
before do
|
120
|
-
ssl_socket.
|
120
|
+
allow(ssl_socket).to receive(:connect).and_raise(cert_revoked_error)
|
121
121
|
end
|
122
122
|
|
123
123
|
it 'reflects that the certificate has been revoked' do
|
124
|
-
connection.
|
124
|
+
expect(connection).to receive(:reflect).with(:ssl_certificate_revoked, app, cert_revoked_error)
|
125
125
|
expect { connection.connect }.to raise_error(Rpush::Daemon::TcpConnectionError, 'OpenSSL::SSL::SSLError, certificate revoked')
|
126
126
|
end
|
127
127
|
|
128
128
|
it 'logs that the certificate has been revoked' do
|
129
|
-
logger.
|
129
|
+
expect(logger).to receive(:warn).with('[Connection 0] Certificate has been revoked.')
|
130
130
|
expect { connection.connect }.to raise_error(Rpush::Daemon::TcpConnectionError, 'OpenSSL::SSL::SSLError, certificate revoked')
|
131
131
|
end
|
132
132
|
end
|
@@ -135,32 +135,32 @@ describe Rpush::Daemon::TcpConnection do
|
|
135
135
|
describe "when shuting down the connection" do
|
136
136
|
it "closes the TCP socket" do
|
137
137
|
connection.connect
|
138
|
-
tcp_socket.
|
138
|
+
expect(tcp_socket).to receive(:close)
|
139
139
|
connection.close
|
140
140
|
end
|
141
141
|
|
142
142
|
it "does not attempt to close the TCP socket if it is not connected" do
|
143
143
|
connection.connect
|
144
|
-
tcp_socket.
|
144
|
+
expect(tcp_socket).not_to receive(:close)
|
145
145
|
connection.instance_variable_set("@tcp_socket", nil)
|
146
146
|
connection.close
|
147
147
|
end
|
148
148
|
|
149
149
|
it "closes the SSL socket" do
|
150
150
|
connection.connect
|
151
|
-
ssl_socket.
|
151
|
+
expect(ssl_socket).to receive(:close)
|
152
152
|
connection.close
|
153
153
|
end
|
154
154
|
|
155
155
|
it "does not attempt to close the SSL socket if it is not connected" do
|
156
156
|
connection.connect
|
157
|
-
ssl_socket.
|
157
|
+
expect(ssl_socket).not_to receive(:close)
|
158
158
|
connection.instance_variable_set("@ssl_socket", nil)
|
159
159
|
connection.close
|
160
160
|
end
|
161
161
|
|
162
162
|
it "ignores IOError when the socket is already closed" do
|
163
|
-
tcp_socket.
|
163
|
+
allow(tcp_socket).to receive(:close).and_raise(IOError)
|
164
164
|
connection.connect
|
165
165
|
connection.close
|
166
166
|
end
|
@@ -168,23 +168,23 @@ describe Rpush::Daemon::TcpConnection do
|
|
168
168
|
|
169
169
|
shared_examples_for "when the write fails" do
|
170
170
|
before do
|
171
|
-
connection.
|
171
|
+
allow(connection).to receive(:sleep)
|
172
172
|
connection.connect
|
173
|
-
ssl_socket.
|
173
|
+
allow(ssl_socket).to receive(:write).and_raise(error)
|
174
174
|
end
|
175
175
|
|
176
176
|
it 'reflects the connection has been lost' do
|
177
|
-
connection.
|
177
|
+
expect(connection).to receive(:reflect).with(:tcp_connection_lost, app, kind_of(error.class))
|
178
178
|
expect { connection.write(nil) }.to raise_error(Rpush::Daemon::TcpConnectionError)
|
179
179
|
end
|
180
180
|
|
181
181
|
it "logs that the connection has been lost once only" do
|
182
|
-
logger.
|
182
|
+
expect(logger).to receive(:error).with("[Connection 0] Lost connection to gateway.push.apple.com:2195 (#{error.class.name}, #{error.message}), reconnecting...").once
|
183
183
|
expect { connection.write(nil) }.to raise_error(Rpush::Daemon::TcpConnectionError)
|
184
184
|
end
|
185
185
|
|
186
186
|
it "retries to make a connection 3 times" do
|
187
|
-
connection.
|
187
|
+
expect(connection).to receive(:reconnect).exactly(3).times
|
188
188
|
expect { connection.write(nil) }.to raise_error(Rpush::Daemon::TcpConnectionError)
|
189
189
|
end
|
190
190
|
|
@@ -195,7 +195,7 @@ describe Rpush::Daemon::TcpConnection do
|
|
195
195
|
end
|
196
196
|
|
197
197
|
it "sleeps 1 second before retrying the connection" do
|
198
|
-
connection.
|
198
|
+
expect(connection).to receive(:sleep).with(1)
|
199
199
|
expect { connection.write(nil) }.to raise_error(Rpush::Daemon::TcpConnectionError)
|
200
200
|
end
|
201
201
|
end
|
@@ -236,12 +236,12 @@ describe Rpush::Daemon::TcpConnection do
|
|
236
236
|
before { connection.connect }
|
237
237
|
|
238
238
|
it 'closes the socket' do
|
239
|
-
connection.
|
239
|
+
expect(connection).to receive(:close)
|
240
240
|
connection.send(:reconnect)
|
241
241
|
end
|
242
242
|
|
243
243
|
it 'connects the socket' do
|
244
|
-
connection.
|
244
|
+
expect(connection).to receive(:connect_socket)
|
245
245
|
connection.send(:reconnect)
|
246
246
|
end
|
247
247
|
end
|
@@ -250,12 +250,12 @@ describe Rpush::Daemon::TcpConnection do
|
|
250
250
|
before { connection.connect }
|
251
251
|
|
252
252
|
it "writes the data to the SSL socket" do
|
253
|
-
ssl_socket.
|
253
|
+
expect(ssl_socket).to receive(:write).with("blah")
|
254
254
|
connection.write("blah")
|
255
255
|
end
|
256
256
|
|
257
257
|
it "flushes the SSL socket" do
|
258
|
-
ssl_socket.
|
258
|
+
expect(ssl_socket).to receive(:flush)
|
259
259
|
connection.write("blah")
|
260
260
|
end
|
261
261
|
end
|
@@ -264,28 +264,28 @@ describe Rpush::Daemon::TcpConnection do
|
|
264
264
|
before { connection.connect }
|
265
265
|
|
266
266
|
it 'reconnects if the connection has been idle for more than the defined period' do
|
267
|
-
Rpush::Daemon::TcpConnection.
|
268
|
-
Time.
|
269
|
-
connection.
|
267
|
+
allow(Rpush::Daemon::TcpConnection).to receive_messages(idle_period: 60)
|
268
|
+
allow(Time).to receive_messages(now: Time.now + 61)
|
269
|
+
expect(connection).to receive(:reconnect)
|
270
270
|
connection.write('blah')
|
271
271
|
end
|
272
272
|
|
273
273
|
it 'resets the last touch time' do
|
274
274
|
now = Time.now
|
275
|
-
Time.
|
275
|
+
allow(Time).to receive_messages(now: now)
|
276
276
|
connection.write('blah')
|
277
|
-
connection.last_touch.
|
277
|
+
expect(connection.last_touch).to eq now
|
278
278
|
end
|
279
279
|
|
280
280
|
it 'does not reconnect if the connection has not been idle for more than the defined period' do
|
281
|
-
connection.
|
281
|
+
expect(connection).not_to receive(:reconnect)
|
282
282
|
connection.write('blah')
|
283
283
|
end
|
284
284
|
|
285
285
|
it 'logs the the connection is idle' do
|
286
|
-
Rpush::Daemon::TcpConnection.
|
287
|
-
Time.
|
288
|
-
Rpush.logger.
|
286
|
+
allow(Rpush::Daemon::TcpConnection).to receive_messages(idle_period: 60)
|
287
|
+
allow(Time).to receive_messages(now: Time.now + 61)
|
288
|
+
expect(Rpush.logger).to receive(:info).with('[Connection 0] Idle period exceeded, reconnecting...')
|
289
289
|
connection.write('blah')
|
290
290
|
end
|
291
291
|
end
|
@@ -20,20 +20,20 @@ describe Rpush::Daemon::Wpns::Delivery do
|
|
20
20
|
end
|
21
21
|
|
22
22
|
before do
|
23
|
-
delivery.
|
24
|
-
Rpush::Daemon.
|
25
|
-
Time.
|
26
|
-
Rpush.
|
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
27
|
end
|
28
28
|
|
29
29
|
shared_examples_for "an notification with some delivery faliures" do
|
30
30
|
let(:new_notification) { Rpush::Wpns::Notification.where('id != ?', notification.id).first }
|
31
31
|
|
32
|
-
before { response.
|
32
|
+
before { allow(response).to receive_messages(body: JSON.dump(body)) }
|
33
33
|
|
34
34
|
it "marks the original notification falied" do
|
35
|
-
delivery.
|
36
|
-
error.message.
|
35
|
+
expect(delivery).to receive(:mark_failed) do |error|
|
36
|
+
expect(error.message).to match(error_description)
|
37
37
|
end
|
38
38
|
perform_with_rescue
|
39
39
|
end
|
@@ -45,122 +45,122 @@ describe Rpush::Daemon::Wpns::Delivery do
|
|
45
45
|
|
46
46
|
describe "an 200 response" do
|
47
47
|
before do
|
48
|
-
response.
|
48
|
+
allow(response).to receive_messages(code: 200)
|
49
49
|
end
|
50
50
|
|
51
51
|
it "marks the notification as delivered if delivered successfully to all devices" do
|
52
|
-
response.
|
53
|
-
response.
|
54
|
-
batch.
|
52
|
+
allow(response).to receive_messages(body: JSON.dump("failure" => 0))
|
53
|
+
allow(response).to receive_messages(to_hash: { "x-notificationstatus" => ["Received"] })
|
54
|
+
expect(batch).to receive(:mark_delivered).with(notification)
|
55
55
|
perform
|
56
56
|
end
|
57
57
|
|
58
58
|
it "retries the notification when the queue is full" do
|
59
|
-
response.
|
60
|
-
response.
|
61
|
-
batch.
|
59
|
+
allow(response).to receive_messages(body: JSON.dump("failure" => 0))
|
60
|
+
allow(response).to receive_messages(to_hash: { "x-notificationstatus" => ["QueueFull"] })
|
61
|
+
expect(batch).to receive(:mark_retryable).with(notification, Time.now + (60 * 10))
|
62
62
|
perform
|
63
63
|
end
|
64
64
|
|
65
65
|
it "marks the notification as failed if the notification is suppressed" do
|
66
|
-
response.
|
67
|
-
response.
|
66
|
+
allow(response).to receive_messages(body: JSON.dump("faliure" => 0))
|
67
|
+
allow(response).to receive_messages(to_hash: { "x-notificationstatus" => ["Suppressed"] })
|
68
68
|
error = Rpush::DeliveryError.new(200, notification.id, 'Notification was received but suppressed by the service.')
|
69
|
-
delivery.
|
69
|
+
expect(delivery).to receive(:mark_failed).with(error)
|
70
70
|
perform_with_rescue
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
74
|
describe "an 400 response" do
|
75
|
-
before { response.
|
75
|
+
before { allow(response).to receive_messages(code: 400) }
|
76
76
|
it "marks notifications as failed" do
|
77
77
|
error = Rpush::DeliveryError.new(400, notification.id, 'Bad XML or malformed notification URI.')
|
78
|
-
delivery.
|
78
|
+
expect(delivery).to receive(:mark_failed).with(error)
|
79
79
|
perform_with_rescue
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
83
|
describe "an 401 response" do
|
84
|
-
before { response.
|
84
|
+
before { allow(response).to receive_messages(code: 401) }
|
85
85
|
it "marks notifications as failed" do
|
86
86
|
error = Rpush::DeliveryError.new(401, notification.id, 'Unauthorized to send a notification to this app.')
|
87
|
-
delivery.
|
87
|
+
expect(delivery).to receive(:mark_failed).with(error)
|
88
88
|
perform_with_rescue
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
92
|
describe "an 404 response" do
|
93
|
-
before { response.
|
93
|
+
before { allow(response).to receive_messages(code: 404) }
|
94
94
|
it "marks notifications as failed" do
|
95
95
|
error = Rpush::DeliveryError.new(404, notification.id, 'Not Found')
|
96
|
-
delivery.
|
96
|
+
expect(delivery).to receive(:mark_failed).with(error)
|
97
97
|
perform_with_rescue
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
101
101
|
describe "an 405 response" do
|
102
|
-
before { response.
|
102
|
+
before { allow(response).to receive_messages(code: 405) }
|
103
103
|
it "marks notifications as failed" do
|
104
104
|
error = Rpush::DeliveryError.new(405, notification.id, 'Method Not Allowed')
|
105
|
-
delivery.
|
105
|
+
expect(delivery).to receive(:mark_failed).with(error)
|
106
106
|
perform_with_rescue
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
110
110
|
describe "an 406 response" do
|
111
|
-
before { response.
|
111
|
+
before { allow(response).to receive_messages(code: 406) }
|
112
112
|
|
113
113
|
it "retries the notification" do
|
114
|
-
batch.
|
114
|
+
expect(batch).to receive(:mark_retryable).with(notification, Time.now + (60 * 60))
|
115
115
|
perform
|
116
116
|
end
|
117
117
|
|
118
118
|
it "logs a warning that the notification will be retried" do
|
119
119
|
notification.retries = 1
|
120
120
|
notification.deliver_after = now + 2
|
121
|
-
logger.
|
121
|
+
expect(logger).to receive(:warn).with("[MyApp] Per-day throttling limit reached. Notification #{notification.id} will be retried after 2012-10-14 00:00:02 (retry 1).")
|
122
122
|
perform
|
123
123
|
end
|
124
124
|
end
|
125
125
|
|
126
126
|
describe "an 412 response" do
|
127
|
-
before { response.
|
127
|
+
before { allow(response).to receive_messages(code: 412) }
|
128
128
|
|
129
129
|
it "retries the notification" do
|
130
|
-
batch.
|
130
|
+
expect(batch).to receive(:mark_retryable).with(notification, Time.now + (60 * 60))
|
131
131
|
perform
|
132
132
|
end
|
133
133
|
|
134
134
|
it "logs a warning that the notification will be retried" do
|
135
135
|
notification.retries = 1
|
136
136
|
notification.deliver_after = now + 2
|
137
|
-
logger.
|
137
|
+
expect(logger).to receive(:warn).with("[MyApp] Device unreachable. Notification #{notification.id} will be retried after 2012-10-14 00:00:02 (retry 1).")
|
138
138
|
perform
|
139
139
|
end
|
140
140
|
end
|
141
141
|
|
142
142
|
describe "an 503 response" do
|
143
|
-
before { response.
|
143
|
+
before { allow(response).to receive_messages(code: 503) }
|
144
144
|
|
145
145
|
it "retries the notification exponentially" do
|
146
|
-
delivery.
|
146
|
+
expect(delivery).to receive(:mark_retryable_exponential).with(notification)
|
147
147
|
perform
|
148
148
|
end
|
149
149
|
|
150
150
|
it 'logs a warning that the notification will be retried.' do
|
151
151
|
notification.retries = 1
|
152
152
|
notification.deliver_after = now + 2
|
153
|
-
logger.
|
153
|
+
expect(logger).to receive(:warn).with("[MyApp] Service Unavailable. Notification #{notification.id} will be retried after 2012-10-14 00:00:02 (retry 1).")
|
154
154
|
perform
|
155
155
|
end
|
156
156
|
end
|
157
157
|
|
158
158
|
describe 'an un-handled response' do
|
159
|
-
before { response.
|
159
|
+
before { allow(response).to receive_messages(code: 418) }
|
160
160
|
|
161
161
|
it 'marks the notification as failed' do
|
162
162
|
error = Rpush::DeliveryError.new(418, notification.id, "I'm a Teapot")
|
163
|
-
delivery.
|
163
|
+
expect(delivery).to receive(:mark_failed).with(error)
|
164
164
|
perform_with_rescue
|
165
165
|
end
|
166
166
|
end
|