rapns 2.0.5 → 3.0.0.beta.1

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 (82) hide show
  1. data/lib/generators/rapns_generator.rb +1 -0
  2. data/lib/generators/templates/add_gcm.rb +86 -0
  3. data/lib/generators/templates/create_rapns_notifications.rb +1 -1
  4. data/lib/rapns/apns/app.rb +8 -0
  5. data/lib/rapns/apns/binary_notification_validator.rb +12 -0
  6. data/lib/rapns/apns/device_token_format_validator.rb +12 -0
  7. data/lib/rapns/apns/feedback.rb +14 -0
  8. data/lib/rapns/apns/notification.rb +84 -0
  9. data/lib/rapns/app.rb +5 -6
  10. data/lib/rapns/{config.rb → configuration.rb} +5 -5
  11. data/lib/rapns/daemon/apns/app_runner.rb +36 -0
  12. data/lib/rapns/daemon/apns/connection.rb +113 -0
  13. data/lib/rapns/daemon/apns/delivery.rb +63 -0
  14. data/lib/rapns/daemon/apns/delivery_handler.rb +21 -0
  15. data/lib/rapns/daemon/apns/disconnection_error.rb +20 -0
  16. data/lib/rapns/daemon/apns/feedback_receiver.rb +74 -0
  17. data/lib/rapns/daemon/app_runner.rb +76 -77
  18. data/lib/rapns/daemon/database_reconnectable.rb +3 -3
  19. data/lib/rapns/daemon/delivery.rb +43 -0
  20. data/lib/rapns/daemon/delivery_error.rb +6 -2
  21. data/lib/rapns/daemon/delivery_handler.rb +13 -79
  22. data/lib/rapns/daemon/delivery_queue_18.rb +2 -2
  23. data/lib/rapns/daemon/delivery_queue_19.rb +3 -3
  24. data/lib/rapns/daemon/feeder.rb +5 -5
  25. data/lib/rapns/daemon/gcm/app_runner.rb +13 -0
  26. data/lib/rapns/daemon/gcm/delivery.rb +206 -0
  27. data/lib/rapns/daemon/gcm/delivery_handler.rb +20 -0
  28. data/lib/rapns/daemon.rb +31 -20
  29. data/lib/rapns/gcm/app.rb +7 -0
  30. data/lib/rapns/gcm/expiry_collapse_key_mutual_inclusion_validator.rb +11 -0
  31. data/lib/rapns/gcm/notification.rb +31 -0
  32. data/lib/rapns/gcm/payload_size_validator.rb +13 -0
  33. data/lib/rapns/multi_json_helper.rb +16 -0
  34. data/lib/rapns/notification.rb +28 -95
  35. data/lib/rapns/version.rb +1 -1
  36. data/lib/rapns.rb +14 -4
  37. data/lib/tasks/cane.rake +19 -0
  38. data/lib/tasks/test.rake +34 -0
  39. data/spec/acceptance/gcm_upgrade_spec.rb +34 -0
  40. data/spec/acceptance_spec_helper.rb +85 -0
  41. data/spec/support/simplecov_helper.rb +13 -0
  42. data/spec/support/simplecov_quality_formatter.rb +8 -0
  43. data/spec/unit/apns/app_spec.rb +15 -0
  44. data/spec/unit/apns/feedback_spec.rb +12 -0
  45. data/spec/{rapns → unit/apns}/notification_spec.rb +44 -72
  46. data/spec/unit/app_spec.rb +18 -0
  47. data/spec/unit/daemon/apns/app_runner_spec.rb +37 -0
  48. data/spec/{rapns/daemon → unit/daemon/apns}/connection_spec.rb +9 -9
  49. data/spec/unit/daemon/apns/delivery_handler_spec.rb +48 -0
  50. data/spec/unit/daemon/apns/delivery_spec.rb +154 -0
  51. data/spec/{rapns/daemon → unit/daemon/apns}/feedback_receiver_spec.rb +14 -14
  52. data/spec/unit/daemon/app_runner_shared.rb +66 -0
  53. data/spec/unit/daemon/app_runner_spec.rb +78 -0
  54. data/spec/{rapns → unit}/daemon/database_reconnectable_spec.rb +4 -5
  55. data/spec/{rapns → unit}/daemon/delivery_error_spec.rb +2 -2
  56. data/spec/unit/daemon/delivery_handler_shared.rb +19 -0
  57. data/spec/{rapns → unit}/daemon/delivery_queue_spec.rb +1 -1
  58. data/spec/{rapns → unit}/daemon/feeder_spec.rb +33 -33
  59. data/spec/unit/daemon/gcm/app_runner_spec.rb +15 -0
  60. data/spec/unit/daemon/gcm/delivery_handler_spec.rb +36 -0
  61. data/spec/unit/daemon/gcm/delivery_spec.rb +236 -0
  62. data/spec/{rapns → unit}/daemon/interruptible_sleep_spec.rb +1 -1
  63. data/spec/{rapns → unit}/daemon/logger_spec.rb +1 -1
  64. data/spec/{rapns → unit}/daemon_spec.rb +1 -1
  65. data/spec/unit/gcm/app_spec.rb +5 -0
  66. data/spec/unit/gcm/notification_spec.rb +55 -0
  67. data/spec/unit/notification_shared.rb +38 -0
  68. data/spec/unit/notification_spec.rb +6 -0
  69. data/spec/{rapns/app_spec.rb → unit_spec_helper.rb} +76 -16
  70. metadata +107 -45
  71. data/lib/rapns/binary_notification_validator.rb +0 -10
  72. data/lib/rapns/daemon/connection.rb +0 -114
  73. data/lib/rapns/daemon/delivery_handler_pool.rb +0 -18
  74. data/lib/rapns/daemon/disconnection_error.rb +0 -14
  75. data/lib/rapns/daemon/feedback_receiver.rb +0 -82
  76. data/lib/rapns/device_token_format_validator.rb +0 -10
  77. data/lib/rapns/feedback.rb +0 -12
  78. data/spec/rapns/daemon/app_runner_spec.rb +0 -193
  79. data/spec/rapns/daemon/delivery_handler_pool_spec.rb +0 -17
  80. data/spec/rapns/daemon/delivery_handler_spec.rb +0 -206
  81. data/spec/rapns/feedback_spec.rb +0 -12
  82. data/spec/spec_helper.rb +0 -78
