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.
Files changed (46) hide show
  1. data/CHANGELOG.md +10 -2
  2. data/README.md +26 -3
  3. data/bin/rapns +2 -7
  4. data/lib/generators/templates/add_gcm.rb +3 -1
  5. data/lib/generators/templates/rapns.rb +42 -11
  6. data/lib/rapns/apns/notification.rb +8 -2
  7. data/lib/rapns/app.rb +3 -3
  8. data/lib/rapns/configuration.rb +46 -13
  9. data/lib/rapns/daemon/apns/connection.rb +12 -9
  10. data/lib/rapns/daemon/apns/delivery_handler.rb +1 -1
  11. data/lib/rapns/daemon/apns/feedback_receiver.rb +6 -2
  12. data/lib/rapns/daemon/app_runner.rb +23 -7
  13. data/lib/rapns/daemon/delivery.rb +5 -1
  14. data/lib/rapns/daemon/delivery_handler.rb +4 -0
  15. data/lib/rapns/daemon/feeder.rb +26 -5
  16. data/lib/rapns/daemon/reflectable.rb +13 -0
  17. data/lib/rapns/daemon.rb +33 -22
  18. data/lib/rapns/embed.rb +28 -0
  19. data/lib/rapns/gcm/notification.rb +7 -2
  20. data/lib/rapns/gcm/payload_data_size_validator.rb +13 -0
  21. data/lib/rapns/gcm/registration_ids_count_validator.rb +13 -0
  22. data/lib/rapns/push.rb +12 -0
  23. data/lib/rapns/reflection.rb +44 -0
  24. data/lib/rapns/version.rb +1 -1
  25. data/lib/rapns.rb +11 -1
  26. data/spec/support/cert_with_password.pem +90 -0
  27. data/spec/support/cert_without_password.pem +59 -0
  28. data/spec/unit/apns/app_spec.rb +15 -1
  29. data/spec/unit/apns/notification_spec.rb +16 -1
  30. data/spec/unit/configuration_spec.rb +10 -1
  31. data/spec/unit/daemon/apns/connection_spec.rb +11 -2
  32. data/spec/unit/daemon/apns/delivery_handler_spec.rb +1 -1
  33. data/spec/unit/daemon/apns/delivery_spec.rb +10 -0
  34. data/spec/unit/daemon/apns/feedback_receiver_spec.rb +16 -7
  35. data/spec/unit/daemon/delivery_handler_shared.rb +8 -0
  36. data/spec/unit/daemon/feeder_spec.rb +37 -6
  37. data/spec/unit/daemon/gcm/delivery_spec.rb +33 -1
  38. data/spec/unit/daemon/reflectable_spec.rb +27 -0
  39. data/spec/unit/daemon_spec.rb +55 -9
  40. data/spec/unit/embed_spec.rb +44 -0
  41. data/spec/unit/gcm/notification_spec.rb +9 -3
  42. data/spec/unit/push_spec.rb +28 -0
  43. data/spec/unit/reflection_spec.rb +34 -0
  44. data/spec/unit_spec_helper.rb +4 -62
  45. metadata +22 -5
  46. 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::Daemon.stub(:logger => logger, :config => config)
11
- Rapns::Daemon::Feeder.instance_variable_set("@stop", true)
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(0)
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 "enqueue the notification" do
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(2)
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
- Rapns::Daemon::Gcm::Delivery.perform(app, http, notification)
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
@@ -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, :push_poll => 2, :airbrake_notify => false, :foreground => true) }
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).with(2)
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.setup_signal_hooks
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.setup_signal_hooks
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.send(:shutdown)
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.send(:shutdown)
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.send(:shutdown)
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.send(:shutdown)
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.send(:shutdown)
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 'has a payload limit of 4096 bytes' do
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
@@ -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
- TEST_CERT = <<EOF
86
- Bag Attributes
87
- friendlyName: test certificate
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.1
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: 2012-12-16 00:00:00.000000000 Z
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 daemon
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/payload_size_validator.rb
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 daemon
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