rpush 1.0.0 → 2.0.0.beta1

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.
Files changed (193) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -0
  3. data/README.md +12 -14
  4. data/bin/rpush +11 -2
  5. data/lib/generators/rpush_generator.rb +2 -0
  6. data/lib/generators/templates/add_adm.rb +5 -5
  7. data/lib/generators/templates/add_alert_is_json_to_rapns_notifications.rb +1 -1
  8. data/lib/generators/templates/add_app_to_rapns.rb +2 -2
  9. data/lib/generators/templates/add_fail_after_to_rpush_notifications.rb +1 -1
  10. data/lib/generators/templates/add_gcm.rb +32 -32
  11. data/lib/generators/templates/add_rpush.rb +67 -67
  12. data/lib/generators/templates/add_wpns.rb +2 -2
  13. data/lib/generators/templates/create_rapns_apps.rb +5 -5
  14. data/lib/generators/templates/create_rapns_feedback.rb +2 -2
  15. data/lib/generators/templates/create_rapns_notifications.rb +15 -15
  16. data/lib/generators/templates/rpush.rb +10 -7
  17. data/lib/generators/templates/rpush_2_0_0_updates.rb +23 -0
  18. data/lib/rpush.rb +4 -28
  19. data/lib/rpush/client/active_model.rb +21 -0
  20. data/lib/rpush/client/active_model/adm/app.rb +23 -0
  21. data/lib/rpush/client/active_model/adm/data_validator.rb +14 -0
  22. data/lib/rpush/client/active_model/adm/notification.rb +28 -0
  23. data/lib/rpush/client/active_model/apns/app.rb +37 -0
  24. data/lib/rpush/client/active_model/apns/binary_notification_validator.rb +16 -0
  25. data/lib/rpush/client/active_model/apns/device_token_format_validator.rb +14 -0
  26. data/lib/rpush/client/active_model/apns/notification.rb +90 -0
  27. data/lib/rpush/client/active_model/gcm/app.rb +19 -0
  28. data/lib/rpush/client/active_model/gcm/expiry_collapse_key_mutual_inclusion_validator.rb +14 -0
  29. data/lib/rpush/client/active_model/gcm/notification.rb +31 -0
  30. data/lib/rpush/client/active_model/notification.rb +26 -0
  31. data/lib/rpush/client/active_model/payload_data_size_validator.rb +13 -0
  32. data/lib/rpush/client/active_model/registration_ids_count_validator.rb +13 -0
  33. data/lib/rpush/client/active_model/wpns/app.rb +13 -0
  34. data/lib/rpush/client/active_model/wpns/notification.rb +17 -0
  35. data/lib/rpush/client/active_record.rb +19 -0
  36. data/lib/rpush/client/active_record/adm/app.rb +11 -0
  37. data/lib/rpush/client/active_record/adm/notification.rb +11 -0
  38. data/lib/rpush/client/active_record/apns/app.rb +11 -0
  39. data/lib/rpush/client/active_record/apns/feedback.rb +20 -0
  40. data/lib/rpush/client/active_record/apns/notification.rb +46 -0
  41. data/lib/rpush/client/active_record/app.rb +17 -0
  42. data/lib/rpush/client/active_record/gcm/app.rb +11 -0
  43. data/lib/rpush/client/active_record/gcm/notification.rb +11 -0
  44. data/lib/rpush/client/active_record/notification.rb +38 -0
  45. data/lib/rpush/client/active_record/wpns/app.rb +11 -0
  46. data/lib/rpush/client/active_record/wpns/notification.rb +11 -0
  47. data/lib/rpush/client/redis.rb +35 -0
  48. data/lib/rpush/client/redis/adm/app.rb +14 -0
  49. data/lib/rpush/client/redis/adm/notification.rb +11 -0
  50. data/lib/rpush/client/redis/apns/app.rb +11 -0
  51. data/lib/rpush/client/redis/apns/feedback.rb +20 -0
  52. data/lib/rpush/client/redis/apns/notification.rb +11 -0
  53. data/lib/rpush/client/redis/app.rb +22 -0
  54. data/lib/rpush/client/redis/gcm/app.rb +11 -0
  55. data/lib/rpush/client/redis/gcm/notification.rb +11 -0
  56. data/lib/rpush/client/redis/notification.rb +68 -0
  57. data/lib/rpush/client/redis/wpns/app.rb +11 -0
  58. data/lib/rpush/client/redis/wpns/notification.rb +11 -0
  59. data/lib/rpush/configuration.rb +27 -6
  60. data/lib/rpush/daemon.rb +36 -56
  61. data/lib/rpush/daemon/adm/delivery.rb +50 -52
  62. data/lib/rpush/daemon/apns.rb +6 -5
  63. data/lib/rpush/daemon/apns/delivery.rb +20 -44
  64. data/lib/rpush/daemon/apns/feedback_receiver.rb +11 -8
  65. data/lib/rpush/daemon/app_runner.rb +67 -60
  66. data/lib/rpush/daemon/batch.rb +54 -40
  67. data/lib/rpush/daemon/delivery.rb +13 -3
  68. data/lib/rpush/daemon/delivery_error.rb +10 -2
  69. data/lib/rpush/daemon/dispatcher/apns_tcp.rb +106 -0
  70. data/lib/rpush/daemon/dispatcher/http.rb +3 -3
  71. data/lib/rpush/daemon/dispatcher/tcp.rb +3 -3
  72. data/lib/rpush/daemon/dispatcher_loop.rb +15 -6
  73. data/lib/rpush/daemon/errors.rb +18 -0
  74. data/lib/rpush/daemon/feeder.rb +28 -39
  75. data/lib/rpush/daemon/gcm/delivery.rb +19 -20
  76. data/lib/rpush/daemon/interruptible_sleep.rb +26 -45
  77. data/lib/rpush/daemon/loggable.rb +2 -4
  78. data/lib/rpush/daemon/proc_title.rb +16 -0
  79. data/lib/rpush/daemon/queue_payload.rb +12 -0
  80. data/lib/rpush/daemon/reflectable.rb +3 -5
  81. data/lib/rpush/daemon/retry_header_parser.rb +6 -6
  82. data/lib/rpush/daemon/ring_buffer.rb +16 -0
  83. data/lib/rpush/daemon/service_config_methods.rb +23 -7
  84. data/lib/rpush/daemon/signal_handler.rb +51 -0
  85. data/lib/rpush/daemon/store/active_record.rb +71 -38
  86. data/lib/rpush/daemon/store/active_record/reconnectable.rb +15 -15
  87. data/lib/rpush/daemon/store/interface.rb +19 -0
  88. data/lib/rpush/daemon/store/redis.rb +149 -0
  89. data/lib/rpush/daemon/tcp_connection.rb +6 -11
  90. data/lib/rpush/daemon/wpns/delivery.rb +21 -30
  91. data/lib/rpush/deprecatable.rb +4 -3
  92. data/lib/rpush/deprecation.rb +7 -10
  93. data/lib/rpush/embed.rb +7 -2
  94. data/lib/rpush/logger.rb +11 -15
  95. data/lib/rpush/push.rb +0 -1
  96. data/lib/rpush/reflection.rb +6 -12
  97. data/lib/rpush/version.rb +1 -1
  98. data/lib/tasks/quality.rake +34 -0
  99. data/spec/.rubocop.yml +4 -0
  100. data/spec/functional/adm_spec.rb +3 -6
  101. data/spec/functional/apns_spec.rb +118 -24
  102. data/spec/functional/embed_spec.rb +22 -20
  103. data/spec/functional/gcm_spec.rb +4 -7
  104. data/spec/functional/new_app_spec.rb +61 -0
  105. data/spec/functional/retry_spec.rb +46 -0
  106. data/spec/functional/wpns_spec.rb +3 -6
  107. data/spec/functional_spec_helper.rb +26 -0
  108. data/spec/integration/rpush_spec.rb +13 -0
  109. data/spec/integration/support/gcm_success_response.json +1 -0
  110. data/spec/spec_helper.rb +60 -0
  111. data/spec/support/active_record_setup.rb +48 -0
  112. data/{config → spec/support/config}/database.yml +0 -0
  113. data/spec/support/install.sh +43 -7
  114. data/spec/support/simplecov_helper.rb +9 -5
  115. data/spec/support/simplecov_quality_formatter.rb +10 -6
  116. data/spec/unit/apns_feedback_spec.rb +3 -3
  117. data/spec/unit/{adm → client/active_record/adm}/app_spec.rb +3 -3
  118. data/spec/unit/{adm → client/active_record/adm}/notification_spec.rb +5 -7
  119. data/spec/unit/client/active_record/apns/app_spec.rb +29 -0
  120. data/spec/unit/client/active_record/apns/feedback_spec.rb +9 -0
  121. data/spec/unit/client/active_record/apns/notification_spec.rb +231 -0
  122. data/spec/unit/client/active_record/app_spec.rb +30 -0
  123. data/spec/unit/client/active_record/gcm/app_spec.rb +4 -0
  124. data/spec/unit/{gcm → client/active_record/gcm}/notification_spec.rb +5 -7
  125. data/spec/unit/client/active_record/notification_spec.rb +15 -0
  126. data/spec/unit/client/active_record/wpns/app_spec.rb +4 -0
  127. data/spec/unit/client/active_record/wpns/notification_spec.rb +21 -0
  128. data/spec/unit/configuration_spec.rb +12 -5
  129. data/spec/unit/daemon/adm/delivery_spec.rb +57 -54
  130. data/spec/unit/daemon/apns/certificate_expired_error_spec.rb +3 -3
  131. data/spec/unit/daemon/apns/delivery_spec.rb +90 -83
  132. data/spec/unit/daemon/apns/feedback_receiver_spec.rb +24 -17
  133. data/spec/unit/daemon/app_runner_spec.rb +66 -123
  134. data/spec/unit/daemon/batch_spec.rb +52 -115
  135. data/spec/unit/daemon/delivery_spec.rb +15 -1
  136. data/spec/unit/daemon/dispatcher/http_spec.rb +3 -2
  137. data/spec/unit/daemon/dispatcher/tcp_spec.rb +10 -9
  138. data/spec/unit/daemon/dispatcher_loop_spec.rb +7 -12
  139. data/spec/unit/daemon/feeder_spec.rb +40 -39
  140. data/spec/unit/daemon/gcm/delivery_spec.rb +108 -89
  141. data/spec/unit/daemon/reflectable_spec.rb +2 -2
  142. data/spec/unit/daemon/retryable_error_spec.rb +1 -1
  143. data/spec/unit/daemon/service_config_methods_spec.rb +6 -3
  144. data/spec/unit/daemon/signal_handler_spec.rb +72 -0
  145. data/spec/unit/daemon/store/active_record/reconnectable_spec.rb +9 -9
  146. data/spec/unit/daemon/store/active_record_spec.rb +38 -47
  147. data/spec/unit/daemon/tcp_connection_spec.rb +22 -34
  148. data/spec/unit/daemon/too_many_requests_error_spec.rb +1 -1
  149. data/spec/unit/daemon/wpns/delivery_spec.rb +61 -50
  150. data/spec/unit/daemon_spec.rb +46 -81
  151. data/spec/unit/embed_spec.rb +4 -2
  152. data/spec/unit/logger_spec.rb +30 -40
  153. data/spec/unit/notification_shared.rb +9 -79
  154. data/spec/unit/push_spec.rb +3 -8
  155. data/spec/unit/reflection_spec.rb +25 -25
  156. data/spec/unit/rpush_spec.rb +1 -2
  157. data/spec/unit_spec_helper.rb +33 -88
  158. metadata +119 -67
  159. data/lib/rpush/TODO +0 -3
  160. data/lib/rpush/adm/app.rb +0 -15
  161. data/lib/rpush/adm/data_validator.rb +0 -11
  162. data/lib/rpush/adm/notification.rb +0 -29
  163. data/lib/rpush/apns/app.rb +0 -29
  164. data/lib/rpush/apns/binary_notification_validator.rb +0 -12
  165. data/lib/rpush/apns/device_token_format_validator.rb +0 -12
  166. data/lib/rpush/apns/feedback.rb +0 -16
  167. data/lib/rpush/apns/notification.rb +0 -84
  168. data/lib/rpush/app.rb +0 -18
  169. data/lib/rpush/daemon/apns/certificate_expired_error.rb +0 -20
  170. data/lib/rpush/daemon/apns/disconnection_error.rb +0 -20
  171. data/lib/rpush/gcm/app.rb +0 -11
  172. data/lib/rpush/gcm/expiry_collapse_key_mutual_inclusion_validator.rb +0 -11
  173. data/lib/rpush/gcm/notification.rb +0 -30
  174. data/lib/rpush/notification.rb +0 -69
  175. data/lib/rpush/notifier.rb +0 -52
  176. data/lib/rpush/payload_data_size_validator.rb +0 -10
  177. data/lib/rpush/railtie.rb +0 -11
  178. data/lib/rpush/registration_ids_count_validator.rb +0 -10
  179. data/lib/rpush/wpns/app.rb +0 -9
  180. data/lib/rpush/wpns/notification.rb +0 -26
  181. data/lib/tasks/cane.rake +0 -18
  182. data/lib/tasks/rpush.rake +0 -16
  183. data/spec/unit/apns/app_spec.rb +0 -29
  184. data/spec/unit/apns/feedback_spec.rb +0 -9
  185. data/spec/unit/apns/notification_spec.rb +0 -208
  186. data/spec/unit/app_spec.rb +0 -30
  187. data/spec/unit/daemon/apns/disconnection_error_spec.rb +0 -18
  188. data/spec/unit/daemon/interruptible_sleep_spec.rb +0 -68
  189. data/spec/unit/gcm/app_spec.rb +0 -4
  190. data/spec/unit/notification_spec.rb +0 -15
  191. data/spec/unit/notifier_spec.rb +0 -49
  192. data/spec/unit/wpns/app_spec.rb +0 -4
  193. data/spec/unit/wpns/notification_spec.rb +0 -30
