Skip to content

Commit

Permalink
Added APN::Notification.send_notifications method and tests for it.
Browse files Browse the repository at this point in the history
  • Loading branch information
markbates committed Jul 23, 2009
1 parent bae347d commit a50d3e2
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 14 deletions.
20 changes: 20 additions & 0 deletions lib/apn_on_rails/apn_on_rails.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
27 changes: 26 additions & 1 deletion lib/apn_on_rails/app/models/apn/notification.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion spec/active_record/setup_ar.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
41 changes: 41 additions & 0 deletions spec/apn_on_rails/app/models/apn/notification_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
12 changes: 1 addition & 11 deletions spec/factories/notification_factory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
19 changes: 19 additions & 0 deletions spec/rails_root/config/apple_push_notification_development.pem
Original file line number Diff line number Diff line change
@@ -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-----
6 changes: 6 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.