Permalink
Browse files

Added APN::Notification.send_notifications method and tests for it.

  • Loading branch information...
1 parent bae347d commit a50d3e2e139ece7aada4b885e8ae575630c318b3 @markbates markbates committed Jul 23, 2009
@@ -2,6 +2,26 @@
require 'openssl'
require 'configatron'
+rails_root = File.join(FileUtils.pwd, 'rails_root')
+if defined?(RAILS_ROOT)
+ rails_root = RAILS_ROOT
+end
+
+rails_env = 'development'
+if defined?(RAILS_ENV)
+ rails_env = RAILS_ENV
+end
+
+configatron.apn.set_default(:passphrase, '')
+configatron.apn.set_default(:port, 2195)
+configatron.apn.set_default(:host, 'gateway.sandbox.push.apple.com')
+configatron.apn.set_default(:cert, File.join(rails_root, 'config', 'apple_push_notification_development.pem'))
+
+if rails_env == 'production'
+ configatron.apn.set_default(:host, 'gateway.push.apple.com')
+ configatron.apn.set_default(:cert, File.join(rails_root, 'config', 'apple_push_notification_production.pem'))
+end
+
module APN
module Errors
@@ -51,4 +51,29 @@ def message_for_sending
message
end
-end
+ class << self
+
+ def send_notifications(notifications)
+ cert = File.read(configatron.apn.cert)
+ ctx = OpenSSL::SSL::SSLContext.new
+ ctx.key = OpenSSL::PKey::RSA.new(cert, configatron.apn.passphrase)
+ ctx.cert = OpenSSL::X509::Certificate.new(cert)
+
+ s = TCPSocket.new(configatron.apn.host, configatron.apn.port)
+ ssl = OpenSSL::SSL::SSLSocket.new(s, ctx)
+ ssl.sync = true
+ ssl.connect
+
+ notifications.each do |noty|
+ ssl.write(noty.message_for_sending)
+ noty.sent_at = Time.now
+ noty.save
+ end
+
+ ssl.close
+ s.close
+ end
+
+ end # class << self
+
+end # APN::Notification
@@ -6,7 +6,6 @@ def self.up
t.integer :device_id, :null => false
t.integer :errors_nb, :default => 0 # used for storing errors from apple feedbacks
t.string :device_language, :size => 5 # if you don't want to send localized strings
- t.text :payload
t.string :sound
t.string :alert, :size => 150
t.integer :badge
@@ -6,7 +6,8 @@
ActiveRecord::Base.logger = logger
db_file = File.join(File.dirname(__FILE__), 'test.db')
-FileUtils.rm(db_file) if File.exists?(db_file)
+# FileUtils.rm(db_file) if File.exists?(db_file)
+File.open(db_file, 'w')
ActiveRecord::Base.establish_connection({
:adapter => 'sqlite3',
@@ -56,4 +56,45 @@
end
+ describe 'send_notifications' do
+
+ it 'should send the notifications in an Array' do
+
+ notifications = [NotificationFactory.create, NotificationFactory.create]
+ notifications.each_with_index do |notify, i|
+ notify.stub(:message_for_sending).and_return("message-#{i}")
+ notify.should_receive(:sent_at=).with(instance_of(Time))
+ notify.should_receive(:save)
+ end
+
+ rsa_mock = mock('rsa_mock')
+ OpenSSL::PKey::RSA.should_receive(:new).with(apn_cert, '').and_return(rsa_mock)
+
+ cert_mock = mock('cert_mock')
+ OpenSSL::X509::Certificate.should_receive(:new).and_return(cert_mock)
+
+ ctx_mock = mock('ctx_mock')
+ ctx_mock.should_receive(:key=).with(rsa_mock)
+ ctx_mock.should_receive(:cert=).with(cert_mock)
+ OpenSSL::SSL::SSLContext.should_receive(:new).and_return(ctx_mock)
+
+ # TCPSocket.new(configatron.apn.host, configatron.apn.port)
+ tcp_mock = mock('tcp_mock')
+ tcp_mock.should_receive(:close)
+ TCPSocket.should_receive(:new).with('gateway.sandbox.push.apple.com', 2195).and_return(tcp_mock)
+
+ ssl_mock = mock('ssl_mock')
+ ssl_mock.should_receive(:sync=).with(true)
+ ssl_mock.should_receive(:connect)
+ ssl_mock.should_receive(:write).with('message-0')
+ ssl_mock.should_receive(:write).with('message-1')
+ ssl_mock.should_receive(:close)
+ OpenSSL::SSL::SSLSocket.should_receive(:new).with(tcp_mock, ctx_mock).and_return(ssl_mock)
+
+ APN::Notification.send_notifications(notifications)
+
+ end
+
+ end
+
end
@@ -19,14 +19,4 @@ def create(options = {})
end
-NotificationFactory.create
-
-# t.integer :device_id, :null => false
-# t.integer :errors_nb, :default => 0 # used for storing errors from apple feedbacks
-# t.string :device_language, :size => 5 # if you don't want to send localized strings
-# t.text :payload
-# t.string :sound
-# t.integer :badge
-# t.text :app_data
-# t.datetime :sent_at
-# t.timestamps
+NotificationFactory.create
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDDDCCAfSgAwIBAgIBATANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGEwJVUzEN
+MAsGA1UECgwEaG9tZTERMA8GA1UECwwIbWFjYmF0ZXMxCzAJBgNVBAMMAkNBMB4X
+DTA5MDIyMjE5MDUyOVoXDTEwMDIyMjE5MDUyOVowUzELMAkGA1UEBhMCVVMxDTAL
+BgNVBAoMBGhvbWUxETAPBgNVBAsMCG1hY2JhdGVzMQswCQYDVQQLDAJDQTEVMBMG
+A1UEAwwMaGVsbG8tc2VydmVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCr
+LhTbcQc6hpYVeB8O94JzWnS41wZTaHReYe2mAxkIH9gF11Gm/Tejdfy7TboVsVtD
+FZ+vrVYPFnnVZG2UNDUkfBvkbCBrFQ8glnAHGRYtDxdFjrLDxm0BOfC58wEtV2cM
+hZhiLqjHFuSjHuAlAUshfCfWmKbEeDVtFSDxUMa6iQIDAQABo4GFMIGCMAwGA1Ud
+EwEB/wQCMAAwMQYJYIZIAYb4QgENBCQWIlJ1YnkvT3BlblNTTCBHZW5lcmF0ZWQg
+Q2VydGlmaWNhdGUwHQYDVR0OBBYEFEIBIEcdhFKPB+QILbsupdz3uD6YMAsGA1Ud
+DwQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOCAQEA
+dOKP/y/hsdnn2cbYpu2I6r8Lzql52XKa+jOaOT0TyPhmUAz0bFUgA53a202MDhbS
+KDVhIkC88KTjyyRwVNnwsrS5JD/IOXIJw/vy9VX14aCymPkup0TQR6ZIicKrjcMS
+yhmU5I0+fmsUN4PnayOuT/tJ0giy/x+1L/pgMicS47TvyNLB0vl34FplgmH6zlXv
+nS/5phroEJm71DPyDNNzoohZo54YHpGmvEDqjLc6DB+Ihu6/sghmd5dlSPNqsubO
+sBQeOyNuscbXo6MXI8uDYrZ/PqAtdzPXBjB7LXvVs69YT4KT7BaO3rqobgfJ0kNU
+e7roqj04VUJGmU47qrMLBg==
+-----END CERTIFICATE-----
View
@@ -14,6 +14,8 @@
require f
end
+configatron.apn.cert = File.expand_path(File.join(File.dirname(__FILE__), 'rails_root', 'config', 'apple_push_notification_development.pem'))
+
Spec::Runner.configure do |config|
config.before(:all) do
@@ -44,4 +46,8 @@ def fixture_value(*name)
def write_fixture(name, value)
File.open(fixture_path(*name), 'w') {|f| f.write(value)}
+end
+
+def apn_cert
+ File.read(File.join(File.dirname(__FILE__), 'rails_root', 'config', 'apple_push_notification_development.pem'))
end

0 comments on commit a50d3e2

Please sign in to comment.