@@ -1,4 +1,5 @@
1
- require "unit_spec_helper"
1
+ require 'unit_spec_helper'
2
+ require 'rpush/daemon/store/active_record'
2
3
 
3
4
  describe Rpush::Daemon::Apns::FeedbackReceiver, 'check_for_feedback' do
4
5
 
@@ -7,35 +8,41 @@ describe Rpush::Daemon::Apns::FeedbackReceiver, 'check_for_feedback' do
7
8
  let(:poll) { 60 }
8
9
  let(:certificate) { double }
9
10
  let(:password) { double }
10
- let(:app) { double(:name => 'my_app', :password => password, :certificate => certificate, :environment => 'production') }
11
- let(:connection) { double(:connect => nil, :read => nil, :close => nil) }
12
- let(:logger) { double(:error => nil, :info => nil) }
11
+ let(:app) { double(name: 'my_app', password: password, certificate: certificate, environment: 'production') }
12
+ let(:connection) { double(connect: nil, read: nil, close: nil) }
13
+ let(:logger) { double(error: nil, info: nil) }
13
14
  let(:receiver) { Rpush::Daemon::Apns::FeedbackReceiver.new(app) }
14
15
  let(:feedback) { double }
15
- let(:sleeper) { double(Rpush::Daemon::InterruptibleSleep, :sleep => nil, :interrupt_sleep => nil) }
16
- let(:store) { double(Rpush::Daemon::Store::ActiveRecord,
17
- create_apns_feedback: feedback, release_connection: nil) }
16
+ let(:sleeper) { double(Rpush::Daemon::InterruptibleSleep, sleep: nil, start: nil, stop: nil) }
17
+ let(:store) do double(Rpush::Daemon::Store::ActiveRecord,
18
+ create_apns_feedback: feedback, release_connection: nil)
19
+ end
18
20
 
