rapns 3.3.2-java → 3.4.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/CHANGELOG.md +7 -0
  2. data/README.md +19 -21
  3. data/bin/rapns +14 -13
  4. data/lib/generators/templates/rapns.rb +8 -4
  5. data/lib/rapns.rb +7 -0
  6. data/lib/rapns/TODO +3 -0
  7. data/lib/rapns/apns/feedback.rb +4 -2
  8. data/lib/rapns/app.rb +3 -1
  9. data/lib/rapns/configuration.rb +8 -1
  10. data/lib/rapns/daemon.rb +3 -1
  11. data/lib/rapns/daemon/apns/app_runner.rb +3 -2
  12. data/lib/rapns/daemon/apns/certificate_expired_error.rb +20 -0
  13. data/lib/rapns/daemon/apns/connection.rb +26 -0
  14. data/lib/rapns/daemon/apns/delivery.rb +2 -1
  15. data/lib/rapns/daemon/apns/delivery_handler.rb +2 -2
  16. data/lib/rapns/daemon/app_runner.rb +50 -28
  17. data/lib/rapns/daemon/batch.rb +100 -0
  18. data/lib/rapns/daemon/delivery.rb +6 -10
  19. data/lib/rapns/daemon/delivery_handler.rb +14 -12
  20. data/lib/rapns/daemon/delivery_handler_collection.rb +33 -0
  21. data/lib/rapns/daemon/feeder.rb +3 -5
  22. data/lib/rapns/daemon/gcm/delivery.rb +5 -4
  23. data/lib/rapns/daemon/gcm/delivery_handler.rb +2 -2
  24. data/lib/rapns/daemon/store/active_record.rb +23 -2
  25. data/lib/rapns/deprecation.rb +7 -6
  26. data/lib/rapns/logger.rb +1 -1
  27. data/lib/rapns/notification.rb +5 -3
  28. data/lib/rapns/reflection.rb +1 -1
  29. data/lib/rapns/version.rb +1 -1
  30. data/lib/tasks/cane.rake +1 -1
  31. data/lib/tasks/test.rake +8 -3
  32. data/spec/unit/apns/app_spec.rb +4 -4
  33. data/spec/unit/apns_feedback_spec.rb +1 -1
  34. data/spec/unit/configuration_spec.rb +12 -6
  35. data/spec/unit/daemon/apns/app_runner_spec.rb +6 -4
  36. data/spec/unit/daemon/apns/certificate_expired_error_spec.rb +11 -0
  37. data/spec/unit/daemon/apns/connection_spec.rb +46 -10
  38. data/spec/unit/daemon/apns/delivery_handler_spec.rb +24 -18
  39. data/spec/unit/daemon/apns/delivery_spec.rb +11 -12
  40. data/spec/unit/daemon/apns/feedback_receiver_spec.rb +16 -16
  41. data/spec/unit/daemon/app_runner_shared.rb +27 -10
  42. data/spec/unit/daemon/app_runner_spec.rb +48 -28
  43. data/spec/unit/daemon/batch_spec.rb +160 -0
  44. data/spec/unit/daemon/delivery_handler_collection_spec.rb +37 -0
  45. data/spec/unit/daemon/delivery_handler_shared.rb +20 -11
  46. data/spec/unit/daemon/feeder_spec.rb +12 -12
  47. data/spec/unit/daemon/gcm/app_runner_spec.rb +4 -2
  48. data/spec/unit/daemon/gcm/delivery_handler_spec.rb +18 -10
  49. data/spec/unit/daemon/gcm/delivery_spec.rb +47 -17
  50. data/spec/unit/daemon/interruptible_sleep_spec.rb +3 -3
  51. data/spec/unit/daemon/reflectable_spec.rb +1 -1
  52. data/spec/unit/daemon/store/active_record/reconnectable_spec.rb +1 -1
  53. data/spec/unit/daemon/store/active_record_spec.rb +87 -10
  54. data/spec/unit/daemon_spec.rb +6 -6
  55. data/spec/unit/deprecation_spec.rb +2 -2
  56. data/spec/unit/logger_spec.rb +33 -17
  57. data/spec/unit/notification_shared.rb +7 -3
  58. data/spec/unit/upgraded_spec.rb +8 -14
  59. data/spec/unit_spec_helper.rb +9 -1
  60. metadata +53 -44
  61. data/lib/rapns/daemon/delivery_queue.rb +0 -42
  62. data/lib/rapns/daemon/delivery_queue_18.rb +0 -44
  63. data/lib/rapns/daemon/delivery_queue_19.rb +0 -42
  64. data/spec/acceptance/gcm_upgrade_spec.rb +0 -34
  65. data/spec/acceptance_spec_helper.rb +0 -85
  66. data/spec/unit/daemon/delivery_queue_spec.rb +0 -29
