rapns 3.0.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +10 -2
- data/README.md +26 -3
- data/bin/rapns +2 -7
- data/lib/generators/templates/add_gcm.rb +3 -1
- data/lib/generators/templates/rapns.rb +42 -11
- data/lib/rapns/apns/notification.rb +8 -2
- data/lib/rapns/app.rb +3 -3
- data/lib/rapns/configuration.rb +46 -13
- data/lib/rapns/daemon/apns/connection.rb +12 -9
- data/lib/rapns/daemon/apns/delivery_handler.rb +1 -1
- data/lib/rapns/daemon/apns/feedback_receiver.rb +6 -2
- data/lib/rapns/daemon/app_runner.rb +23 -7
- data/lib/rapns/daemon/delivery.rb +5 -1
- data/lib/rapns/daemon/delivery_handler.rb +4 -0
- data/lib/rapns/daemon/feeder.rb +26 -5
- data/lib/rapns/daemon/reflectable.rb +13 -0
- data/lib/rapns/daemon.rb +33 -22
- data/lib/rapns/embed.rb +28 -0
- data/lib/rapns/gcm/notification.rb +7 -2
- data/lib/rapns/gcm/payload_data_size_validator.rb +13 -0
- data/lib/rapns/gcm/registration_ids_count_validator.rb +13 -0
- data/lib/rapns/push.rb +12 -0
- data/lib/rapns/reflection.rb +44 -0
- data/lib/rapns/version.rb +1 -1
- data/lib/rapns.rb +11 -1
- data/spec/support/cert_with_password.pem +90 -0
- data/spec/support/cert_without_password.pem +59 -0
- data/spec/unit/apns/app_spec.rb +15 -1
- data/spec/unit/apns/notification_spec.rb +16 -1
- data/spec/unit/configuration_spec.rb +10 -1
- data/spec/unit/daemon/apns/connection_spec.rb +11 -2
- data/spec/unit/daemon/apns/delivery_handler_spec.rb +1 -1
- data/spec/unit/daemon/apns/delivery_spec.rb +10 -0
- data/spec/unit/daemon/apns/feedback_receiver_spec.rb +16 -7
- data/spec/unit/daemon/delivery_handler_shared.rb +8 -0
- data/spec/unit/daemon/feeder_spec.rb +37 -6
- data/spec/unit/daemon/gcm/delivery_spec.rb +33 -1
- data/spec/unit/daemon/reflectable_spec.rb +27 -0
- data/spec/unit/daemon_spec.rb +55 -9
- data/spec/unit/embed_spec.rb +44 -0
- data/spec/unit/gcm/notification_spec.rb +9 -3
- data/spec/unit/push_spec.rb +28 -0
- data/spec/unit/reflection_spec.rb +34 -0
- data/spec/unit_spec_helper.rb +4 -62
- metadata +22 -5
- data/lib/rapns/gcm/payload_size_validator.rb +0 -13
@@ -1,19 +1,27 @@
|
|
1
1
|
require "unit_spec_helper"
|
2
2
|
|
3
3
|
describe Rapns::Daemon::Feeder do
|
4
|
-
let(:config) { stub(:batch_size => 5000
|
4
|
+
let(:config) { stub(:batch_size => 5000, :push_poll => 0, :embedded => false,
|
5
|
+
:push => false) }
|
5
6
|
let!(:app) { Rapns::Apns::App.create!(:name => 'my_app', :environment => 'development', :certificate => TEST_CERT) }
|
6
7
|
let(:notification) { Rapns::Apns::Notification.create!(:device_token => "a" * 64, :app => app) }
|
7
8
|
let(:logger) { stub }
|
8
9
|
|
9
10
|
before do
|
10
|
-
Rapns
|
11
|
-
Rapns::Daemon::Feeder.
|
11
|
+
Rapns.stub(:config => config)
|
12
|
+
Rapns::Daemon::Feeder.stub(:stop? => true)
|
12
13
|
Rapns::Daemon::AppRunner.stub(:idle => [stub(:app => app)])
|
13
14
|
end
|
14
15
|
|
15
16
|
def start
|
16
|
-
Rapns::Daemon::Feeder.start
|
17
|
+
Rapns::Daemon::Feeder.start
|
18
|
+
end
|
19
|
+
|
20
|
+
it "starts the loop in a new thread if embedded" do
|
21
|
+
config.stub(:embedded => true)
|
22
|
+
Thread.should_receive(:new).and_yield
|
23
|
+
Rapns::Daemon::Feeder.should_receive(:feed_forever)
|
24
|
+
start
|
17
25
|
end
|
18
26
|
|
19
27
|
it "checks for new notifications with the ability to reconnect the database" do
|
@@ -21,6 +29,13 @@ describe Rapns::Daemon::Feeder do
|
|
21
29
|
start
|
22
30
|
end
|
23
31
|
|
32
|
+
it 'enqueues notifications without looping if in push mode' do
|
33
|
+
config.stub(:push => true)
|
34
|
+
Rapns::Daemon::Feeder.should_not_receive(:feed_forever)
|
35
|
+
Rapns::Daemon::Feeder.should_receive(:enqueue_notifications)
|
36
|
+
start
|
37
|
+
end
|
38
|
+
|
24
39
|
it 'loads notifications in batches' do
|
25
40
|
relation = stub.as_null_object
|
26
41
|
relation.should_receive(:limit).with(5000)
|
@@ -28,12 +43,27 @@ describe Rapns::Daemon::Feeder do
|
|
28
43
|
start
|
29
44
|
end
|
30
45
|
|
31
|
-
it
|
46
|
+
it 'does not load notification in batches if in push mode' do
|
47
|
+
config.stub(:push => true)
|
48
|
+
relation = stub.as_null_object
|
49
|
+
relation.should_not_receive(:limit)
|
50
|
+
Rapns::Notification.stub(:ready_for_delivery => relation)
|
51
|
+
start
|
52
|
+
end
|
53
|
+
|
54
|
+
it "enqueues the notification" do
|
32
55
|
notification.update_attributes!(:delivered => false)
|
33
56
|
Rapns::Daemon::AppRunner.should_receive(:enqueue).with(notification)
|
34
57
|
start
|
35
58
|
end
|
36
59
|
|
60
|
+
it 'reflects the notification has been enqueued' do
|
61
|
+
notification.update_attributes!(:delivered => false)
|
62
|
+
Rapns::Daemon::AppRunner.stub(:enqueue)
|
63
|
+
Rapns::Daemon::Feeder.should_receive(:reflect).with(:notification_enqueued, notification)
|
64
|
+
start
|
65
|
+
end
|
66
|
+
|
37
67
|
it 'does not enqueue the notification if the app runner is still processing the previous batch' do
|
38
68
|
Rapns::Daemon::AppRunner.should_not_receive(:enqueue)
|
39
69
|
start
|
@@ -88,8 +118,9 @@ describe Rapns::Daemon::Feeder do
|
|
88
118
|
end
|
89
119
|
|
90
120
|
it "sleeps for the given period" do
|
121
|
+
config.stub(:push_poll => 2)
|
91
122
|
Rapns::Daemon::Feeder.should_receive(:interruptible_sleep).with(2)
|
92
123
|
Rapns::Daemon::Feeder.stub(:loop).and_yield
|
93
|
-
Rapns::Daemon::Feeder.start
|
124
|
+
Rapns::Daemon::Feeder.start
|
94
125
|
end
|
95
126
|
end
|
@@ -7,9 +7,10 @@ describe Rapns::Daemon::Gcm::Delivery do
|
|
7
7
|
let(:response) { stub(:code => 200, :header => {}) }
|
8
8
|
let(:http) { stub(:shutdown => nil, :request => response)}
|
9
9
|
let(:now) { Time.parse('2012-10-14 00:00:00') }
|
10
|
+
let(:delivery) { Rapns::Daemon::Gcm::Delivery.new(app, http, notification) }
|
10
11
|
|
11
12
|
def perform
|
12
|
-
|
13
|
+
delivery.perform
|
13
14
|
end
|
14
15
|
|
15
16
|
before do
|
@@ -29,6 +30,12 @@ describe Rapns::Daemon::Gcm::Delivery do
|
|
29
30
|
end.to change(notification, :delivered).to(true)
|
30
31
|
end
|
31
32
|
|
33
|
+
it 'reflects the notification was delivered' do
|
34
|
+
response.stub(:body => JSON.dump({ 'failure' => 0 }))
|
35
|
+
delivery.should_receive(:reflect).with(:notification_delivered, notification)
|
36
|
+
perform
|
37
|
+
end
|
38
|
+
|
32
39
|
it 'logs that the notification was delivered' do
|
33
40
|
response.stub(:body => JSON.dump({ 'failure' => 0 }))
|
34
41
|
logger.should_receive(:info).with("[MyApp] 1 sent to xyz")
|
@@ -105,6 +112,11 @@ describe Rapns::Daemon::Gcm::Delivery do
|
|
105
112
|
notification.error_description.should == error_description
|
106
113
|
end
|
107
114
|
|
115
|
+
it 'reflects the notification delivery failed' do
|
116
|
+
delivery.should_receive(:reflect).with(:notification_failed, notification)
|
117
|
+
perform rescue Rapns::DeliveryError
|
118
|
+
end
|
119
|
+
|
108
120
|
it 'creates a new notification for the unavailable devices' do
|
109
121
|
notification.update_attributes(:registration_ids => ['id_0', 'id_1', 'id_2'], :data => {'one' => 1}, :collapse_key => 'thing', :delay_while_idle => true)
|
110
122
|
perform rescue Rapns::DeliveryError
|
@@ -179,6 +191,11 @@ describe Rapns::Daemon::Gcm::Delivery do
|
|
179
191
|
perform
|
180
192
|
end.to change(notification, :deliver_after).to(now + 2 ** 1)
|
181
193
|
end
|
194
|
+
|
195
|
+
it 'reflects the notification will be retried' do
|
196
|
+
delivery.should_receive(:reflect).with(:notification_will_retry, notification)
|
197
|
+
perform
|
198
|
+
end
|
182
199
|
end
|
183
200
|
|
184
201
|
describe 'an 500 response' do
|
@@ -198,6 +215,11 @@ describe Rapns::Daemon::Gcm::Delivery do
|
|
198
215
|
notification.reload
|
199
216
|
end.to change(notification, :deliver_after).to(now + 2 ** 3)
|
200
217
|
end
|
218
|
+
|
219
|
+
it 'reflects the notification will be retried' do
|
220
|
+
delivery.should_receive(:reflect).with(:notification_will_retry, notification)
|
221
|
+
perform
|
222
|
+
end
|
201
223
|
end
|
202
224
|
|
203
225
|
describe 'an 401 response' do
|
@@ -219,6 +241,11 @@ describe Rapns::Daemon::Gcm::Delivery do
|
|
219
241
|
notification.error_code.should == 400
|
220
242
|
notification.error_description.should == 'GCM failed to parse the JSON request. Possibly an rapns bug, please open an issue.'
|
221
243
|
end
|
244
|
+
|
245
|
+
it 'reflects the notification delivery failed' do
|
246
|
+
delivery.should_receive(:reflect).with(:notification_failed, notification)
|
247
|
+
perform rescue Rapns::DeliveryError
|
248
|
+
end
|
222
249
|
end
|
223
250
|
|
224
251
|
describe 'an un-handled response' do
|
@@ -232,5 +259,10 @@ describe Rapns::Daemon::Gcm::Delivery do
|
|
232
259
|
notification.error_code.should == 418
|
233
260
|
notification.error_description.should == "I'm a Teapot"
|
234
261
|
end
|
262
|
+
|
263
|
+
it 'reflects the notification delivery failed' do
|
264
|
+
delivery.should_receive(:reflect).with(:notification_failed, notification)
|
265
|
+
perform rescue Rapns::DeliveryError
|
266
|
+
end
|
235
267
|
end
|
236
268
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'unit_spec_helper'
|
2
|
+
|
3
|
+
describe Rapns::Daemon::Reflectable do
|
4
|
+
class TestReflectable
|
5
|
+
include Rapns::Daemon::Reflectable
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:logger) { stub(:error => nil) }
|
9
|
+
let(:test_reflectable) { TestReflectable.new }
|
10
|
+
|
11
|
+
before do
|
12
|
+
Rapns.reflections.stub(:__dispatch)
|
13
|
+
Rapns::Daemon.stub(:logger => logger)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'dispatches the given reflection' do
|
17
|
+
Rapns.reflections.should_receive(:__dispatch).with(:error)
|
18
|
+
test_reflectable.reflect(:error)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'logs errors raise by the reflection' do
|
22
|
+
error = StandardError.new
|
23
|
+
Rapns.reflections.stub(:__dispatch).and_raise(error)
|
24
|
+
Rapns::Daemon.logger.should_receive(:error).with(error)
|
25
|
+
test_reflectable.reflect(:error)
|
26
|
+
end
|
27
|
+
end
|
data/spec/unit/daemon_spec.rb
CHANGED
@@ -5,7 +5,8 @@ describe Rapns::Daemon, "when starting" do
|
|
5
5
|
|
6
6
|
let(:certificate) { stub }
|
7
7
|
let(:password) { stub }
|
8
|
-
let(:config) { stub(:pid_file => nil, :
|
8
|
+
let(:config) { stub(:pid_file => nil, :airbrake_notify => false,
|
9
|
+
:foreground => true, :embedded => false, :push => false) }
|
9
10
|
let(:logger) { stub(:info => nil, :error => nil, :warn => nil) }
|
10
11
|
|
11
12
|
before do
|
@@ -31,6 +32,35 @@ describe Rapns::Daemon, "when starting" do
|
|
31
32
|
Rapns::Daemon.start
|
32
33
|
end
|
33
34
|
|
35
|
+
it "does not fork into a daemon if the push option is true" do
|
36
|
+
config.stub(:push => true)
|
37
|
+
Rapns::Daemon.should_not_receive(:daemonize)
|
38
|
+
Rapns::Daemon.start
|
39
|
+
end
|
40
|
+
|
41
|
+
it "does not fork into a daemon if the embedded option is true" do
|
42
|
+
config.stub(:embedded => true)
|
43
|
+
Rapns::Daemon.should_not_receive(:daemonize)
|
44
|
+
Rapns::Daemon.start
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'sets up setup signal traps' do
|
48
|
+
Rapns::Daemon.should_receive(:setup_signal_traps)
|
49
|
+
Rapns::Daemon.start
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'does not setup signal traps when embedded' do
|
53
|
+
config.stub(:embedded => true)
|
54
|
+
Rapns::Daemon.should_not_receive(:setup_signal_traps)
|
55
|
+
Rapns::Daemon.start
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'does not setup signal traps when in push mode' do
|
59
|
+
config.stub(:push => true)
|
60
|
+
Rapns::Daemon.should_not_receive(:setup_signal_traps)
|
61
|
+
Rapns::Daemon.start
|
62
|
+
end
|
63
|
+
|
34
64
|
it "writes the process ID to the PID file" do
|
35
65
|
Rapns::Daemon.should_receive(:write_pid_file)
|
36
66
|
Rapns::Daemon.start
|
@@ -44,7 +74,7 @@ describe Rapns::Daemon, "when starting" do
|
|
44
74
|
end
|
45
75
|
|
46
76
|
it "starts the feeder" do
|
47
|
-
Rapns::Daemon::Feeder.should_receive(:start)
|
77
|
+
Rapns::Daemon::Feeder.should_receive(:start)
|
48
78
|
Rapns::Daemon.start
|
49
79
|
end
|
50
80
|
|
@@ -77,6 +107,22 @@ describe Rapns::Daemon, "when starting" do
|
|
77
107
|
Rapns::Daemon.start
|
78
108
|
end
|
79
109
|
|
110
|
+
it 'does not exit if Rapns has not been upgraded and is embedded' do
|
111
|
+
config.stub(:embedded => true)
|
112
|
+
Rapns::App.stub(:count).and_raise(ActiveRecord::StatementInvalid)
|
113
|
+
Rapns::Daemon.should_receive(:puts).any_number_of_times
|
114
|
+
Rapns::Daemon.should_not_receive(:exit)
|
115
|
+
Rapns::Daemon.start
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'does not exit if Rapns has not been upgraded and is in push mode' do
|
119
|
+
config.stub(:push => true)
|
120
|
+
Rapns::App.stub(:count).and_raise(ActiveRecord::StatementInvalid)
|
121
|
+
Rapns::Daemon.should_receive(:puts).any_number_of_times
|
122
|
+
Rapns::Daemon.should_not_receive(:exit)
|
123
|
+
Rapns::Daemon.start
|
124
|
+
end
|
125
|
+
|
80
126
|
it 'warns if rapns.yml still exists' do
|
81
127
|
File.should_receive(:exists?).with('/rails_root/config/rapns/rapns.yml').and_return(true)
|
82
128
|
logger.should_receive(:warn).with("Since 2.0.0 rapns uses command-line options and a Ruby based configuration file.\nPlease run 'rails g rapns' to generate a new configuration file into config/initializers.\nRemove config/rapns/rapns.yml to avoid this warning.\n")
|
@@ -97,13 +143,13 @@ describe Rapns::Daemon, "when being shutdown" do
|
|
97
143
|
# These tests do not work on JRuby.
|
98
144
|
unless defined? JRUBY_VERSION
|
99
145
|
it "shuts down when signaled signaled SIGINT" do
|
100
|
-
Rapns::Daemon.
|
146
|
+
Rapns::Daemon.setup_signal_traps
|
101
147
|
Rapns::Daemon.should_receive(:shutdown)
|
102
148
|
Process.kill("SIGINT", Process.pid)
|
103
149
|
end
|
104
150
|
|
105
151
|
it "shuts down when signaled signaled SIGTERM" do
|
106
|
-
Rapns::Daemon.
|
152
|
+
Rapns::Daemon.setup_signal_traps
|
107
153
|
Rapns::Daemon.should_receive(:shutdown)
|
108
154
|
Process.kill("SIGTERM", Process.pid)
|
109
155
|
end
|
@@ -111,29 +157,29 @@ describe Rapns::Daemon, "when being shutdown" do
|
|
111
157
|
|
112
158
|
it "stops the feeder" do
|
113
159
|
Rapns::Daemon::Feeder.should_receive(:stop)
|
114
|
-
Rapns::Daemon.
|
160
|
+
Rapns::Daemon.shutdown
|
115
161
|
end
|
116
162
|
|
117
163
|
it "stops the app runners" do
|
118
164
|
Rapns::Daemon::AppRunner.should_receive(:stop)
|
119
|
-
Rapns::Daemon.
|
165
|
+
Rapns::Daemon.shutdown
|
120
166
|
end
|
121
167
|
|
122
168
|
it "removes the PID file if one was written" do
|
123
169
|
File.stub(:exists?).and_return(true)
|
124
170
|
File.should_receive(:delete).with("/rails_root/rapns.pid")
|
125
|
-
Rapns::Daemon.
|
171
|
+
Rapns::Daemon.shutdown
|
126
172
|
end
|
127
173
|
|
128
174
|
it "does not attempt to remove the PID file if it does not exist" do
|
129
175
|
File.stub(:exists?).and_return(false)
|
130
176
|
File.should_not_receive(:delete)
|
131
|
-
Rapns::Daemon.
|
177
|
+
Rapns::Daemon.shutdown
|
132
178
|
end
|
133
179
|
|
134
180
|
it "does not attempt to remove the PID file if one was not written" do
|
135
181
|
config.stub(:pid_file).and_return(nil)
|
136
182
|
File.should_not_receive(:delete)
|
137
|
-
Rapns::Daemon.
|
183
|
+
Rapns::Daemon.shutdown
|
138
184
|
end
|
139
185
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'unit_spec_helper'
|
2
|
+
|
3
|
+
describe Rapns, 'embed' do
|
4
|
+
before do
|
5
|
+
Rapns::Daemon.stub(:start)
|
6
|
+
Kernel.stub(:at_exit)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'sets the embedded config option to true' do
|
10
|
+
Rapns.embed
|
11
|
+
Rapns.config.embedded.should be_true
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'starts the daemon' do
|
15
|
+
Rapns::Daemon.should_receive(:start)
|
16
|
+
Rapns.embed
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'overrides the default config options with those given as a hash' do
|
20
|
+
Rapns.config.push_poll = 4
|
21
|
+
expect { Rapns.embed(:push_poll => 2) }.to change(Rapns.config, :push_poll).to(2)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe Rapns, 'shutdown' do
|
26
|
+
it 'shuts down the daemon' do
|
27
|
+
Rapns::Daemon.should_receive(:shutdown)
|
28
|
+
Rapns.shutdown
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe Rapns, 'sync' do
|
33
|
+
it 'syncs the AppRunner' do
|
34
|
+
Rapns::Daemon::AppRunner.should_receive(:sync)
|
35
|
+
Rapns.sync
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe Rapns, 'debug' do
|
40
|
+
it 'debugs the AppRunner' do
|
41
|
+
Rapns::Daemon::AppRunner.should_receive(:debug)
|
42
|
+
Rapns.debug
|
43
|
+
end
|
44
|
+
end
|
@@ -12,10 +12,10 @@ describe Rapns::Gcm::Notification do
|
|
12
12
|
|
13
13
|
it { should validate_presence_of :registration_ids }
|
14
14
|
|
15
|
-
it
|
15
|
+
it "has a 'data' payload limit of 4096 bytes" do
|
16
16
|
notification.data = { :key => "a" * 4096 }
|
17
17
|
notification.valid?.should be_false
|
18
|
-
notification.errors[:base].should == ["GCM notification payload cannot be larger than 4096 bytes."]
|
18
|
+
notification.errors[:base].should == ["GCM notification payload data cannot be larger than 4096 bytes."]
|
19
19
|
end
|
20
20
|
|
21
21
|
it 'allows assignment of many registration IDs' do
|
@@ -26,6 +26,12 @@ describe Rapns::Gcm::Notification do
|
|
26
26
|
reloaded_notification.registration_ids.should == ['a', 'b']
|
27
27
|
end
|
28
28
|
|
29
|
+
it 'num of registration Ids limit of 1000' do
|
30
|
+
notification.registration_ids = ['a']*(1000+1)
|
31
|
+
notification.valid?.should be_false
|
32
|
+
notification.errors[:base].should == ["GCM notification num of registration_ids cannot be larger than 1000."]
|
33
|
+
end
|
34
|
+
|
29
35
|
it 'allows assignment of a single registration ID' do
|
30
36
|
notification.app = app
|
31
37
|
notification.registration_ids = 'a'
|
@@ -52,4 +58,4 @@ describe Rapns::Gcm::Notification do
|
|
52
58
|
notification.collapse_key = 'sync'
|
53
59
|
notification.as_json['time_to_live'].should == 100
|
54
60
|
end
|
55
|
-
end
|
61
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'unit_spec_helper'
|
2
|
+
|
3
|
+
describe Rapns, 'push' do
|
4
|
+
before do
|
5
|
+
Rapns::Daemon.stub(:start)
|
6
|
+
Rapns::Daemon.stub(:shutdown)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'sets the push config option to true' do
|
10
|
+
Rapns.push
|
11
|
+
Rapns.config.push.should be_true
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'starts the daemon' do
|
15
|
+
Rapns::Daemon.should_receive(:start)
|
16
|
+
Rapns.push
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'shuts down the daemon' do
|
20
|
+
Rapns::Daemon.should_receive(:shutdown).with(true)
|
21
|
+
Rapns.push
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'overrides the default config options with those given as a hash' do
|
25
|
+
Rapns.config.push_poll = 4
|
26
|
+
expect { Rapns.push(:push_poll => 2) }.to change(Rapns.config, :push_poll).to(2)
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'unit_spec_helper'
|
2
|
+
|
3
|
+
describe Rapns do
|
4
|
+
it 'yields reflections for configuration' do
|
5
|
+
did_yield = false
|
6
|
+
Rapns.reflect { |on| did_yield = true }
|
7
|
+
did_yield.should be_true
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'returns all reflections' do
|
11
|
+
Rapns.reflections.should be_kind_of(Rapns::Reflections)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# :apns_feedback, :notification_enqueued, :notification_delivered,
|
16
|
+
# :notification_failed, :notification_will_retry, :apns_connection_lost,
|
17
|
+
# :error
|
18
|
+
|
19
|
+
describe Rapns::Reflections do
|
20
|
+
it 'dispatches the given reflection' do
|
21
|
+
did_yield = false
|
22
|
+
Rapns.reflect do |on|
|
23
|
+
on.error { did_yield = true }
|
24
|
+
end
|
25
|
+
Rapns.reflections.__dispatch(:error)
|
26
|
+
did_yield.should be_true
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'raises an error when trying to dispatch and unknown reflection' do
|
30
|
+
expect do
|
31
|
+
Rapns.reflections.__dispatch(:unknown)
|
32
|
+
end.to raise_error(Rapns::Reflections::NoSuchReflectionError)
|
33
|
+
end
|
34
|
+
end
|
data/spec/unit_spec_helper.rb
CHANGED
@@ -81,65 +81,7 @@ end
|
|
81
81
|
# the certificate, and this is private to Apple. So if the app
|
82
82
|
# has a certificate and a private key in it, the only way to find
|
83
83
|
# out if it really is valid is to connect to Apple's servers.
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
localKeyID: 00 93 8F E4 A3 C3 75 64 3D 7E EA 14 0B 0A EA DD 15 85 8A D5
|
89
|
-
subject=/CN=test certificate/O=Example/OU=Example/ST=QLD/C=AU/L=Example/emailAddress=user@example.com
|
90
|
-
issuer=/CN=test certificate/O=Example/OU=Example/ST=QLD/C=AU/L=Example/emailAddress=user@example.com
|
91
|
-
-----BEGIN CERTIFICATE-----
|
92
|
-
MIID5jCCAs6gAwIBAgIBATALBgkqhkiG9w0BAQswgY0xGTAXBgNVBAMMEHRlc3Qg
|
93
|
-
Y2VydGlmaWNhdGUxEDAOBgNVBAoMB0V4YW1wbGUxEDAOBgNVBAsMB0V4YW1wbGUx
|
94
|
-
DDAKBgNVBAgMA1FMRDELMAkGA1UEBhMCQVUxEDAOBgNVBAcMB0V4YW1wbGUxHzAd
|
95
|
-
BgkqhkiG9w0BCQEWEHVzZXJAZXhhbXBsZS5jb20wHhcNMTIwOTA5MDMxODMyWhcN
|
96
|
-
MjIwOTA3MDMxODMyWjCBjTEZMBcGA1UEAwwQdGVzdCBjZXJ0aWZpY2F0ZTEQMA4G
|
97
|
-
A1UECgwHRXhhbXBsZTEQMA4GA1UECwwHRXhhbXBsZTEMMAoGA1UECAwDUUxEMQsw
|
98
|
-
CQYDVQQGEwJBVTEQMA4GA1UEBwwHRXhhbXBsZTEfMB0GCSqGSIb3DQEJARYQdXNl
|
99
|
-
ckBleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKF+
|
100
|
-
UDsN1sLen8g+97PNTiWju9+wkSv+H5rQlvb6YFLPx11YvqpK8ms6kFU1OmWeLfmh
|
101
|
-
cpsT+bZtKupC7aGPoSG3RXzzf/YUMgs/ZSXA0idZHA6tkReAEzIX6jL5otfPWbaP
|
102
|
-
luCTUoVMeP4u9ywk628zlqh9IQHC1Agl0R1xGCpULDk8kn1gPyEisl38wI5aDbzy
|
103
|
-
6lYQGNUKOqt1xfVjtIFe/jyY/v0sxFjIJlRLcAFBuJx4sRV+PwRBkusOQtYwcwpI
|
104
|
-
loMxJj+GQe66ueATW81aC4iOU66DAFFEuGzwIwm3bOilimGGQbGb92F339RfmSOo
|
105
|
-
TPAvVhsakI3mzESb4lkCAwEAAaNRME8wDgYDVR0PAQH/BAQDAgeAMCAGA1UdJQEB
|
106
|
-
/wQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAbBgNVHREEFDASgRB1c2VyQGV4YW1w
|
107
|
-
bGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQA5UbNR+83ZdI2DiaB4dRmy0V5RDAqJ
|
108
|
-
k9+QskcTV4gBTjsOBS46Dw1tI6iTrfTyjYJdnyH0Y2Y2YVWBnvtON41UCZak+4ed
|
109
|
-
/IqyzU0dtfZ+frWa0RY4reyl80TwqnzyJfni0nDo4zGGvz70cxyaz2u1BWqwLjqb
|
110
|
-
dh8Dxvt+aHW2MQi0iGKh/HNbgwVanR4+ubNwziK9sR1Rnq9MkHWtwBw16SXQG6ao
|
111
|
-
SZKASWNaH8VL08Zz0E98cwd137UJkPsldCwJ8kHR5OzkcjPdXvnGD3d64yy2TC1Z
|
112
|
-
Gy1Aazt98wPcTYBytlhK8Rvzg9OoY9QmsdpmWxz1ZCXECJNqCa3IKsqO
|
113
|
-
-----END CERTIFICATE-----
|
114
|
-
Bag Attributes
|
115
|
-
friendlyName: test certificate
|
116
|
-
localKeyID: 00 93 8F E4 A3 C3 75 64 3D 7E EA 14 0B 0A EA DD 15 85 8A D5
|
117
|
-
Key Attributes: <No Attributes>
|
118
|
-
-----BEGIN RSA PRIVATE KEY-----
|
119
|
-
MIIEpQIBAAKCAQEAoX5QOw3Wwt6fyD73s81OJaO737CRK/4fmtCW9vpgUs/HXVi+
|
120
|
-
qkryazqQVTU6ZZ4t+aFymxP5tm0q6kLtoY+hIbdFfPN/9hQyCz9lJcDSJ1kcDq2R
|
121
|
-
F4ATMhfqMvmi189Zto+W4JNShUx4/i73LCTrbzOWqH0hAcLUCCXRHXEYKlQsOTyS
|
122
|
-
fWA/ISKyXfzAjloNvPLqVhAY1Qo6q3XF9WO0gV7+PJj+/SzEWMgmVEtwAUG4nHix
|
123
|
-
FX4/BEGS6w5C1jBzCkiWgzEmP4ZB7rq54BNbzVoLiI5TroMAUUS4bPAjCbds6KWK
|
124
|
-
YYZBsZv3YXff1F+ZI6hM8C9WGxqQjebMRJviWQIDAQABAoIBAQCTiLIDQUFSBdAz
|
125
|
-
QFNLD+S0vkCEuunlJuP4q1c/ir006l1YChsluBJ/o6D4NwiCjV+zDquEwVsALftm
|
126
|
-
yH4PewfZpXT2Ef508T5GyEO/mchj6iSXxDkpHvhqay6qIyWBwwxSnBtaTzy0Soi+
|
127
|
-
rmlhCtmLXbXld2sQEM1kJChGnWtWPtvSyrn+mapNPZviGRtgRNK+YsrAti1nUext
|
128
|
-
2syO5mTdHf1D8GR7I98OaX6odREuSocEV9PzfapWZx2GK5tvRiS1skiug5ciieTd
|
129
|
-
Am5/C+bb31h4drFslihLb5BRGO5SFQJvMJL2Sx1f19BCC4XikS01P4/zZbxQNq79
|
130
|
-
kxEQuDGBAoGBANP4pIYZ5xshCkx7cTYqmxzWLClGKE2S7Oa8N89mtOwfmqT9AFun
|
131
|
-
t9Us9Ukbi8BaKlKhGpQ1HlLf/KVcpyW0x2qLou6AyIWYH+/5VaR3graNgUnzpK9f
|
132
|
-
1F5HoaNHbhlAoebqhzhASFlJI2aqUdQjdOv73z+s9szJU4gpILNwGDFnAoGBAMMJ
|
133
|
-
j+vIxtG9J2jldyoXzpg5mbMXSj9u/wFLBVdjXWyOoiqVMMBto53RnoqAom7Ifr9D
|
134
|
-
49LxRAT1Q3l4vs/YnM3ziMsIg2vQK1EbrLsY9OnD/kvPaLXOlNIOdfLM8UeVWZMc
|
135
|
-
I4LPbbZrhv/7CC8RjbRhMoWWdGYPvxmvD6V4ZDY/AoGBALoI6OxA45Htx4okdNHj
|
136
|
-
RstiNNPsnQaoQn6nBhxiubraafEPkzbd1fukP4pwQJELEUX/2sHkdL6rkqLW1GPF
|
137
|
-
a5dZAiBsqpCFWNJWdBGqSfBJ9QSgbxLz+gDcwUH6OOi0zuNJRm/aCyVBiW5bYQHc
|
138
|
-
NIvAPMk31ksZDtTbs7WIVdNVAoGBALZ1+KWNxKqs+fSBT5UahpUUtfy8miJz9a7A
|
139
|
-
/3M8q0cGvSF3Rw+OwpW/aEGMi+l2OlU27ykFuyukRAac9m296RwnbF79TO2M5ylO
|
140
|
-
6a5zb5ROXlWP6RbE96b4DlIidssQJqegmHwlEC+rsrVBpOtb0aThlYEyOxzMOGyP
|
141
|
-
wOR9l8rDAoGADZ4TUHFM6VrvPlUZBkGbqiyXH9IM/y9JWk+22JQCEGnM6RFZemSs
|
142
|
-
jxWqQiPAdJtb3xKryJSCMtFPH9azedoCrSgaMflJ1QgoXgpiKZyoEXWraVUggh/0
|
143
|
-
CEavgZcTZ6SvMuayqJdGGB+zb1V8XwXMtCjApR/kTm47DjxO4DmpOPs=
|
144
|
-
-----END RSA PRIVATE KEY-----
|
145
|
-
EOF
|
84
|
+
|
85
|
+
path = File.join(File.dirname(__FILE__), 'support')
|
86
|
+
TEST_CERT = File.read(File.join(path, 'cert_without_password.pem'))
|
87
|
+
TEST_CERT_WITH_PASSWORD = File.read(File.join(path, 'cert_with_password.pem'))
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rapns
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0
|
4
|
+
version: 3.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: multi_json
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '0'
|
46
|
-
description: Professional grade APNs and GCM
|
46
|
+
description: Professional grade APNs and GCM for Ruby
|
47
47
|
email:
|
48
48
|
- port001@gmail.com
|
49
49
|
executables:
|
@@ -92,23 +92,30 @@ files:
|
|
92
92
|
- lib/rapns/daemon/gcm/delivery_handler.rb
|
93
93
|
- lib/rapns/daemon/interruptible_sleep.rb
|
94
94
|
- lib/rapns/daemon/logger.rb
|
95
|
+
- lib/rapns/daemon/reflectable.rb
|
95
96
|
- lib/rapns/deprecatable.rb
|
96
97
|
- lib/rapns/deprecation.rb
|
98
|
+
- lib/rapns/embed.rb
|
97
99
|
- lib/rapns/gcm/app.rb
|
98
100
|
- lib/rapns/gcm/expiry_collapse_key_mutual_inclusion_validator.rb
|
99
101
|
- lib/rapns/gcm/notification.rb
|
100
|
-
- lib/rapns/gcm/
|
102
|
+
- lib/rapns/gcm/payload_data_size_validator.rb
|
103
|
+
- lib/rapns/gcm/registration_ids_count_validator.rb
|
101
104
|
- lib/rapns/multi_json_helper.rb
|
102
105
|
- lib/rapns/notification.rb
|
103
106
|
- lib/rapns/patches.rb
|
104
107
|
- lib/rapns/patches/rails/3.1.0/postgresql_adapter.rb
|
105
108
|
- lib/rapns/patches/rails/3.1.1/postgresql_adapter.rb
|
109
|
+
- lib/rapns/push.rb
|
110
|
+
- lib/rapns/reflection.rb
|
106
111
|
- lib/rapns/version.rb
|
107
112
|
- lib/tasks/cane.rake
|
108
113
|
- lib/tasks/test.rake
|
109
114
|
- config/database.yml
|
110
115
|
- spec/acceptance/gcm_upgrade_spec.rb
|
111
116
|
- spec/acceptance_spec_helper.rb
|
117
|
+
- spec/support/cert_with_password.pem
|
118
|
+
- spec/support/cert_without_password.pem
|
112
119
|
- spec/support/simplecov_helper.rb
|
113
120
|
- spec/support/simplecov_quality_formatter.rb
|
114
121
|
- spec/unit/apns/app_spec.rb
|
@@ -134,13 +141,17 @@ files:
|
|
134
141
|
- spec/unit/daemon/gcm/delivery_spec.rb
|
135
142
|
- spec/unit/daemon/interruptible_sleep_spec.rb
|
136
143
|
- spec/unit/daemon/logger_spec.rb
|
144
|
+
- spec/unit/daemon/reflectable_spec.rb
|
137
145
|
- spec/unit/daemon_spec.rb
|
138
146
|
- spec/unit/deprecatable_spec.rb
|
139
147
|
- spec/unit/deprecation_spec.rb
|
148
|
+
- spec/unit/embed_spec.rb
|
140
149
|
- spec/unit/gcm/app_spec.rb
|
141
150
|
- spec/unit/gcm/notification_spec.rb
|
142
151
|
- spec/unit/notification_shared.rb
|
143
152
|
- spec/unit/notification_spec.rb
|
153
|
+
- spec/unit/push_spec.rb
|
154
|
+
- spec/unit/reflection_spec.rb
|
144
155
|
- spec/unit_spec_helper.rb
|
145
156
|
- bin/rapns
|
146
157
|
homepage: https://github.com/ileitch/rapns
|
@@ -166,11 +177,13 @@ rubyforge_project:
|
|
166
177
|
rubygems_version: 1.8.23
|
167
178
|
signing_key:
|
168
179
|
specification_version: 3
|
169
|
-
summary: Professional grade APNs and GCM
|
180
|
+
summary: Professional grade APNs and GCM for Ruby
|
170
181
|
test_files:
|
171
182
|
- config/database.yml
|
172
183
|
- spec/acceptance/gcm_upgrade_spec.rb
|
173
184
|
- spec/acceptance_spec_helper.rb
|
185
|
+
- spec/support/cert_with_password.pem
|
186
|
+
- spec/support/cert_without_password.pem
|
174
187
|
- spec/support/simplecov_helper.rb
|
175
188
|
- spec/support/simplecov_quality_formatter.rb
|
176
189
|
- spec/unit/apns/app_spec.rb
|
@@ -196,11 +209,15 @@ test_files:
|
|
196
209
|
- spec/unit/daemon/gcm/delivery_spec.rb
|
197
210
|
- spec/unit/daemon/interruptible_sleep_spec.rb
|
198
211
|
- spec/unit/daemon/logger_spec.rb
|
212
|
+
- spec/unit/daemon/reflectable_spec.rb
|
199
213
|
- spec/unit/daemon_spec.rb
|
200
214
|
- spec/unit/deprecatable_spec.rb
|
201
215
|
- spec/unit/deprecation_spec.rb
|
216
|
+
- spec/unit/embed_spec.rb
|
202
217
|
- spec/unit/gcm/app_spec.rb
|
203
218
|
- spec/unit/gcm/notification_spec.rb
|
204
219
|
- spec/unit/notification_shared.rb
|
205
220
|
- spec/unit/notification_spec.rb
|
221
|
+
- spec/unit/push_spec.rb
|
222
|
+
- spec/unit/reflection_spec.rb
|
206
223
|
- spec/unit_spec_helper.rb
|
@@ -1,13 +0,0 @@
|
|
1
|
-
module Rapns
|
2
|
-
module Gcm
|
3
|
-
class PayloadSizeValidator < ActiveModel::Validator
|
4
|
-
LIMIT = 4096
|
5
|
-
|
6
|
-
def validate(record)
|
7
|
-
if record.payload_size > LIMIT
|
8
|
-
record.errors[:base] << "GCM notification payload cannot be larger than #{LIMIT} bytes."
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|