19
21
  before do
20
22
  Rpush.config.feedback_poll = poll
21
- Rpush::Daemon::InterruptibleSleep.stub(:new => sleeper)
22
- Rpush.stub(:logger => logger)
23
- Rpush::Daemon::TcpConnection.stub(:new => connection)
23
+ Rpush::Daemon::InterruptibleSleep.stub(new: sleeper)
24
+ Rpush.stub(logger: logger)
25
+ Rpush::Daemon::TcpConnection.stub(new: connection)
24
26
  receiver.instance_variable_set("@stop", false)
25
- Rpush::Daemon.stub(:store => store)
27
+ Rpush::Daemon.stub(store: store)
26
28
  end
27
29
 
28
30
  def double_connection_read_with_tuple
29
31
  connection.unstub(:read)
30
32
 
31
- def connection.read(bytes)
32
- if !@called
33
+ def connection.read(*)
34
+ unless @called
33
35
  @called = true
34
36
  "N\xE3\x84\r\x00 \x83OxfU\xEB\x9F\x84aJ\x05\xAD}\x00\xAF1\xE5\xCF\xE9:\xC3\xEA\a\x8F\x1D\xA4M*N\xB0\xCE\x17"
35
37
  end
36
38
  end
37
39
  end
38
40
 
41
+ it 'initializes the sleeper with the feedback polling duration' do
42
+ Rpush::Daemon::InterruptibleSleep.should_receive(:new).with(poll).and_return(sleeper)
43
+ Rpush::Daemon::Apns::FeedbackReceiver.new(app)
44
+ end
45
+
39
46
  it 'instantiates a new connection' do