@@ -2,7 +2,7 @@ require 'unit_spec_helper'
2
2
 
3
3
  describe Rapns, 'apns_feedback' do
4
4
  let!(:app) { Rapns::Apns::App.create!(:name => 'test', :environment => 'production', :certificate => TEST_CERT) }
5
- let(:receiver) { stub(:check_for_feedback => nil) }
5
+ let(:receiver) { double(:check_for_feedback => nil) }
6
6
 
7
7
  before do
8
8
  Rapns::Daemon::Apns::FeedbackReceiver.stub(:new => receiver)
@@ -1,7 +1,7 @@
1
1
  require 'unit_spec_helper'
2
2
 
3
3
  describe Rapns do
4
- let(:config) { stub }
4
+ let(:config) { double }
5
5
 
6
6
  before { Rapns.stub(:config => config) }
7
7
 
@@ -11,20 +11,26 @@ describe Rapns do
11
11
  end
12
12
 
13
13
  describe Rapns::Configuration do
14
- let(:config) { Rapns::Configuration.new }
14
+ let(:config) do
15
+ Rapns::Deprecation.muted do
16
+ Rapns::Configuration.new
17
+ end
18
+ end
15
19
 
16
20
  it 'configures a feedback callback' do
17
21
  b = Proc.new {}
18
- Rapns::Deprecation.silenced do
22
+ Rapns::Deprecation.muted do
19
23
  config.on_apns_feedback(&b)
20
24
  end
21
25
  config.apns_feedback_callback.should == b
22
26
  end
23
27
 
24
28
  it 'can be updated' do
25
- new_config = Rapns::Configuration.new
26
- new_config.batch_size = 100
27
- expect { config.update(new_config) }.to change(config, :batch_size).to(100)
29
+ Rapns::Deprecation.muted do
30
+ new_config = Rapns::Configuration.new
31
+ new_config.batch_size = 100
32
+ expect { config.update(new_config) }.to change(config, :batch_size).to(100)
33
+ end
28
34
  end
29
35
 
30
36
  it 'sets the pid_file relative if not absolute' do
@@ -8,14 +8,16 @@ describe Rapns::Daemon::Apns::AppRunner do
8
8
  let(:app) { app_class.create!(:name => 'my_app', :environment => 'development',
9
9
  :certificate => TEST_CERT, :password => 'pass') }
10
10
  let(:runner) { Rapns::Daemon::Apns::AppRunner.new(app) }
11
- let(:handler) { stub(:start => nil, :stop => nil, :queue= => nil) }
12
- let(:receiver) { stub(:start => nil, :stop => nil) }
13
- let(:config) { stub(:feedback_poll => 60, :push => false) }
14
- let(:logger) { stub(:info => nil) }
11
+ let(:handler) { double(:start => nil, :queue= => nil, :wakeup => nil, :wait => nil, :stop => nil) }
12
+ let(:handler_collection) { double(:handler_collection, :push => nil, :size => 1, :stop => nil) }
13
+ let(:receiver) { double(:start => nil, :stop => nil) }
14
+ let(:config) { double(:feedback_poll => 60, :push => false) }
15
+ let(:logger) { double(:info => nil, :warn => nil, :error => nil) }
15
16
 
16
17
  before do
17
18
  Rapns.stub(:logger => logger, :config => config)
18
19
  Rapns::Daemon::Apns::DeliveryHandler.stub(:new => handler)
