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.
Files changed (36) hide show
  1. data/CHANGELOG.md +5 -0
  2. data/README.md +9 -18
  3. data/lib/generators/templates/rapns.rb +5 -0
  4. data/lib/rapns.rb +4 -0
  5. data/lib/rapns/apns_feedback.rb +1 -0
  6. data/lib/rapns/configuration.rb +4 -3
  7. data/lib/rapns/daemon.rb +20 -4
  8. data/lib/rapns/daemon/apns/feedback_receiver.rb +9 -11
  9. data/lib/rapns/daemon/delivery.rb +3 -20
  10. data/lib/rapns/daemon/delivery_queue.rb +2 -2
  11. data/lib/rapns/daemon/feeder.rb +5 -10
  12. data/lib/rapns/daemon/gcm/delivery.rb +19 -9
  13. data/lib/rapns/daemon/store/active_record.rb +74 -0
  14. data/lib/rapns/daemon/store/active_record/reconnectable.rb +61 -0
  15. data/lib/rapns/gcm/notification.rb +5 -4
  16. data/lib/rapns/gcm/registration_ids_count_validator.rb +1 -1
  17. data/lib/rapns/logger.rb +6 -2
  18. data/lib/rapns/push.rb +1 -0
  19. data/lib/rapns/reflection.rb +1 -1
  20. data/lib/rapns/version.rb +1 -1
  21. data/spec/unit/apns/notification_spec.rb +2 -0
  22. data/spec/unit/apns_feedback_spec.rb +5 -0
  23. data/spec/unit/configuration_spec.rb +1 -1
  24. data/spec/unit/daemon/apns/delivery_spec.rb +7 -64
  25. data/spec/unit/daemon/apns/feedback_receiver_spec.rb +2 -2
  26. data/spec/unit/daemon/feeder_spec.rb +6 -58
  27. data/spec/unit/daemon/gcm/delivery_spec.rb +49 -57
  28. data/spec/unit/daemon/{database_reconnectable_spec.rb → store/active_record/reconnectable_spec.rb} +4 -3
  29. data/spec/unit/daemon/store/active_record_spec.rb +181 -0
  30. data/spec/unit/daemon_spec.rb +27 -7
  31. data/spec/unit/gcm/notification_spec.rb +2 -9
  32. data/spec/unit/push_spec.rb +5 -0
  33. data/spec/unit/reflection_spec.rb +0 -4
  34. data/spec/unit_spec_helper.rb +4 -1
  35. metadata +28 -25
  36. data/lib/rapns/daemon/database_reconnectable.rb +0 -57
@@ -1,8 +1,9 @@
1
- require "unit_spec_helper"
1
+ require 'unit_spec_helper'
2
+ require 'rapns/daemon/store/active_record/reconnectable'
2
3
 
3
- describe Rapns::Daemon::DatabaseReconnectable do
4
+ describe Rapns::Daemon::Store::ActiveRecord::Reconnectable do
4
5
  class TestDouble
5
- include Rapns::Daemon::DatabaseReconnectable
6
+ include Rapns::Daemon::Store::ActiveRecord::Reconnectable
6
7
 
7
8
  attr_reader :name
8
9
 