40
47
  Rpush::Daemon::TcpConnection.should_receive(:new).with(app, host, port)
41
48
  receiver.check_for_feedback
@@ -63,7 +70,7 @@ describe Rpush::Daemon::Apns::FeedbackReceiver, 'check_for_feedback' do
63
70
  end
64
71
 
65
72
  it 'creates the feedback' do
66
- Rpush::Daemon.store.should_receive(:create_apns_feedback).with(Time.at(1323533325), '834f786655eb9f84614a05ad7d00af31e5cfe93ac3ea078f1da44d2a4eb0ce17', app)
73
+ Rpush::Daemon.store.should_receive(:create_apns_feedback).with(Time.at(1_323_533_325), '834f786655eb9f84614a05ad7d00af31e5cfe93ac3ea078f1da44d2a4eb0ce17', app)
67
74
  double_connection_read_with_tuple
68
75
  receiver.check_for_feedback
69
76
  end
@@ -81,9 +88,9 @@ describe Rpush::Daemon::Apns::FeedbackReceiver, 'check_for_feedback' do
81
88
  receiver.stub(:loop).and_yield
82
89
  end
83
90
 
84
- it 'sleeps for the feedback poll period' do
91
+ it 'sleeps' do
85
92
  receiver.stub(:check_for_feedback)
86
- sleeper.should_receive(:sleep).with(60).at_least(:once)
93
+ sleeper.should_receive(:sleep).at_least(:once)
87
94
  receiver.start
88
95
  end
89
96
 
@@ -96,7 +103,7 @@ describe Rpush::Daemon::Apns::FeedbackReceiver, 'check_for_feedback' do
96
103
  describe 'stop' do
97
104
  it 'interrupts sleep when stopped' do
98
105
  receiver.stub(:check_for_feedback)
99
- sleeper.should_receive(:interrupt_sleep)
106
+ sleeper.should_receive(:stop)
100
107
  receiver.stop
101
108
  end
102
109
 
@@ -1,4 +1,5 @@
1
1
  require 'unit_spec_helper'
2
+ require 'rpush/daemon/store/active_record'
2
3
 
3
4
  module Rpush
4
5
  module AppRunnerSpecService
@@ -11,7 +12,7 @@ module Rpush
11
12
  extend ServiceConfigMethods
12
13
 
13
14
  class ServiceLoop
14
- def initialize(app)
15
+ def initialize(*)
15
16
  end
16
17
 
17
18
  def start
@@ -42,69 +43,63 @@ describe Rpush::Daemon::AppRunner, 'stop' do
42
43
  end
43
44
 
44
45
  describe Rpush::Daemon::AppRunner, 'enqueue' do
45
- let(:runner) { double(:enqueue => nil) }
46
- let(:notification1) { double(:app_id => 1) }
47
- let(:notification2) { double(:app_id => 2) }
48
- let(:logger) { double(Rpush::Logger, :error => nil) }
46
+ let(:runner) { double(enqueue: nil) }
47
+ let(:notification1) { double(app_id: 1) }
48
+ let(:notification2) { double(app_id: 2) }
49
+ let(:logger) { double(Rpush::Logger, error: nil, info: nil) }
49
50
 
50
51
  before do
51
- Rpush.stub(:logger => logger)
52
+ Rpush.stub(logger: logger)
53
+ Rpush::Daemon::ProcTitle.stub(:update)
52
54
  Rpush::Daemon::AppRunner.runners[1] = runner
55
+ Rpush::Daemon::AppRunner.runners[2] = runner
53
56
  end
54
57
 
55
58
  after { Rpush::Daemon::AppRunner.runners.clear }
56
59
 
57
- it 'batches notifications by app' do
58
- batch = double.as_null_object
59
- Rpush::Daemon::Batch.stub(:new => batch)
60
- Rpush::Daemon::Batch.should_receive(:new).with([notification1])
61
- Rpush::Daemon::Batch.should_receive(:new).with([notification2])
60
+ it 'enqueues notifications on each runner' do
61
+ runner.should_receive(:enqueue).with([notification1])
62
+ runner.should_receive(:enqueue).with([notification2])
62
63
  Rpush::Daemon::AppRunner.enqueue([notification1, notification2])
63
64
  end
64
65
 
65
- it 'enqueues each batch' do
66
- runner.should_receive(:enqueue).with(kind_of(Rpush::Daemon::Batch))
67
- Rpush::Daemon::AppRunner.enqueue([notification1])
68
- end
69
-
70
- it 'logs an error if there is no runner to deliver the notification' do
71
- notification1.stub(:app_id => 2, :id => 123)
72
- notification2.stub(:app_id => 2, :id => 456)
73
- logger.should_receive(:error).with("No such app '#{notification1.app_id}' for notifications 123, 456.")
74
- Rpush::Daemon::AppRunner.enqueue([notification1, notification2])
66
+ it 'syncs the app if a runner does not exist' do
67
+ Rpush::Daemon::AppRunner.runners[3].should be_nil
68
+ notification = double(app_id: 3)
69
+ app = double(Rpush::App, id: 3, connections: 1, service_name: 'app_runner_spec_service', environment: 'sandbox', certificate: TEST_CERT, password: nil, name: 'test')
70
+ Rpush::Daemon.store = double(app: app)
71
+ Rpush::Daemon::AppRunner.enqueue([notification])
72
+ Rpush::Daemon::AppRunner.runners[3].should_not be_nil
75
73
  end