@@ -0,0 +1,85 @@
1
+ require 'unit_spec_helper'
2
+ require 'fileutils'
3
+
4
+ ENV['RAILS_ENV'] = 'test'
5
+ require 'bundler'
6
+ Bundler.require(:default)
7
+
8
+ TMP_DIR = '/tmp'
9
+ RAILS_DIR = File.join(TMP_DIR, 'rapns_test')
10
+ if ENV['TRAVIS']
11
+ TRAVIS_BRANCH = 'gcm'
12
+ RAPNS_ROOT = 'git://github.com/ileitch/rapns.git'
13
+ else
14
+ RAPNS_ROOT = File.expand_path(__FILE__ + '/../../')
15
+ end
16
+
17
+ def setup_rails
18
+ return if $rails_is_setup
19
+ `rm -rf #{RAILS_DIR}`
20
+ FileUtils.mkdir_p(RAILS_DIR)
21
+ cmd("bundle exec rails new #{RAILS_DIR} --skip-bundle")
22
+ branch = `git branch | grep '\*'`.split(' ').last
23
+ in_test_rails do
24
+ cmd('echo "gem \'rake\'" >> Gemfile')
25
+ if ENV['TRAVIS']
26
+ cmd("echo \"gem 'rapns', :git => '#{RAPNS_ROOT}', :branch => '#{TRAVIS_BRANCH}'\" >> Gemfile")
27
+ else
28
+ cmd("echo \"gem 'rapns', :git => '#{RAPNS_ROOT}', :branch => '#{branch}'\" >> Gemfile")
29
+ end
30
+
31
+ cmd("bundle install")
32
+ end
33
+ end
34
+
35
+ def as_test_rails_db(env='development')
36
+ orig_config = ActiveRecord::Base.connection_config
37
+ begin
38
+ in_test_rails do
39
+ config = YAML.load_file('config/database.yml')
40
+ ActiveRecord::Base.establish_connection(config[env])
41
+ yield
42
+ end
43
+ ensure
44
+ ActiveRecord::Base.establish_connection(orig_config)
45
+ end
46
+ end
47
+
48
+ def cmd(str, echo = true)
49
+ puts "* #{str.strip}" if echo
50
+ retval = Bundler.with_clean_env { `#{str}` }
51
+ puts retval.strip if echo
52
+ retval
53
+ end
54
+
55
+ def generate
56
+ in_test_rails { cmd('bundle exec rails g rapns') }
57
+ end
58
+
59
+ def migrate(*migrations)
60
+ in_test_rails do
61
+ if migrations.present?
62
+ migrations.each do |name|
63
+ migration = Dir.entries('db/migrate').find { |entry| entry =~ /#{name}/ }
64
+ version = migration.split('_').first
65
+ cmd("bundle exec rake db:migrate VERSION=#{version} RAILS_ENV=development")
66
+ end
67
+ else
68
+ cmd('bundle exec rake db:migrate RAILS_ENV=development')
69
+ end
70
+ end
71
+ end
72
+
73
+ def in_test_rails
74
+ pwd = Dir.pwd
75
+ begin
76
+ Dir.chdir(RAILS_DIR)
77
+ yield
78
+ ensure
79
+ Dir.chdir(pwd)
80
+ end
81
+ end
82
+
83
+ def runner(str)
84
+ in_test_rails { cmd("rails runner -e test '#{str}'").strip }
85
+ end
@@ -0,0 +1,13 @@
1
+ require 'simplecov'
2
+ require './spec/support/simplecov_quality_formatter'
3
+
4
+ module SimpleCovHelper
5
+ def start_simple_cov(name)
6
+ SimpleCov.start do
7
+ add_filter '/spec/'
8
+ add_filter '/lib/generators'
9
+ command_name name
10
+ formatter SimpleCov::Formatter::QualityFormatter
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,8 @@
1
+ class SimpleCov::Formatter::QualityFormatter
2
+ def format(result)
3
+ SimpleCov::Formatter::HTMLFormatter.new.format(result)
4
+ File.open("coverage/covered_percent", "w") do |f|
5
+ f.puts result.source_files.covered_percent.to_f
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,15 @@
1
+ require 'unit_spec_helper'
2
+
3
+ describe Rapns::App do
4
+ it 'does not validate an app with an invalid certificate' do
5
+ app = Rapns::Apns::App.new(:key => 'test', :environment => 'development', :certificate => 'foo')
6
+ app.valid?
7
+ app.errors[:certificate].should == ['Certificate value must contain a certificate and a private key.']
8
+ end
9
+
10
+ it 'validates a real certificate' do
11
+ app = Rapns::Apns::App.new :key => 'test', :environment => 'development', :certificate => TEST_CERT
12
+ app.valid?
13
+ app.errors[:certificate].should == []
14
+ end
15
+ end
@@ -0,0 +1,12 @@
1
+ require "unit_spec_helper"
2
+
3
+ describe Rapns::Apns::Feedback do
4
+ it { should validate_presence_of(:device_token) }
5
+ it { should validate_presence_of(:failed_at) }
6
+
7
+ it "should validate the format of the device_token" do
8
+ notification = Rapns::Apns::Feedback.new(:device_token => "{$%^&*()}")
9
+ notification.valid?.should be_false
10
+ notification.errors[:device_token].include?("is invalid").should be_true
11
+ end
12
+ end
@@ -1,19 +1,24 @@
1
- require "spec_helper"
1
+ require "unit_spec_helper"
2
+ require 'unit/notification_shared.rb'
3
+
4
+ describe Rapns::Apns::Notification do
5
+ it_should_behave_like 'an Notification subclass'
2
6
 
3
- describe Rapns::Notification do
4
- it { should validate_presence_of(:app) }
5
7
  it { should validate_presence_of(:device_token) }
6
8
  it { should validate_numericality_of(:badge) }
7
- it { should validate_numericality_of(:expiry) }
9
+
10
+ let(:notification_class) { Rapns::Apns::Notification }
11
+ let(:notification) { notification_class.new }
12
+ let(:data_setter) { 'attributes_for_device=' }
13
+ let(:data_getter) { 'attributes_for_device' }
8
14
 
9
15
  it "should validate the format of the device_token" do
10
- notification = Rapns::Notification.new(:device_token => "{$%^&*()}")
16
+ notification = Rapns::Apns::Notification.new(:device_token => "{$%^&*()}")
11
17
  notification.valid?.should be_false
12
18
  notification.errors[:device_token].include?("is invalid").should be_true
13
19
  end
14
20
 
15
21
  it "should validate the length of the binary conversion of the notification" do
16
- notification = Rapns::Notification.new
17
22
  notification.device_token = "a" * 64
18
23
  notification.alert = "way too long!" * 100
19
24
  notification.valid?.should be_false
@@ -21,90 +26,73 @@ describe Rapns::Notification do
21
26
  end
22
27
 
23
28
  it "should default the sound to 1.aiff" do
24
- Rapns::Notification.new.sound.should == "1.aiff"
29
+ notification.sound.should == "1.aiff"
25
30
  end
26
31
 
27
32
  it "should default the expiry to 1 day" do
28
- Rapns::Notification.new.expiry.should == 1.day.to_i
33
+ notification.expiry.should == 1.day.to_i
29
34
  end
30
35
  end
31
36
 
32
- describe Rapns::Notification, "when assigning the device token" do
37
+ describe Rapns::Apns::Notification, "when assigning the device token" do
33
38
  it "should strip spaces from the given string" do
34
- notification = Rapns::Notification.new(:device_token => "o m g")
39
+ notification = Rapns::Apns::Notification.new(:device_token => "o m g")
35
40
  notification.device_token.should == "omg"
36
41
  end
37
42
 
38
43
  it "should strip chevrons from the given string" do
39
- notification = Rapns::Notification.new(:device_token => "<omg>")
44
+ notification = Rapns::Apns::Notification.new(:device_token => "<omg>")
40
45
  notification.device_token.should == "omg"
41
46
  end
42
47
  end
43
48
 
44
- describe Rapns::Notification, "when assigning the attributes for the device" do
45
- it "should raise an ArgumentError if something other than a Hash is assigned" do
46
- expect { Rapns::Notification.new(:attributes_for_device => Array.new) }.to \
47
- raise_error(ArgumentError, "attributes_for_device must be a Hash")
48
- end
49
-
50
- it "should encode the given Hash as JSON" do
51
- notification = Rapns::Notification.new(:attributes_for_device => {:hi => "mom"})
52
- notification.read_attribute(:attributes_for_device).should == "{\"hi\":\"mom\"}"
53
- end
54
-
55
- it "should decode the JSON when using the reader method" do
56
- notification = Rapns::Notification.new(:attributes_for_device => {:hi => "mom"})
57
- notification.attributes_for_device.should == {"hi" => "mom"}
58
- end
59
- end
60
-
61
- describe Rapns::Notification, "as_json" do
49
+ describe Rapns::Apns::Notification, "as_json" do
62
50
  it "should include the alert if present" do
63
- notification = Rapns::Notification.new(:alert => "hi mom")
51
+ notification = Rapns::Apns::Notification.new(:alert => "hi mom")
64
52
  notification.as_json["aps"]["alert"].should == "hi mom"
65
53
  end
66
54
 
67
55
  it "should not include the alert key if the alert is not present" do
68
- notification = Rapns::Notification.new(:alert => nil)
56
+ notification = Rapns::Apns::Notification.new(:alert => nil)
69
57
  notification.as_json["aps"].key?("alert").should be_false
70
58
  end
71
59
 
72
60
  it "should encode the alert as JSON if it is a Hash" do
73
- notification = Rapns::Notification.new(:alert => { 'body' => "hi mom", 'alert-loc-key' => "View" })
61
+ notification = Rapns::Apns::Notification.new(:alert => { 'body' => "hi mom", 'alert-loc-key' => "View" })
74
62
  notification.as_json["aps"]["alert"].should == { 'body' => "hi mom", 'alert-loc-key' => "View" }
75
63
  end
76
64
 
77
65
  it "should include the badge if present" do
78
- notification = Rapns::Notification.new(:badge => 6)
66
+ notification = Rapns::Apns::Notification.new(:badge => 6)
79
67
  notification.as_json["aps"]["badge"].should == 6
80
68
  end
81
69
 
82
70
  it "should not include the badge key if the badge is not present" do
83
- notification = Rapns::Notification.new(:badge => nil)
71
+ notification = Rapns::Apns::Notification.new(:badge => nil)
84
72
  notification.as_json["aps"].key?("badge").should be_false
85
73
  end
86
74
 
87
75
  it "should include the sound if present" do
88
- notification = Rapns::Notification.new(:alert => "my_sound.aiff")
76
+ notification = Rapns::Apns::Notification.new(:alert => "my_sound.aiff")
89
77
  notification.as_json["aps"]["alert"].should == "my_sound.aiff"
90
78
  end
91
79
 
92
80
  it "should not include the sound key if the sound is not present" do
93
- notification = Rapns::Notification.new(:sound => false)
81
+ notification = Rapns::Apns::Notification.new(:sound => false)
94
82
  notification.as_json["aps"].key?("sound").should be_false
95
83
  end
96
84
 
97
- it "should include attrbutes for the device" do
98
- notification = Rapns::Notification.new
85
+ it "should include attributes for the device" do
86
+ notification = Rapns::Apns::Notification.new
99
87
  notification.attributes_for_device = {:omg => :lol, :wtf => :dunno}
100
88
  notification.as_json["omg"].should == "lol"
101
89
  notification.as_json["wtf"].should == "dunno"
102
90
  end
103
91
  end
104
92
 
105
- describe Rapns::Notification, 'MDM' do
93
+ describe Rapns::Apns::Notification, 'MDM' do
106
94
  let(:magic) { 'abc123' }
107
- let(:notification) { Rapns::Notification.new }
95
+ let(:notification) { Rapns::Apns::Notification.new }
108
96
 
109
97
  it 'includes the mdm magic in the payload' do
110
98
  notification.mdm = magic
@@ -118,8 +106,8 @@ describe Rapns::Notification, 'MDM' do
118
106
  end
119
107
  end
120
108
 
121
- describe Rapns::Notification, 'content-available' do
122
- let(:notification) { Rapns::Notification.new }
109
+ describe Rapns::Apns::Notification, 'content-available' do
110
+ let(:notification) { Rapns::Apns::Notification.new }
123
111
 
124
112
  it 'includes content-available in the payload' do
125
113
  notification.content_available = true
@@ -136,43 +124,43 @@ describe Rapns::Notification, 'content-available' do
136
124
  end
137
125
  end
138
126
 
139
- describe Rapns::Notification, "to_binary" do
127
+ describe Rapns::Apns::Notification, "to_binary" do
140
128
  it "should correctly convert the notification to binary" do
141
- notification = Rapns::Notification.new
129
+ notification = Rapns::Apns::Notification.new
142
130
  notification.device_token = "a" * 64
143
131
  notification.sound = "1.aiff"
144
132
  notification.badge = 3
145
133
  notification.alert = "Don't panic Mr Mainwaring, don't panic!"
146
134
  notification.attributes_for_device = {:hi => :mom}
147
135
  notification.expiry = 86400 # 1 day, \x00\x01Q\x80
148
- notification.app = 'my_app'
136
+ notification.app = Rapns::Apns::App.create!(:name => 'my_app', :environment => 'development', :certificate => TEST_CERT)
149
137
  notification.save!
150
138
  notification.stub(:id).and_return(1234)
151
139
  notification.to_binary.should == "\x01\x00\x00\x04\xD2\x00\x01Q\x80\x00 \xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\x00a{\"aps\":{\"alert\":\"Don't panic Mr Mainwaring, don't panic!\",\"badge\":3,\"sound\":\"1.aiff\"},\"hi\":\"mom\"}"
152
140
  end
153
141
  end
154
142
 
155
- describe Rapns::Notification, "bug #31" do
143
+ describe Rapns::Apns::Notification, "bug #31" do
156
144
  it 'does not confuse a JSON looking string as JSON' do
157
- notification = Rapns::Notification.new
145
+ notification = Rapns::Apns::Notification.new
158
146
  notification.alert = "{\"one\":2}"
159
147
  notification.alert.should == "{\"one\":2}"
160
148
  end
161
149
 
162
150
  it 'does confuse a JSON looking string as JSON if the alert_is_json attribute is not present' do
163
- notification = Rapns::Notification.new
151
+ notification = Rapns::Apns::Notification.new
164
152
  notification.stub(:has_attribute? => false)
165
153
  notification.alert = "{\"one\":2}"
166
154
  notification.alert.should == {"one" => 2}
167
155
  end
168
156
  end
169
157
 
170
- describe Rapns::Notification, "bug #35" do
158
+ describe Rapns::Apns::Notification, "bug #35" do
171
159
  it "should limit payload size to 256 bytes but not the entire packet" do
172
- notification = Rapns::Notification.new do |n|
160
+ notification = Rapns::Apns::Notification.new do |n|
173
161
  n.device_token = "a" * 64
174
162
  n.alert = "a" * 210
175
- n.app = 'my_app'
163
+ n.app = Rapns::Apns::App.create!(:name => 'my_app', :environment => 'development', :certificate => TEST_CERT)
176
164
  end
177
165
 
178
166
  notification.to_binary(:for_validation => true).bytesize.should > 256
@@ -181,36 +169,20 @@ describe Rapns::Notification, "bug #35" do
181
169
  end
182
170
  end
183
171
 
184
- describe Rapns::Notification, "multi_json usage" do
185
- describe Rapns::Notification, "alert" do
172
+ describe Rapns::Apns::Notification, "multi_json usage" do
173
+ describe Rapns::Apns::Notification, "alert" do
186
174
  it "should call MultiJson.load when multi_json version is 1.3.0" do
187
- notification = Rapns::Notification.new(:alert => { :a => 1 }, :alert_is_json => true)
175
+ notification = Rapns::Apns::Notification.new(:alert => { :a => 1 }, :alert_is_json => true)
188
176
  Gem.stub(:loaded_specs).and_return( { 'multi_json' => Gem::Specification.new('multi_json', '1.3.0') } )
189
177
  MultiJson.should_receive(:load).with(any_args())
190
178
  notification.alert
191
179
  end
192
180
 
193
181
  it "should call MultiJson.decode when multi_json version is 1.2.9" do
194
- notification = Rapns::Notification.new(:alert => { :a => 1 }, :alert_is_json => true)
182
+ notification = Rapns::Apns::Notification.new(:alert => { :a => 1 }, :alert_is_json => true)
195
183
  Gem.stub(:loaded_specs).and_return( { 'multi_json' => Gem::Specification.new('multi_json', '1.2.9') } )
196
184
  MultiJson.should_receive(:decode).with(any_args())
197
185
  notification.alert
198
186
  end
199
187
  end
200
-
201
- describe Rapns::Notification, "attributes_for_device=" do
202
- it "should call MultiJson.dump when multi_json responds to :dump" do
203
- notification = Rapns::Notification.new
204
- MultiJson.stub(:respond_to?).with(:dump).and_return(true)
205
- MultiJson.should_receive(:dump).with(any_args())
206
- notification.attributes_for_device = { :pirates => 1 }
207
- end
208
-
209
- it "should call MultiJson.encode when multi_json does not respond to :dump" do
210
- notification = Rapns::Notification.new
211
- MultiJson.stub(:respond_to?).with(:dump).and_return(false)
212
- MultiJson.should_receive(:encode).with(any_args())
213
- notification.attributes_for_device = { :ninjas => 1 }
214
- end
215
- end
216
- end
188
+ end
@@ -0,0 +1,18 @@
1
+ require "unit_spec_helper"
2
+
3
+ describe Rapns::App do
4
+ it { should validate_numericality_of(:connections) }
5
+
6
+ it 'validates the uniqueness of name within type and environment' do
7
+ Rapns::Apns::App.create!(:name => 'test', :environment => 'production', :certificate => TEST_CERT)
8
+ app = Rapns::Apns::App.new(:name => 'test', :environment => 'production', :certificate => TEST_CERT)
9
+ app.valid?.should be_false
10
+ app.errors[:name].should == ['has already been taken']
11
+
12
+ app = Rapns::Apns::App.new(:name => 'test', :environment => 'development', :certificate => TEST_CERT)
13
+ app.valid?.should be_true
14
+
15
+ app = Rapns::Gcm::App.new(:name => 'test', :environment => 'production', :auth_key => TEST_CERT)
16
+ app.valid?.should be_true
17
+ end
18
+ end
@@ -0,0 +1,37 @@
1
+ require 'unit_spec_helper'
2
+ require File.dirname(__FILE__) + '/../app_runner_shared.rb'
3
+
4
+ describe Rapns::Daemon::Apns::AppRunner do
5
+ it_behaves_like 'an AppRunner subclass'
6
+
7
+ let(:app_class) { Rapns::Apns::App }
8
+ let(:app) { app_class.create!(:name => 'my_app', :environment => 'development',
9
+ :certificate => TEST_CERT, :password => 'pass') }
10
+ let(:runner) { Rapns::Daemon::Apns::AppRunner.new(app) }
11
+ let(:handler) { stub(:start => nil, :stop => nil, :queue= => nil) }
12
+ let(:receiver) { stub(:start => nil, :stop => nil) }
13
+ let(:config) { {:feedback_poll => 60 } }
14
+
15
+ before do
16
+ Rapns::Daemon::Apns::DeliveryHandler.stub(:new => handler)
17
+ Rapns::Daemon::Apns::FeedbackReceiver.stub(:new => receiver)
18
+ Rapns::Daemon.stub(:config => config)
19
+ end
20
+
21
+ it 'instantiates a new feedback receiver when started' do
22
+ Rapns::Daemon::Apns::FeedbackReceiver.should_receive(:new).with(app, 'feedback.sandbox.push.apple.com',
23
+ 2196, 60)
24
+ runner.start
25
+ end
26
+
27
+ it 'starts the feedback receiver' do
28
+ receiver.should_receive(:start)
29
+ runner.start
30
+ end
31
+
32
+ it 'stops the feedback receiver' do
33
+ runner.start
34
+ receiver.should_receive(:stop)
35
+ runner.stop
36
+ end
37
+ end
@@ -1,6 +1,6 @@
1
- require "spec_helper"
1
+ require "unit_spec_helper"
2
2
 
3
- describe Rapns::Daemon::Connection do
3
+ describe Rapns::Daemon::Apns::Connection do
4
4
  let(:ssl_context) { stub(:key= => nil, :cert= => nil) }
5
5
  let(:rsa_key) { stub }
6
6
  let(:certificate) { stub }
@@ -11,7 +11,7 @@ describe Rapns::Daemon::Connection do
11
11
  let(:tcp_socket) { stub(:setsockopt => nil, :close => nil) }
12
12
  let(:ssl_socket) { stub(:sync= => nil, :connect => nil, :close => nil, :write => nil, :flush => nil) }
13
13
  let(:logger) { stub(:info => nil, :error => nil) }
14
- let(:connection) { Rapns::Daemon::Connection.new('Connection 0', host, port, certificate, password) }
14
+ let(:connection) { Rapns::Daemon::Apns::Connection.new('Connection 0', host, port, certificate, password) }
15
15
 
16
16
  before do
17
17
  OpenSSL::SSL::SSLContext.stub(:new => ssl_context)
@@ -125,7 +125,7 @@ describe Rapns::Daemon::Connection do
125
125
  logger.should_receive(:error).with("[Connection 0] Lost connection to gateway.push.apple.com:2195 (#{error_type.name}), reconnecting...").once
126
126
  begin
127
127
  connection.write(nil)
128
- rescue Rapns::Daemon::ConnectionError
128
+ rescue Rapns::Daemon::Apns::ConnectionError
129
129
  end
130
130
  end
131
131
 
@@ -133,21 +133,21 @@ describe Rapns::Daemon::Connection do
133
133
  connection.should_receive(:reconnect).exactly(3).times
134
134
  begin
135
135
  connection.write(nil)
136
- rescue Rapns::Daemon::ConnectionError
136
+ rescue Rapns::Daemon::Apns::ConnectionError
137
137
  end
138
138
  end
139
139
 
140
140
  it "raises a ConnectionError after 3 attempts at reconnecting" do
141
141
  expect do
142
142
  connection.write(nil)
143
- end.to raise_error(Rapns::Daemon::ConnectionError, "Connection 0 tried 3 times to reconnect but failed (#{error_type.name}).")
143
+ end.to raise_error(Rapns::Daemon::Apns::ConnectionError, "Connection 0 tried 3 times to reconnect but failed (#{error_type.name}).")
144
144
  end
145
145
 
146
146
  it "sleeps 1 second before retrying the connection" do
147
147
  connection.should_receive(:sleep).with(1)
148
148
  begin
149
149
  connection.write(nil)
150
- rescue Rapns::Daemon::ConnectionError
150
+ rescue Rapns::Daemon::Apns::ConnectionError
151
151
  end
152
152
  end
153
153
  end
@@ -206,7 +206,7 @@ describe Rapns::Daemon::Connection do
206
206
  before { connection.connect }
207
207
 
208
208
  it 'reconnects if the connection has been idle for more than the defined period' do
209
- Rapns::Daemon::Connection.stub(:idle_period => 0.1)
209
+ Rapns::Daemon::Apns::Connection.stub(:idle_period => 0.1)
210
210
  sleep 0.2
211
211
  connection.should_receive(:reconnect)
212
212
  connection.write('blah')
@@ -225,7 +225,7 @@ describe Rapns::Daemon::Connection do
225
225
  end
226
226
 
227
227
  it 'logs the the connection is idle' do
228
- Rapns::Daemon::Connection.stub(:idle_period => 0.1)
228
+ Rapns::Daemon::Apns::Connection.stub(:idle_period => 0.1)
229
229
  sleep 0.2
230
230
  Rapns::Daemon.logger.should_receive(:info).with('[Connection 0] Idle period exceeded, reconnecting...')
231
231
  connection.write('blah')
@@ -0,0 +1,48 @@
1
+ require 'unit_spec_helper'
2
+ require File.dirname(__FILE__) + '/../delivery_handler_shared.rb'
3
+
4
+ describe Rapns::Daemon::Apns::DeliveryHandler do
5
+ it_should_behave_like 'an DeliveryHandler subclass'
6
+
7
+ let(:host) { 'localhost' }
8
+ let(:port) { 2195 }
9
+ let(:certificate) { stub }
10
+ let(:password) { stub }
11
+ let(:app) { stub(:password => password, :certificate => certificate, :name => 'MyApp')}
12
+ let(:delivery_handler) { Rapns::Daemon::Apns::DeliveryHandler.new(app, host, port) }
13
+ let(:connection) { stub('Connection', :select => false, :write => nil, :reconnect => nil, :close => nil, :connect => nil) }
14
+ let(:notification) { stub }
15
+ let(:http) { stub(:shutdown => nil)}
16
+ let(:queue) { Rapns::Daemon::DeliveryQueue.new }
17
+
18
+ before do
19
+ Rapns::Daemon::Apns::Connection.stub(:new => connection)
20
+ Rapns::Daemon::Apns::Delivery.stub(:perform)
21
+ delivery_handler.queue = queue
22
+ queue.push(notification)
23
+ end
24
+
25
+ it "instantiates a new connection" do
26
+ Rapns::Daemon::Apns::Connection.should_receive(:new).with(app.name, host, port, certificate, password)
27
+ Rapns::Daemon::Apns::DeliveryHandler.new(app, host, port)
28
+ end
29
+
30
+ it 'performs delivery of an notification' do
31
+ Rapns::Daemon::Apns::Delivery.should_receive(:perform).with(app, connection, notification)
32
+ delivery_handler.start
33
+ delivery_handler.stop
34
+ end
35
+
36
+ it "connects the socket when instantiated" do
37
+ connection.should_receive(:connect)
38
+ Rapns::Daemon::Apns::DeliveryHandler.new(app, host, port)
39
+ delivery_handler.start
40
+ delivery_handler.stop
41
+ end
42
+
43
+ it 'closes the connection stopped' do
44
+ connection.should_receive(:close)
45
+ delivery_handler.start
46
+ delivery_handler.stop
47
+ end
48
+ end