@@ -0,0 +1,181 @@
1
+ require 'unit_spec_helper'
2
+ require 'rapns/daemon/store/active_record'
3
+
4
+ describe Rapns::Daemon::Store::ActiveRecord do
5
+ let(:app) { Rapns::Apns::App.create!(:name => 'my_app', :environment => 'development', :certificate => TEST_CERT) }
6
+ let(:notification) { Rapns::Apns::Notification.create!(:device_token => "a" * 64, :app => app) }
7
+ let(:store) { Rapns::Daemon::Store::ActiveRecord.new }
8
+ let(:now) { Time.now }
9
+
10
+ before { Time.stub(:now => now) }
11
+
12
+ describe 'deliverable_notifications' do
13
+ it 'checks for new notifications with the ability to reconnect the database' do
14
+ store.should_receive(:with_database_reconnect_and_retry)
15
+ store.deliverable_notifications(app)
16
+ end
17
+
18
+ it 'loads notifications in batches' do
19
+ Rapns.config.batch_size = 5000
20
+ Rapns.config.push = false
21
+ relation = stub.as_null_object
22
+ relation.should_receive(:limit).with(5000)
23
+ Rapns::Notification.stub(:ready_for_delivery => relation)
24
+ store.deliverable_notifications([app])
25
+ end
26
+
27
+ it 'does not load notification in batches if in push mode' do
28
+ Rapns.config.push = true
29
+ relation = stub.as_null_object
30
+ relation.should_not_receive(:limit)
31
+ Rapns::Notification.stub(:ready_for_delivery => relation)
32
+ store.deliverable_notifications([app])
33
+ end
34
+
35
+ it 'loads an undelivered notification without deliver_after set' do
36
+ notification.update_attributes!(:delivered => false, :deliver_after => nil)
37
+ store.deliverable_notifications([app]).should == [notification]
38
+ end
39
+
40
+ it 'loads an notification with a deliver_after time in the past' do
41
+ notification.update_attributes!(:delivered => false, :deliver_after => 1.hour.ago)
42
+ store.deliverable_notifications([app]).should == [notification]
43
+ end
44
+
45
+ it 'does not load an notification with a deliver_after time in the future' do
46
+ notification.update_attributes!(:delivered => false, :deliver_after => 1.hour.from_now)
47
+ store.deliverable_notifications([app]).should be_empty
48
+ end
49
+
50
+ it 'does not load a previously delivered notification' do
51
+ notification.update_attributes!(:delivered => true, :delivered_at => Time.now)
52
+ store.deliverable_notifications([app]).should be_empty
53
+ end
54
+
55
+ it "does not enqueue a notification that has previously failed delivery" do
56
+ notification.update_attributes!(:delivered => false, :failed => true)
57
+ store.deliverable_notifications([app]).should be_empty
58
+ end
59
+
60
+ it 'does not load notifications for apps that are still processing the previous batch' do
61
+ notification
62
+ store.deliverable_notifications([]).should be_empty
63
+ end
64
+ end
65
+
66
+ describe 'retry_after' do
67
+ it 'increments the retry count' do
68
+ expect do
69
+ store.retry_after(notification, now)
70
+ end.to change(notification, :retries).by(1)
71
+ end
72
+
73
+ it 'sets the deliver after timestamp' do
74
+ deliver_after = now + 10.seconds
75
+ expect do
76
+ store.retry_after(notification, deliver_after)
77
+ end.to change(notification, :deliver_after).to(deliver_after)
78
+ end
79
+
80
+ it 'saves the notification without validation' do
81
+ notification.should_receive(:save!).with(:validate => false)
82
+ store.retry_after(notification, now)
83
+ end
84
+ end
85
+
86
+ describe 'mark_delivered' do
87
+ it 'marks the notification as delivered' do
88
+ expect do
89
+ store.mark_delivered(notification)
90
+ end.to change(notification, :delivered).to(true)
91
+ end
92
+
93
+ it 'sets the time the notification was delivered' do
94
+ expect do
95
+ store.mark_delivered(notification)
96
+ end.to change(notification, :delivered_at).to(now)
97
+ end
98
+
99
+ it 'saves the notification without validation' do
100
+ notification.should_receive(:save!).with(:validate => false)
101
+ store.mark_delivered(notification)
102
+ end
103
+ end
104
+
105
+ describe 'mark_failed' do
106
+ it 'marks the notification as not delivered' do
107
+ store.mark_failed(notification, nil, '')
108
+ notification.delivered.should be_false
109
+ end
110
+
111
+ it 'marks the notification as failed' do
112
+ expect do
113
+ store.mark_failed(notification, nil, '')
114
+ end.to change(notification, :failed).to(true)
115
+ end
116
+
117
+ it 'sets the time the notification delivery failed' do
118
+ expect do
119
+ store.mark_failed(notification, nil, '')
120
+ end.to change(notification, :failed_at).to(now)
121
+ end
122
+
123
+ it 'sets the error code' do
124
+ expect do
125
+ store.mark_failed(notification, 42, '')
126
+ end.to change(notification, :error_code).to(42)
127
+ end
128
+
129
+ it 'sets the error description' do
130
+ expect do
131
+ store.mark_failed(notification, 42, 'Weeee')
132
+ end.to change(notification, :error_description).to('Weeee')
133
+ end
134
+
135
+ it 'saves the notification without validation' do
136
+ notification.should_receive(:save!).with(:validate => false)
137
+ store.mark_failed(notification, nil, '')
138
+ end
139
+ end
140
+
141
+ describe 'create_apns_feedback' do
142
+ it 'creates the Feedback record' do
143
+ Rapns::Apns::Feedback.should_receive(:create!).with(
144
+ :failed_at => now, :device_token => 'ab' * 32, :app => app)
145
+ store.create_apns_feedback(now, 'ab' * 32, app)
146
+ end
147
+ end
148
+
149
+ describe 'create_gcm_notification' do
150
+ let(:data) { { :data => true } }
151
+ let(:attributes) { { :device_token => 'ab' * 32 } }
152
+ let(:registration_ids) { ['123', '456'] }
153
+ let(:deliver_after) { now + 10.seconds }
154
+ let(:args) { [attributes, data, registration_ids, deliver_after, app] }
155
+
156
+ it 'sets the given attributes' do
157
+ new_notification = store.create_gcm_notification(*args)
158
+ new_notification.device_token.should == 'ab' * 32
159
+ end
160
+
161
+ it 'sets the given data' do
162
+ new_notification = store.create_gcm_notification(*args)
163
+ new_notification.data['data'].should be_true
164
+ end
165
+
166
+ it 'sets the given registration IDs' do
167
+ new_notification = store.create_gcm_notification(*args)
168
+ new_notification.registration_ids.should == registration_ids
169
+ end
170
+
171
+ it 'sets the deliver_after timestamp' do
172
+ new_notification = store.create_gcm_notification(*args)
173
+ new_notification.deliver_after.should == deliver_after
174
+ end
175
+
176
+ it 'saves the new notification' do
177
+ new_notification = store.create_gcm_notification(*args)
178
+ new_notification.new_record?.should be_false
179
+ end
180
+ end
181
+ end
@@ -1,4 +1,5 @@
1
1
  require 'unit_spec_helper'