76
74
  end
77
75
 
78
76
  describe Rpush::Daemon::AppRunner, 'sync' do
79
- let(:app) { double(Rpush::AppRunnerSpecService::App, :name => 'test') }
80
- let(:new_app) { double(Rpush::AppRunnerSpecService::App, :name => 'new_test') }
81
- let(:runner) { double(:sync => nil, :stop => nil, :start => nil) }
82
- let(:logger) { double(Rpush::Logger, :error => nil, :warn => nil) }
77
+ let(:app) { double(Rpush::AppRunnerSpecService::App, name: 'test') }
78
+ let(:new_app) { double(Rpush::AppRunnerSpecService::App, name: 'new_test') }
79
+ let(:runner) { double(sync: nil, stop: nil, start: nil) }
80
+ let(:logger) { double(Rpush::Logger, error: nil, warn: nil) }
83
81
  let(:queue) { Queue.new }
82
+ let(:store) { double(all_apps: [app]) }
84
83
 
85
84
  before do
86
- app.stub(:id => 1)
87
- new_app.stub(:id => 2)
88
- Queue.stub(:new => queue)
85
+ app.stub(id: 1)
86
+ new_app.stub(id: 2)
87
+ Queue.stub(new: queue)
89
88
  Rpush::Daemon::AppRunner.runners[app.id] = runner
90
- Rpush::App.stub(:all => [app])
91
- Rpush.stub(:logger => logger)
89
+ Rpush.stub(logger: logger)
90
+ Rpush::Daemon.stub(store: store)
91
+ Rpush::Daemon::ProcTitle.stub(:update)
92
92
  end
93
93
 
94
94
  after { Rpush::Daemon::AppRunner.runners.clear }
95
95
 
96
- it 'loads all apps' do
97
- Rpush::App.should_receive(:all)
98
- Rpush::Daemon::AppRunner.sync
99
- end
100
-
101
96
  it 'instructs existing runners to sync' do
102
97
  runner.should_receive(:sync).with(app)
103
98
  Rpush::Daemon::AppRunner.sync
104
99
  end
105
100
 
106
101
  it 'starts a runner for a new app' do
107
- Rpush::App.stub(:all => [app, new_app])
102
+ store.stub(all_apps: [app, new_app])
108
103
  new_runner = double
109
104
  Rpush::Daemon::AppRunner.should_receive(:new).with(new_app).and_return(new_runner)
110
105
  new_runner.should_receive(:start)
@@ -112,13 +107,13 @@ describe Rpush::Daemon::AppRunner, 'sync' do
112
107
  end
113
108
 
114
109
  it 'deletes old runners' do
115
- Rpush::App.stub(:all => [])
110
+ store.stub(all_apps: [])
116
111
  runner.should_receive(:stop)
117
112
  Rpush::Daemon::AppRunner.sync
118
113
  end
119
114
 
120
115
  it 'logs an error if the runner could not be started' do
121
- Rpush::App.stub(:all => [app, new_app])
116
+ store.stub(all_apps: [app, new_app])
122
117
  new_runner = double
123
118
  Rpush::Daemon::AppRunner.should_receive(:new).with(new_app).and_return(new_runner)
124
119
  new_runner.stub(:start).and_raise(StandardError)
@@ -127,7 +122,7 @@ describe Rpush::Daemon::AppRunner, 'sync' do
127
122
  end
128
123
 
129
124
  it 'reflects errors if the runner could not be started' do
130
- Rpush::App.stub(:all => [app, new_app])
125
+ store.stub(all_apps: [app, new_app])
131
126
  new_runner = double
132
127
  Rpush::Daemon::AppRunner.should_receive(:new).with(new_app).and_return(new_runner)
133
128
  e = StandardError.new
@@ -138,90 +133,53 @@ describe Rpush::Daemon::AppRunner, 'sync' do
138
133
  end
139
134
 
140
135
  describe Rpush::Daemon::AppRunner, 'debug' do
141
- let(:app) { double(Rpush::AppRunnerSpecService::App, :id => 1, :name => 'test', :connections => 1,
142
- :environment => 'development', :certificate => TEST_CERT, :service_name => 'app_runner_spec_service') }
143
- let(:logger) { double(Rpush::Logger, :info => nil) }
136
+ let(:app) do double(Rpush::AppRunnerSpecService::App, id: 1, name: 'test', connections: 1,
137
+ environment: 'development', certificate: TEST_CERT, service_name: 'app_runner_spec_service')
138
+ end
139
+ let(:logger) { double(Rpush::Logger, info: nil) }
140
+ let(:store) { double(all_apps: [app]) }
144
141
 
145
142
  before do
146
- Rpush::App.stub(:all => [app])
147
- Rpush::Daemon.stub(:config => {})
148
- Rpush.stub(:logger => logger)
143
+ Rpush::Daemon.stub(config: {}, store: store)
144
+ Rpush.stub(logger: logger)
149
145
  Rpush::Daemon::AppRunner.sync
150
146
  end
151
147
 
152
148
  after { Rpush::Daemon::AppRunner.runners.clear }
153
149
 
154
150
  it 'prints debug app states to the log' do
155
- Rpush.logger.should_receive(:info).with("\ntest:\n dispatchers: 1\n queued: 0\n batch size: 0\n batch processed: 0\n idle: true\n")
151
+ Rpush.logger.should_receive(:info).with(kind_of(String))
156
152
  Rpush::Daemon::AppRunner.debug