20
+ Rapns::Daemon::DeliveryHandlerCollection.stub(:new => handler_collection)
19
21
  Rapns::Daemon::Apns::FeedbackReceiver.stub(:new => receiver)
20
22
  end
21
23
 
@@ -0,0 +1,11 @@
1
+ require 'unit_spec_helper'
2
+
3
+ describe Rapns::Apns::CertificateExpiredError do
4
+ let(:app) { double(:name => 'test') }
5
+ let(:error) { Rapns::Apns::CertificateExpiredError.new(app, Time.now) }
6
+
7
+ it 'returns a message' do
8
+ error.message
9
+ error.to_s
10
+ end
11
+ end
@@ -1,17 +1,17 @@
1
1
  require "unit_spec_helper"
2
2
 
3
3
  describe Rapns::Daemon::Apns::Connection do
4
- let(:ssl_context) { stub(:key= => nil, :cert= => nil) }
5
- let(:rsa_key) { stub }
6
- let(:certificate) { stub }
7
- let(:password) { stub }
8
- let(:x509_certificate) { stub }
4
+ let(:rsa_key) { double }
5
+ let(:certificate) { double }
6
+ let(:password) { double }
7
+ let(:x509_certificate) { OpenSSL::X509::Certificate.new(TEST_CERT) }
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) { stub(:setsockopt => nil, :close => nil) }
12
- let(:ssl_socket) { stub(:sync= => nil, :connect => nil, :close => nil, :write => nil, :flush => nil) }
13
- let(:logger) { stub(:info => nil, :error => nil) }
14
- let(:app) { stub(:name => 'Connection 0', :certificate => certificate, :password => password)}
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) { Rapns::Daemon::Apns::Connection.new(app, host, port) }
16
16
 
17
17
  before do
@@ -21,6 +21,7 @@ describe Rapns::Daemon::Apns::Connection do
21
21
  TCPSocket.stub(:new => tcp_socket)
22
22
  OpenSSL::SSL::SSLSocket.stub(:new => ssl_socket)
23
23
  Rapns.stub(:logger => logger)
24
+ connection.stub(:reflect)
24
25
  end
25
26
 
26
27
  it "reads the number of bytes from the SSL socket" do
@@ -79,6 +80,39 @@ describe Rapns::Daemon::Apns::Connection do
79
80
  tcp_socket.should_receive(:setsockopt).with(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1)
80
81
  connection.connect
81
82
  end
83
+
84
+ describe 'certificate expiry' do
85
+ it 'reflects if the certificate will expire soon' do
86
+ cert = OpenSSL::X509::Certificate.new(app.certificate)
87
+ connection.should_receive(:reflect).with(:apns_certificate_will_expire, app, cert.not_after)
88
+ Timecop.freeze(cert.not_after - 3.days) { connection.connect }
89
+ end
90
+
91
+ it 'logs that the certificate will expire soon' do
92
+ cert = OpenSSL::X509::Certificate.new(app.certificate)
93
+ logger.should_receive(:warn).with("[#{app.name}] Certificate will expire at 2022-09-07 03:18:32 UTC.")
94
+ Timecop.freeze(cert.not_after - 3.days) { connection.connect }
95
+ end
96
+
97
+ it 'does not reflect if the certificate will not expire soon' do
98
+ cert = OpenSSL::X509::Certificate.new(app.certificate)
99
+ connection.should_not_receive(:reflect).with(:apns_certificate_will_expire, app, kind_of(Time))
100
+ Timecop.freeze(cert.not_after - 2.months) { connection.connect }
101
+ end
102
+
103
+ it 'logs that the certificate has expired' do
104
+ cert = OpenSSL::X509::Certificate.new(app.certificate)
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 Rapns::Apns::CertificateExpiredError }
107
+ end
108
+
109
+ it 'raises an error if the certificate has expired' do
110
+ cert = OpenSSL::X509::Certificate.new(app.certificate)
111
+ Timecop.freeze(cert.not_after + 1.day) do
112
+ expect { connection.connect }.to raise_error(Rapns::Apns::CertificateExpiredError)
113
+ end
114
+ end
115
+ end
82
116
  end