2
+ require 'rapns/daemon/store/active_record'
2
3
 
3
4
  describe Rapns::Daemon, "when starting" do
4
5
  module Rails; end
@@ -6,27 +7,34 @@ describe Rapns::Daemon, "when starting" do
6
7
  let(:certificate) { stub }
7
8
  let(:password) { stub }
8
9
  let(:config) { stub(:pid_file => nil, :airbrake_notify => false,
9
- :foreground => true, :embedded => false, :push => false) }
10
+ :foreground => true, :embedded => false, :push => false, :store => :active_record) }
10
11
  let(:logger) { stub(:logger, :info => nil, :error => nil, :warn => nil) }
11
12
 
12
13
  before do
13
- Rapns.stub(:config => config)
14
- Rapns::Logger.stub(:new => logger)
14
+ Rapns.stub(:config => config, :logger => logger)
15
15
  Rapns::Daemon::Feeder.stub(:start)
16
16
  Rapns::Daemon::AppRunner.stub(:sync => nil, :stop => nil)
17
- Rapns::Daemon.stub(:daemonize => nil, :reconnect_database => nil, :exit => nil, :puts => nil)
17
+ Rapns::Daemon.stub(:daemonize => nil, :exit => nil, :puts => nil)
18
18
  File.stub(:open)
19
19
  Rails.stub(:root).and_return("/rails_root")
20
20
  end
21
21
 
22
- unless defined?(JRUBY_VERSION)
22
+ unless Rapns.jruby?
23
23
  it "forks into a daemon if the foreground option is false" do
24
24
  config.stub(:foreground => false)
25
- ActiveRecord::Base.stub(:establish_connection)
25
+ Rapns::Daemon.initialize_store
26
+ Rapns::Daemon.store.stub(:after_daemonize => nil)
26
27
  Rapns::Daemon.should_receive(:daemonize)