157
153
  end
158
154
  end
159
155
 
160
- describe Rpush::Daemon::AppRunner, 'idle' do
161
- let(:app) { double(Rpush::AppRunnerSpecService::App, :name => 'test', :connections => 1,
162
- :environment => 'development', :certificate => TEST_CERT, :id => 1,
163
- :service_name => 'app_runner_spec_service') }
164
- let(:logger) { double(Rpush::Logger, :info => nil) }
165
-
166
- before do
167
- Rpush::App.stub(:all => [app])
168
- Rpush.stub(:logger => logger)
169
- Rpush::Daemon::AppRunner.sync
170
- end
171
-
172
- after { Rpush::Daemon::AppRunner.runners.clear }
173
-
174
- it 'returns idle runners' do
175
- runner = Rpush::Daemon::AppRunner.runners[app.id]
176
- Rpush::Daemon::AppRunner.idle.should eq [runner]
177
- end
178
- end
179
-
180
- describe Rpush::Daemon::AppRunner, 'wait' do
181
- let(:app) { double(Rpush::AppRunnerSpecService::App, :id => 1, :name => 'test',
182
- :connections => 1, :environment => 'development', :certificate => TEST_CERT,
183
- :service_name => 'app_runner_spec_service') }
184
- let(:logger) { double(Rpush::Logger, :info => nil) }
185
-
186
- before do
187
- Rpush::App.stub(:all => [app])
188
- Rpush.stub(:logger => logger)
189
- Rpush::Daemon::AppRunner.sync
190
- end
191
-
192
- after { Rpush::Daemon::AppRunner.runners.clear }
193
-
194
- it 'waits until all runners are idle' do
195
- Rpush::Daemon::AppRunner.runners.count.should eq 1
196
- Timeout.timeout(5) { Rpush::Daemon::AppRunner.wait }
197
- end
198
- end
199
-
200
156
  describe Rpush::Daemon::AppRunner do
201
- let(:app) { double(Rpush::AppRunnerSpecService::App, :environment => :sandbox,
202
- :connections => 1, :service_name => 'app_runner_spec_service',
203
- :name => 'test') }
157
+ let(:app) do double(Rpush::AppRunnerSpecService::App, environment: :sandbox,
158
+ connections: 1, service_name: 'app_runner_spec_service',
159
+ name: 'test')
160
+ end
204
161
  let(:runner) { Rpush::Daemon::AppRunner.new(app) }
205
- let(:logger) { double(Rpush::Logger, :info => nil) }
162
+ let(:logger) { double(Rpush::Logger, info: nil) }
206
163
  let(:queue) { Queue.new }
207
164
  let(:dispatcher_loop_collection) { Rpush::Daemon::DispatcherLoopCollection.new }
208
- let(:service_loop) { double(Rpush::Daemon::AppRunnerSpecService::ServiceLoop,
209
- :start => nil, :stop => nil) }
165
+ let(:service_loop) do double(Rpush::Daemon::AppRunnerSpecService::ServiceLoop,
166
+ start: nil, stop: nil)
167
+ end
210
168
  let(:store) { double(Rpush::Daemon::Store::ActiveRecord, release_connection: nil) }
211
169
 
212
170
  before do
213
171
  Rpush::Daemon.stub(store: store)
214
- Rpush::Daemon::AppRunnerSpecService::ServiceLoop.stub(:new => service_loop)
215
- Queue.stub(:new => queue)
216
- Rpush.stub(:logger => logger)
217
- Rpush::Daemon::DispatcherLoopCollection.stub(:new => dispatcher_loop_collection)
172
+ Rpush::Daemon::AppRunnerSpecService::ServiceLoop.stub(new: service_loop)
173
+ Queue.stub(new: queue)
174
+ Rpush.stub(logger: logger)
175
+ Rpush::Daemon::DispatcherLoopCollection.stub(new: dispatcher_loop_collection)
218
176
  end
219
177
 
220
178
  describe 'start' do
221
179
  it 'starts a delivery dispatcher for each connection' do
222
- app.stub(:connections => 2)
180
+ app.stub(connections: 2)
223
181
  runner.start
224
- runner.num_dispatchers.should eq 2
182
+ runner.num_dispatcher_loops.should eq 2
225
183
  end
226
184
 
227
185
  it 'starts the loops' do
@@ -232,16 +190,18 @@ describe Rpush::Daemon::AppRunner do
232
190
 
233
191
  describe 'enqueue' do
234
192
  let(:notification) { double }
235
- let(:batch) { double(:notifications => [notification]) }
236
193
 
237
194
  it 'enqueues the batch' do
238
- queue.should_receive(:push).with([notification, batch])
239
- runner.enqueue(batch)
195
+ queue.should_receive(:push) do |queue_payload|
196
+ queue_payload.notification.should eq notification
197
+ queue_payload.batch.should_not be_nil
198
+ end
199
+ runner.enqueue([notification])
240
200
  end
241
201
 
242
202
  it 'reflects the notification has been enqueued' do
243
203
  runner.should_receive(:reflect).with(:notification_enqueued, notification)
244
- runner.enqueue(batch)
204
+ runner.enqueue([notification])
245
205
  end
246
206
  end
247
207
 
@@ -259,34 +219,17 @@ describe Rpush::Daemon::AppRunner do
259
219
  end
260
220
  end
261
221
 
262
- describe 'idle?' do
263
- it 'is idle if all notifications have been processed' do
264
- runner.batch = double(:complete? => true)
265
- runner.idle?.should be_true
266
- end
267
-
268
- it 'is idle if the runner has no associated batch' do
269
- runner.batch = nil
270
- runner.idle?.should be_true
271
- end
272
-
273
- it 'is not idle if not all notifications have been processed' do
274
- runner.batch = double(:complete? => false)
275
- runner.idle?.should be_false
276
- end
277
- end
278
-
279
222
  describe 'sync' do