83
117
 
84
118
  describe "when shuting down the connection" do
@@ -111,7 +145,7 @@ describe Rapns::Daemon::Apns::Connection do
111
145
  it "ignores IOError when the socket is already closed" do
112
146
  tcp_socket.stub(:close).and_raise(IOError)
113
147
  connection.connect
114
- expect { connection.close }.to_not raise_error(IOError)
148
+ connection.close
115
149
  end
116
150
  end
117
151
 
@@ -194,6 +228,8 @@ describe Rapns::Daemon::Apns::Connection do
194
228
  end
195
229
 
196
230
  describe "when reconnecting" do
231
+ before { connection.connect }
232
+
197
233
  it 'closes the socket' do
198
234
  connection.should_receive(:close)
199
235
  connection.send(:reconnect)
@@ -6,44 +6,50 @@ describe Rapns::Daemon::Apns::DeliveryHandler do
6
6
 
7
7
  let(:host) { 'gateway.push.apple.com' }
8
8
  let(:port) { 2195 }
9
- let(:certificate) { stub }
10
- let(:password) { stub }
11
- let(:app) { stub(:password => password, :certificate => certificate, :name => 'MyApp', :environment => 'production')}
9
+ let(:certificate) { double }
10
+ let(:password) { double }
11
+ let(:app) { double(:password => password, :certificate => certificate, :name => 'MyApp', :environment => 'production')}
12
12
  let(:delivery_handler) { Rapns::Daemon::Apns::DeliveryHandler.new(app) }
13
- let(:connection) { stub('Connection', :select => false, :write => nil, :reconnect => nil, :close => nil, :connect => nil) }
14
- let(:notification) { stub }
15
- let(:http) { stub(:shutdown => nil)}
16
- let(:queue) { Rapns::Daemon::DeliveryQueue.new }
13
+ let(:connection) { double(:connection, :select => false, :write => nil, :reconnect => nil, :close => nil, :connect => nil) }
14
+ let(:notification) { double(:notification) }
15
+ let(:batch) { double(:batch, :notification_processed => nil) }
16
+ let(:http) { double(:http, :shutdown => nil)}
17
+ let(:queue) { Queue.new }
18
+ let(:delivery) { double(:perform => nil) }
17
19
 
18
20
  before do
19
21
  Rapns::Daemon::Apns::Connection.stub(:new => connection)
20
- Rapns::Daemon::Apns::Delivery.stub(:perform)
22
+ Rapns::Daemon::Apns::Delivery.stub(:new => delivery)
21
23
  delivery_handler.queue = queue
22
- queue.push(notification)
24
+ queue.push([notification, batch])
23
25
  end
24
26
 
25
- it "instantiates a new connection" do
26
- Rapns::Daemon::Apns::Connection.should_receive(:new).with(app, host, port)
27
+ def run_delivery_handler
27
28
  delivery_handler.start
28
29
  delivery_handler.stop
30
+ delivery_handler.wakeup
31
+ delivery_handler.wait
32
+ end
33
+
34
+ it "instantiates a new connection" do
35
+ Rapns::Daemon::Apns::Connection.should_receive(:new).with(app, host, port)
36
+ run_delivery_handler
29
37
  end
30
38
 
31
39
  it "connects the socket" do
32
40
  connection.should_receive(:connect)
33
- delivery_handler.start
34
- delivery_handler.stop
41
+ run_delivery_handler
35
42
  end
36
43
 
37
44
  it 'performs delivery of an notification' do
38
- Rapns::Daemon::Apns::Delivery.should_receive(:perform).with(app, connection, notification)
39
- delivery_handler.start
40
- delivery_handler.stop
45
+ Rapns::Daemon::Apns::Delivery.should_receive(:new).with(app, connection, notification, batch).and_return(delivery)
46
+ delivery.should_receive(:perform)
47
+ run_delivery_handler
41
48
  end
42
49
 
43
50
  it 'closes the connection stopped' do
44
51
  connection.should_receive(:close)
45
- delivery_handler.start
46
- delivery_handler.stop
52
+ run_delivery_handler
47
53
  end