27
28
  Rapns::Daemon.start
28
29
  end
29
30
 
31
+ it 'notifies the store after forking' do
32
+ config.stub(:foreground => false)
33
+ Rapns::Daemon.initialize_store
34
+ Rapns::Daemon.store.should_receive(:after_daemonize)
35
+ Rapns::Daemon.start
36
+ end
37
+
30
38
  it "does not fork into a daemon if the foreground option is true" do
31
39
  config.stub(:foreground => true)
32
40
  Rapns::Daemon.should_not_receive(:daemonize)
@@ -57,6 +65,18 @@ describe Rapns::Daemon, "when starting" do
57
65
  Rapns::Daemon.start
58
66
  end
59
67
 
68
+ it 'instantiates the store' do
69
+ config.stub(:store => :active_record)
70
+ Rapns::Daemon.start
71
+ Rapns::Daemon.store.should be_kind_of(Rapns::Daemon::Store::ActiveRecord)
72
+ end
73
+
74
+ it 'logs an error if the store cannot be loaded' do
75
+ config.stub(:store => :foo_bar)
76
+ Rapns.logger.should_receive(:error).with(kind_of(LoadError))
77
+ Rapns::Daemon.start
78
+ end
79
+
60
80
  it "writes the process ID to the PID file" do
61
81
  Rapns::Daemon.should_receive(:write_pid_file)
62
82
  Rapns::Daemon.start
@@ -91,7 +111,7 @@ describe Rapns::Daemon, "when being shutdown" do
91
111
  end
92
112
 
93
113
  # These tests do not work on JRuby.
94
- unless defined? JRUBY_VERSION
114
+ unless Rapns.jruby?
95
115
  it "shuts down when signaled signaled SIGINT" do
96
116
  Rapns::Daemon.setup_signal_traps
97
117
  Rapns::Daemon.should_receive(:shutdown)
@@ -27,7 +27,7 @@ describe Rapns::Gcm::Notification do
27
27
  it 'num of registration Ids limit of 1000' do
28
28
  notification.registration_ids = ['a']*(1000+1)
29
29
  notification.valid?.should be_false
30
- notification.errors[:base].should == ["GCM notification num of registration_ids cannot be larger than 1000."]
30
+ notification.errors[:base].should == ["GCM notification number of registration_ids cannot be larger than 1000."]
31
31
  end
32
32
 
33
33
  it 'allows assignment of a single registration ID' do
@@ -45,15 +45,8 @@ describe Rapns::Gcm::Notification do
45
45
  notification.errors[:expiry].should == ['must be set when using a collapse_key']
46
46
  end
47
47
 
48
- it 'does not include time_to_live in the payload if collapse_key is not set' do
48
+ it 'includes time_to_live in the payload' do
49
49
  notification.expiry = 100
50
- notification.collapse_key = nil
51
- notification.as_json.key?('time_to_live').should be_false
52
- end
53
-
54
- it 'includes time_to_live in the payload if collapse_key is set' do
55
- notification.expiry = 100
56
- notification.collapse_key = 'sync'
57
50
  notification.as_json['time_to_live'].should == 100
58
51
  end
59
52
  end
@@ -12,6 +12,11 @@ describe Rapns, 'push' do
12
12
  Rapns.config.push.should be_true
13
13
  end
14
14
 
15
+ it 'initializes the store' do
16
+ Rapns::Daemon.should_receive(:initialize_store)
17
+ Rapns.push
18
+ end
19
+
15
20
  it 'syncs the app runner' do
16
21
  Rapns::Daemon::AppRunner.should_receive(:sync)
17
22
  Rapns.push
@@ -12,10 +12,6 @@ describe Rapns do
12
12
  end
13
13
  end
14
14
 
15
- # :apns_feedback, :notification_enqueued, :notification_delivered,
16
- # :notification_failed, :notification_will_retry, :apns_connection_lost,
17
- # :error
18
-
19
15
  describe Rapns::Reflections do
20
16
  it 'dispatches the given reflection' do
21
17
  did_yield = false