280
223
  before { runner.start }
281
224
 
282
225
  it 'reduces the number of dispatchers if needed' do
283
- app.stub(:connections => 0)
284
- expect { runner.sync(app) }.to change(runner, :num_dispatchers).to(0)
226
+ app.stub(connections: 0)
227
+ expect { runner.sync(app) }.to change(runner, :num_dispatcher_loops).to(0)
285
228
  end
286
229
 
287
230
  it 'increases the number of dispatchers if needed' do
288
- app.stub(:connections => 2)
289
- expect { runner.sync(app) }.to change(runner, :num_dispatchers).to(2)
231
+ app.stub(connections: 2)
232
+ expect { runner.sync(app) }.to change(runner, :num_dispatcher_loops).to(2)
290
233
  end
291
234
  end
292
235
  end
@@ -1,23 +1,15 @@
1
1
  require 'unit_spec_helper'
2
2
 
3
3
  describe Rpush::Daemon::Batch do
4
- let(:notification1) { double(:notification1, :id => 1) }
5
- let(:notification2) { double(:notification2, :id => 2) }
4
+ let(:notification1) { double(:notification1, id: 1) }
5
+ let(:notification2) { double(:notification2, id: 2) }
6
6
  let(:batch) { Rpush::Daemon::Batch.new([notification1, notification2]) }
7
7
  let(:store) { double.as_null_object }
8
8
  let(:time) { Time.now }
9
9
 
10
10
  before do
11
- Time.stub(:now => time)
12
- Rpush::Daemon.stub(:store => store)
13
- end
14
-
15
- it 'exposes the notifications' do
16
- batch.notifications.should eq [notification1, notification2]
17
- end
18
-
19
- it 'exposes the number notifications' do
20
- batch.num_notifications.should eq 2
11
+ Time.stub(now: time)
12
+ Rpush::Daemon.stub(store: store)
21
13
  end
22
14
 
23
15
  it 'exposes the number notifications processed' do
@@ -25,125 +17,85 @@ describe Rpush::Daemon::Batch do
25
17
  end
26
18
 
27
19
  it 'increments the processed notifications count' do
28
- expect { batch.notification_dispatched }.to change(batch, :num_processed).to(1)
20
+ expect { batch.notification_processed }.to change(batch, :num_processed).to(1)
29
21
  end
30
22
 
31
23
  it 'completes the batch when all notifications have been processed' do
32
24
  batch.should_receive(:complete)
33
- 2.times { batch.notification_dispatched }
34
- end
35
-
36
- it 'can be described' do
37
- batch.describe.should eq '1, 2'
25
+ 2.times { batch.notification_processed }
38
26
  end
39
27
 
40
28
  describe 'mark_delivered' do
41
- describe 'batching is disabled' do
42
- before { Rpush.config.batch_storage_updates = false }
43
-
44
- it 'marks the notification as delivered immediately' do
45
- store.should_receive(:mark_delivered).with(notification1, time)
46
- batch.mark_delivered(notification1)
47
- end
48
-
49
- it 'reflects the notification was delivered' do
50
- batch.should_receive(:reflect).with(:notification_delivered, notification1)
51
- batch.mark_delivered(notification1)
52
- end
29
+ it 'marks the notification as delivered immediately without persisting' do
30
+ store.should_receive(:mark_delivered).with(notification1, time, persist: false)
31
+ batch.mark_delivered(notification1)
53
32
  end
54
33
 
55
- describe 'batching is enabled' do
56
- before { Rpush.config.batch_storage_updates = true }
34
+ it 'defers persisting' do
35
+ batch.mark_delivered(notification1)
36
+ batch.delivered.should eq [notification1]
37
+ end
38
+ end
57
39
 
58
- it 'marks the notification as delivered immediately without persisting' do
59
- store.should_receive(:mark_delivered).with(notification1, time, :persist => false)
60
- batch.mark_delivered(notification1)
61
- end
40
+ describe 'mark_all_delivered' do
41
+ it 'marks the notifications as delivered immediately without persisting' do
42
+ store.should_receive(:mark_delivered).with(notification1, time, persist: false)
43
+ store.should_receive(:mark_delivered).with(notification2, time, persist: false)
44
+ batch.mark_all_delivered
45
+ end
62
46
 
63
- it 'defers persisting' do
64
- batch.mark_delivered(notification1)
65
- batch.delivered.should eq [notification1]
66
- end
47
+ it 'defers persisting' do
48
+ batch.mark_all_delivered
49
+ batch.delivered.should eq [notification1, notification2]
67
50
  end
68
51
  end
69
52
 
70
53
  describe 'mark_failed' do
71
- describe 'batching is disabled' do
72
- before { Rpush.config.batch_storage_updates = false }
73
-
74
- it 'marks the notification as failed' do
75
- store.should_receive(:mark_failed).with(notification1, 1, 'an error', time)
76
- batch.mark_failed(notification1, 1, 'an error')
77
- end
78
-
79
- it 'reflects the notification failed' do
80
- batch.should_receive(:reflect).with(:notification_delivered, notification1)
81
- batch.mark_delivered(notification1)
82
- end
54
+ it 'marks the notification as failed without persisting' do
55
+ store.should_receive(:mark_failed).with(notification1, 1, 'an error', time, persist: false)
56
+ batch.mark_failed(notification1, 1, 'an error')
83
57
  end
84
58
 
85
- describe 'batching is enabled' do
86
- before { Rpush.config.batch_storage_updates = true }
59
+ it 'defers persisting' do
60
+ batch.mark_failed(notification1, 1, 'an error')
61
+ batch.failed.should eq([1, 'an error'] => [notification1])
62
+ end
63
+ end
87
64
 