48
54
 
49
55
  it 'does not attempt to close the connection if the connection was not established' do
@@ -1,13 +1,13 @@
1
1
  require 'unit_spec_helper'
2
2
 
3
3
  describe Rapns::Daemon::Apns::Delivery do
4
- let(:app) { stub(:name => 'MyApp') }
5
- let(:notification) { stub.as_null_object }
6
- let(:logger) { stub(:error => nil, :info => nil) }
7
- let(:config) { stub(:check_for_errors => true) }
8
- let(:connection) { stub(:select => false, :write => nil, :reconnect => nil, :close => nil, :connect => nil) }
9
- let(:delivery) { Rapns::Daemon::Apns::Delivery.new(app, connection, notification) }
10
- let(:store) { stub(:mark_failed => nil, :mark_delivered => nil) }
4
+ let(:app) { double(:name => 'MyApp') }
5
+ let(:notification) { double.as_null_object }
6
+ let(:batch) { double(:mark_failed => nil, :mark_delivered => nil) }
7
+ let(:logger) { double(:error => nil, :info => nil) }
8
+ let(:config) { double(:check_for_errors => true) }
9
+ let(:connection) { double(:select => false, :write => nil, :reconnect => nil, :close => nil, :connect => nil) }
10
+ let(:delivery) { Rapns::Daemon::Apns::Delivery.new(app, connection, notification, batch) }
11
11
 
12
12
  def perform
13
13
  begin
@@ -17,7 +17,6 @@ describe Rapns::Daemon::Apns::Delivery do
17
17
  end
18
18
 
19
19
  before do
20
- Rapns::Daemon.stub(:store => store)
21
20
  Rapns.stub(:config => config, :logger => logger)
22
21
  end
23
22
 
@@ -34,7 +33,7 @@ describe Rapns::Daemon::Apns::Delivery do
34
33
  end
35
34
 
36
35
  it "marks the notification as delivered" do
37
- store.should_receive(:mark_delivered).with(notification)
36
+ batch.should_receive(:mark_delivered).with(notification)
38
37
  perform
39
38
  end
40
39
 
@@ -53,7 +52,7 @@ describe Rapns::Daemon::Apns::Delivery do
53
52
  before { connection.stub(:select => true, :read => [8, 4, 69].pack("ccN")) }
54
53
 
55
54
  it "marks the notification as failed" do
56
- store.should_receive(:mark_failed).with(notification, 4, "Missing payload")
55
+ batch.should_receive(:mark_failed).with(notification, 4, "Missing payload")
57
56
  perform
58
57
  end
59
58
 
@@ -63,7 +62,7 @@ describe Rapns::Daemon::Apns::Delivery do
63
62
  end
64
63
 
65
64
  it "logs the delivery error" do
66
- # checking for the stubbed error doesn't work in jruby, but checking
65
+ # checking for the doublebed error doesn't work in jruby, but checking
67
66
  # for the exception by class does.
68
67
 
69
68
  #error = Rapns::DeliveryError.new(4, 12, "Missing payload")
@@ -104,7 +103,7 @@ describe Rapns::Daemon::Apns::Delivery do
104
103
  end
105
104
 
106
105
  it 'marks the notification as failed' do
107
- store.should_receive(:mark_failed).with(notification, nil, "APNs disconnected without returning an error.")
106
+ batch.should_receive(:mark_failed).with(notification, nil, "APNs disconnected without returning an error.")
108
107
  perform
109
108
  end
110
109
  end
@@ -4,23 +4,23 @@ describe Rapns::Daemon::Apns::FeedbackReceiver, 'check_for_feedback' do
4
4
  let(:host) { 'feedback.push.apple.com' }
5
5
  let(:port) { 2196 }
6
6
  let(:poll) { 60 }