@@ -72,7 +72,10 @@ RSpec.configure do |config|
72
72
  DatabaseCleaner.clean
73
73
  end
74
74
 
75
- config.after(:each) { Rapns.logger = nil }
75
+ config.after(:each) do
76
+ Rapns.logger = nil
77
+ Rapns::Daemon.store = nil
78
+ end
76
79
  end
77
80
 
78
81
  # a test certificate that contains both an X509 certificate and
metadata CHANGED
@@ -1,85 +1,85 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rapns
3
3
  version: !ruby/object:Gem::Version
4
+ version: 3.3.0
4
5
  prerelease:
5
- version: 3.2.0
6
6
  platform: java
7
7
  authors:
8
8
  - Ian Leitch
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-04-02 00:00:00.000000000 Z
12
+ date: 2013-04-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: multi_json
16
- version_requirements: !ruby/object:Gem::Requirement
15
+ requirement: !ruby/object:Gem::Requirement
17
16
  requirements:
18
17
  - - "~>"
19
18
  - !ruby/object:Gem::Version
20
19
  version: '1.0'
21
20
  none: false
22
- requirement: !ruby/object:Gem::Requirement
21
+ prerelease: false
22
+ name: multi_json
23
+ version_requirements: !ruby/object:Gem::Requirement
23
24
  requirements:
24
25
  - - "~>"
25
26
  - !ruby/object:Gem::Version
26
27
  version: '1.0'
27
28
  none: false
28
- prerelease: false
29
29
  type: :runtime
30
30
  - !ruby/object:Gem::Dependency
31
- name: net-http-persistent
32
- version_requirements: !ruby/object:Gem::Requirement
31
+ requirement: !ruby/object:Gem::Requirement
33
32
  requirements:
34
33
  - - ">="
35
34
  - !ruby/object:Gem::Version
36
35
  version: !binary |-
37
36
  MA==
38
37
  none: false
39
- requirement: !ruby/object:Gem::Requirement
38
+ prerelease: false
39
+ name: net-http-persistent
40
+ version_requirements: !ruby/object:Gem::Requirement
40
41
  requirements:
41
42
  - - ">="
42
43
  - !ruby/object:Gem::Version
43
44
  version: !binary |-
44
45
  MA==
45
46
  none: false
46
- prerelease: false
47
47
  type: :runtime
48
48
  - !ruby/object:Gem::Dependency
49
- name: jruby-openssl
50
- version_requirements: !ruby/object:Gem::Requirement
49
+ requirement: !ruby/object:Gem::Requirement
51
50
  requirements:
52
51
  - - ">="
53
52
  - !ruby/object:Gem::Version
54
53
  version: !binary |-
55
54
  MA==
56
55
  none: false
57
- requirement: !ruby/object:Gem::Requirement
56
+ prerelease: false
57
+ name: jruby-openssl
58
+ version_requirements: !ruby/object:Gem::Requirement
58
59
  requirements:
59
60
  - - ">="
60
61
  - !ruby/object:Gem::Version
61
62
  version: !binary |-
62
63
  MA==
63
64
  none: false
64
- prerelease: false
65
65
  type: :runtime
66
66
  - !ruby/object:Gem::Dependency
67
- name: activerecord-jdbc-adapter
68
- version_requirements: !ruby/object:Gem::Requirement
67
+ requirement: !ruby/object:Gem::Requirement
69
68
  requirements:
70
69
  - - ">="
71
70
  - !ruby/object:Gem::Version
72
71
  version: !binary |-
73
72
  MA==
74
73
  none: false
75
- requirement: !ruby/object:Gem::Requirement
74
+ prerelease: false
75
+ name: activerecord-jdbc-adapter
76
+ version_requirements: !ruby/object:Gem::Requirement
76
77
  requirements:
77
78
  - - ">="
78
79
  - !ruby/object:Gem::Version
79
80
  version: !binary |-
80
81
  MA==
81
82
  none: false
82
- prerelease: false
83
83
  type: :runtime
84
84
  description: Professional grade APNs and GCM for Ruby
85
85
  email:
@@ -118,7 +118,6 @@ files:
118
118
  - lib/rapns/daemon/apns/disconnection_error.rb
119
119
  - lib/rapns/daemon/apns/feedback_receiver.rb
120
120
  - lib/rapns/daemon/app_runner.rb
121
- - lib/rapns/daemon/database_reconnectable.rb
122
121
  - lib/rapns/daemon/delivery.rb
123
122
  - lib/rapns/daemon/delivery_error.rb
124
123
  - lib/rapns/daemon/delivery_handler.rb
@@ -131,6 +130,8 @@ files:
131
130
  - lib/rapns/daemon/gcm/delivery_handler.rb
132
131
  - lib/rapns/daemon/interruptible_sleep.rb
133
132
  - lib/rapns/daemon/reflectable.rb
133
+ - lib/rapns/daemon/store/active_record.rb
134
+ - lib/rapns/daemon/store/active_record/reconnectable.rb
134
135
  - lib/rapns/deprecatable.rb
135
136
  - lib/rapns/deprecation.rb
136
137
  - lib/rapns/embed.rb
@@ -172,7 +173,6 @@ files:
172
173
  - spec/unit/daemon/apns/feedback_receiver_spec.rb
173
174
  - spec/unit/daemon/app_runner_shared.rb
174
175
  - spec/unit/daemon/app_runner_spec.rb
175
- - spec/unit/daemon/database_reconnectable_spec.rb
176
176
  - spec/unit/daemon/delivery_error_spec.rb
177
177
  - spec/unit/daemon/delivery_handler_shared.rb
178
178
  - spec/unit/daemon/delivery_queue_spec.rb
@@ -182,6 +182,8 @@ files:
182
182
  - spec/unit/daemon/gcm/delivery_spec.rb
183
183
  - spec/unit/daemon/interruptible_sleep_spec.rb
184
184
  - spec/unit/daemon/reflectable_spec.rb
185
+ - spec/unit/daemon/store/active_record/reconnectable_spec.rb
186
+ - spec/unit/daemon/store/active_record_spec.rb
185
187
  - spec/unit/daemon_spec.rb
186
188
  - spec/unit/deprecatable_spec.rb
187
189
  - spec/unit/deprecation_spec.rb
@@ -207,21 +209,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
207
209
  requirements:
208
210
  - - ">="
209
211
  - !ruby/object:Gem::Version
210
- segments:
211
- - 0
212
212
  hash: 2
213
213
  version: !binary |-
214
214
  MA==
215
+ segments:
216
+ - 0
215
217
  none: false
216
218
  required_rubygems_version: !ruby/object:Gem::Requirement
217
219
  requirements:
218
220
  - - ">="
219
221
  - !ruby/object:Gem::Version
220
- segments:
221
- - 0
222
222
  hash: 2
223
223
  version: !binary |-
224
224
  MA==
225
+ segments:
226
+ - 0
225
227
  none: false
226
228
  requirements: []
227
229
  rubyforge_project:
@@ -251,7 +253,6 @@ test_files:
251
253
  - spec/unit/daemon/apns/feedback_receiver_spec.rb
252
254
  - spec/unit/daemon/app_runner_shared.rb
253
255
  - spec/unit/daemon/app_runner_spec.rb
254
- - spec/unit/daemon/database_reconnectable_spec.rb
255
256
  - spec/unit/daemon/delivery_error_spec.rb
256
257
  - spec/unit/daemon/delivery_handler_shared.rb
257
258
  - spec/unit/daemon/delivery_queue_spec.rb
@@ -261,6 +262,8 @@ test_files:
261
262
  - spec/unit/daemon/gcm/delivery_spec.rb
262
263
  - spec/unit/daemon/interruptible_sleep_spec.rb
263
264
  - spec/unit/daemon/reflectable_spec.rb
265
+ - spec/unit/daemon/store/active_record/reconnectable_spec.rb
266
+ - spec/unit/daemon/store/active_record_spec.rb
264
267
  - spec/unit/daemon_spec.rb
265
268
  - spec/unit/deprecatable_spec.rb
266
269
  - spec/unit/deprecation_spec.rb