88
- it 'marks the notification as failed without persisting' do
89
- store.should_receive(:mark_failed).with(notification1, 1, 'an error', time, :persist => false)
90
- batch.mark_failed(notification1, 1, 'an error')
91
- end
65
+ describe 'mark_failed' do
66
+ it 'marks the notification as failed without persisting' do
67
+ store.should_receive(:mark_failed).with(notification1, 1, 'an error', time, persist: false)
68
+ store.should_receive(:mark_failed).with(notification2, 1, 'an error', time, persist: false)
69
+ batch.mark_all_failed(1, 'an error')
70
+ end
92
71
 
93
- it 'defers persisting' do
94
- Rpush.config.batch_storage_updates = true
95
- batch.mark_failed(notification1, 1, 'an error')
96
- batch.failed.should eq({[1, 'an error'] => [notification1]})
97
- end
72
+ it 'defers persisting' do
73
+ batch.mark_all_failed(1, 'an error')
74
+ batch.failed.should eq([1, 'an error'] => [notification1, notification2])
98
75
  end
99
76
  end
100
77
 
101
78
  describe 'mark_retryable' do
102
- describe 'batching is disabled' do
103
- before { Rpush.config.batch_storage_updates = false }
104
-
105
- it 'marks the notification as retryable' do
106
- store.should_receive(:mark_retryable).with(notification1, time)
107
- batch.mark_retryable(notification1, time)
108
- end
109
-
110
- it 'reflects the notification will be retried' do
111
- batch.should_receive(:reflect).with(:notification_will_retry, notification1)
112
- batch.mark_retryable(notification1, time)
113
- end
79
+ it 'marks the notification as retryable without persisting' do
80
+ store.should_receive(:mark_retryable).with(notification1, time, persist: false)
81
+ batch.mark_retryable(notification1, time)
114
82
  end
115
83
 
116
- describe 'batching is enabled' do
117
- before { Rpush.config.batch_storage_updates = true }
118
-
119
- it 'marks the notification as retryable without persisting' do
120
- store.should_receive(:mark_retryable).with(notification1, time, :persist => false)
121
- batch.mark_retryable(notification1, time)
122
- end
123
-
124
- it 'defers persisting' do
125
- batch.mark_retryable(notification1, time)
126
- batch.retryable.should eq({time => [notification1]})
127
- end
84
+ it 'defers persisting' do
85
+ batch.mark_retryable(notification1, time)
86
+ batch.retryable.should eq(time => [notification1])
128
87
  end
129
88
  end
130
89
 
131
90
  describe 'complete' do
132
91
  before do
133
- Rpush.config.batch_storage_updates = true
134
- Rpush.stub(:logger => double.as_null_object)
92
+ Rpush.stub(logger: double.as_null_object)
135
93
  batch.stub(:reflect)
136
94
  end
137
95
 
138
- it 'clears the notifications' do
139
- expect do
140
- 2.times { batch.notification_dispatched }
141
- end.to change(batch, :notifications).to([])
142
- end
143
-
144
96
  it 'identifies as complete' do
145
97
  expect do
146
- 2.times { batch.notification_dispatched }
98
+ 2.times { batch.notification_processed }
147
99
  end.to change(batch, :complete?).to(be_true)
148
100
  end
149
101
 
@@ -151,14 +103,14 @@ describe Rpush::Daemon::Batch do
151
103
  e = StandardError.new
152
104
  batch.stub(:complete_delivered).and_raise(e)
153
105
  batch.should_receive(:reflect).with(:error, e)
154
- 2.times { batch.notification_dispatched }
106
+ 2.times { batch.notification_processed }
155
107
  end
156
108
 
157
109
  describe 'delivered' do
158
110
  def complete
159
111
  [notification1, notification2].each do |n|
160
112
  batch.mark_delivered(n)
161
- batch.notification_dispatched
113
+ batch.notification_processed
162
114
  end
163
115
  end
164
116
 
@@ -172,18 +124,13 @@ describe Rpush::Daemon::Batch do
172
124
  batch.should_receive(:reflect).with(:notification_delivered, notification2)
173
125
  complete
174
126
  end
175
-
176
- it 'clears the delivered notifications' do
177
- complete
178
- batch.delivered.should eq([])
179
- end
180
127
  end
181
128
 
182
129
  describe 'failed' do
183
130
  def complete
184
131
  [notification1, notification2].each do |n|
185
132
  batch.mark_failed(n, 1, 'an error')
186
- batch.notification_dispatched
133
+ batch.notification_processed
187
134
  end
188
135
  end
189
136
 
@@ -197,18 +144,13 @@ describe Rpush::Daemon::Batch do
197
144
  batch.should_receive(:reflect).with(:notification_failed, notification2)
198
145
  complete
199
146
  end
200
-
201
- it 'clears the failed notifications' do
202
- complete
203
- batch.failed.should eq({})
204
- end
205
147
  end
206
148
 
207
149
  describe 'retryable' do
208
150
  def complete
209
151
  [notification1, notification2].each do |n|
210
152
  batch.mark_retryable(n, time)
211
- batch.notification_dispatched
153
+ batch.notification_processed
212
154
  end
213
155
  end
214
156
 
@@ -222,11 +164,6 @@ describe Rpush::Daemon::Batch do
222
164
  batch.should_receive(:reflect).with(:notification_will_retry, notification2)
223
165
  complete
224
166
  end
225
-
226
- it 'clears the retryable notifications' do
227
- complete
228
- batch.retryable.should eq({})
229
- end
230
167
  end
231
168
  end
232
169
  end