7
- let(:certificate) { stub }
8
- let(:password) { stub }
9
- let(:app) { stub(:name => 'my_app', :password => password, :certificate => certificate, :environment => 'production') }
10
- let(:connection) { stub(:connect => nil, :read => nil, :close => nil) }
11
- let(:logger) { stub(:error => nil, :info => nil) }
7
+ let(:certificate) { double }
8
+ let(:password) { double }
9
+ let(:app) { double(:name => 'my_app', :password => password, :certificate => certificate, :environment => 'production') }
10
+ let(:connection) { double(:connect => nil, :read => nil, :close => nil) }
11
+ let(:logger) { double(:error => nil, :info => nil) }
12
12
  let(:receiver) { Rapns::Daemon::Apns::FeedbackReceiver.new(app, poll) }
13
- let(:feedback) { stub }
13
+ let(:feedback) { double }
14
14
 
15
15
  before do
16
16
  receiver.stub(:interruptible_sleep)
17
17
  Rapns.stub(:logger => logger)
18
18
  Rapns::Daemon::Apns::Connection.stub(:new => connection)
19
19
  receiver.instance_variable_set("@stop", false)
20
- Rapns::Daemon.stub(:store => stub(:create_apns_feedback => feedback))
20
+ Rapns::Daemon.stub(:store => double(:create_apns_feedback => feedback))
21
21
  end
22
22
 
23
- def stub_connection_read_with_tuple
23
+ def double_connection_read_with_tuple
24
24
  connection.unstub(:read)
25
25
 
26
26
  def connection.read(bytes)
@@ -52,14 +52,14 @@ describe Rapns::Daemon::Apns::FeedbackReceiver, 'check_for_feedback' do
52
52
  end
53
53
 
54
54
  it 'logs the feedback' do
55
- stub_connection_read_with_tuple
55
+ double_connection_read_with_tuple
56
56
  Rapns.logger.should_receive(:info).with("[my_app] [FeedbackReceiver] Delivery failed at 2011-12-10 16:08:45 UTC for 834f786655eb9f84614a05ad7d00af31e5cfe93ac3ea078f1da44d2a4eb0ce17.")
57
57
  receiver.check_for_feedback
58
58
  end
59
59
 
60
60
  it 'creates the feedback' do
61
61
  Rapns::Daemon.store.should_receive(:create_apns_feedback).with(Time.at(1323533325), '834f786655eb9f84614a05ad7d00af31e5cfe93ac3ea078f1da44d2a4eb0ce17', app)
62
- stub_connection_read_with_tuple
62
+ double_connection_read_with_tuple
63
63
  receiver.check_for_feedback
64
64
  end
65
65
 
@@ -92,13 +92,13 @@ describe Rapns::Daemon::Apns::FeedbackReceiver, 'check_for_feedback' do
92
92
  end
93
93
 
94
94
  it 'reflects feedback was received' do
95
- stub_connection_read_with_tuple
95
+ double_connection_read_with_tuple
96
96
  receiver.should_receive(:reflect).with(:apns_feedback, feedback)
97
97
  receiver.check_for_feedback
98
98
  end
99
99
 
100
100
  it 'calls the apns_feedback_callback when feedback is received and the callback is set' do
101
- stub_connection_read_with_tuple
101
+ double_connection_read_with_tuple
102
102
  Rapns.config.apns_feedback_callback = Proc.new {}
103
103
  Rapns.config.apns_feedback_callback.should_receive(:call).with(feedback)
104
104
  receiver.check_for_feedback
@@ -106,9 +106,9 @@ describe Rapns::Daemon::Apns::FeedbackReceiver, 'check_for_feedback' do
106
106
 
107
107
  it 'catches exceptions in the apns_feedback_callback' do
108
108
  error = StandardError.new('bork!')
109
- stub_connection_read_with_tuple
109
+ double_connection_read_with_tuple
110
110
  callback = Proc.new { raise error }
111
- Rapns::Deprecation.silenced do
111
+ Rapns::Deprecation.muted do
112
112
  Rapns.config.on_apns_feedback &callback
113
113
  end
114
114
  expect { receiver.check_for_feedback }.not_to raise_error
@@ -116,10 +116,10 @@ describe Rapns::Daemon::Apns::FeedbackReceiver, 'check_for_feedback' do
116
116
 
117
117
  it 'logs an exception from the apns_feedback_callback' do
118
118
  error = StandardError.new('bork!')
119
- stub_connection_read_with_tuple
119
+ double_connection_read_with_tuple
120
120
  callback = Proc.new { raise error }
121
121
  Rapns.logger.should_receive(:error).with(error)
122
- Rapns::Deprecation.silenced do
122
+ Rapns::Deprecation.muted do
123
123
  Rapns.config.on_apns_feedback &callback
124
124
  end
125
125
  receiver.check_for_feedback
@@ -1,7 +1,7 @@
1
1
  shared_examples_for "an AppRunner subclass" do
2
- let(:queue) { stub(:notifications_processed? => true, :push => nil) }
2
+ let(:queue) { double(:push => nil) }
3
3
 
4
- before { Rapns::Daemon::DeliveryQueue.stub(:new => queue) }
4
+ before { Queue.stub(:new => queue) }
5
5
  after { Rapns::Daemon::AppRunner.runners.clear }
6
6
 
7
7
  describe 'start' do
@@ -10,6 +10,11 @@ shared_examples_for "an AppRunner subclass" do
10
10
  runner.start
11
11
  end
12
12
 
13
+ it 'adds the delivery handler to the collection' do
14
+ handler_collection.should_receive(:push).with(handler)
15
+ runner.start
16
+ end
17
+
13
18
  it 'assigns the queue to the handler' do
14
19
  handler.should_receive(:queue=).with(queue)
15
20
  runner.start
@@ -17,11 +22,17 @@ shared_examples_for "an AppRunner subclass" do
17
22
  end
18
23
 
19
24
  describe 'enqueue' do
20
- let(:notification) { stub }
25
+ let(:notification) { double }
26
+ let(:batch) { double(:notifications => [notification]) }
27
+
28
+ it 'enqueues the batch' do
29
+ queue.should_receive(:push).with([notification, batch])
30
+ runner.enqueue(batch)
31
+ end
21
32
 
22
- it 'enqueues the notification' do
23
- queue.should_receive(:push).with(notification)
24
- runner.enqueue(notification)
33
+ it 'reflects the notification has been enqueued' do
34
+ runner.should_receive(:reflect).with(:notification_enqueued, notification)
35
+ runner.enqueue(batch)
25
36
  end
26
37
  end
27
38
 
@@ -29,19 +40,24 @@ shared_examples_for "an AppRunner subclass" do
29
40
  before { runner.start }
30
41
 
31
42
  it 'stops the delivery handlers' do
32
- handler.should_receive(:stop)
43
+ handler_collection.should_receive(:stop)
33
44
  runner.stop
34
45
  end
35
46
  end
36
47
 
37
48
  describe 'idle?' do
38
49
  it 'is idle if all notifications have been processed' do
39
- queue.stub(:notifications_processed? => true)
50
+ runner.batch = double(:complete? => true)
51
+ runner.idle?.should be_true
52
+ end
53
+
54
+ it 'is idle if the runner has no associated batch' do
55
+ runner.batch = nil
40
56
  runner.idle?.should be_true
41
57
  end
42
58
 
43
59
  it 'is not idle if not all notifications have been processed' do
44
- queue.stub(:notifications_processed? => false)
60
+ runner.batch = double(:complete? => false)
45
61
  runner.idle?.should be_false
46
62
  end
47
63
  end
@@ -50,7 +66,7 @@ shared_examples_for "an AppRunner subclass" do
50
66
  before { runner.start }
51
67
 
52
68
  it 'reduces the number of handlers if needed' do
53
- handler.should_receive(:stop)
69
+ handler_collection.should_receive(:pop)
54
70
  new_app = app_class.new
55
71
  new_app.stub(:connections => app.connections - 1)
56
72
  runner.sync(new_app)
@@ -58,6 +74,7 @@ shared_examples_for "an AppRunner subclass" do
58
74
 
59
75
  it 'increases the number of handlers if needed' do
60
76
  runner.should_receive(:start_handler).and_return(handler)
77
+ handler_collection.should_receive(:push).with(handler)
61
78
  new_app = app_class.new
62
79
  new_app.stub(:connections => app.connections + 1)
63
80
  runner.sync(new_app)