apnd 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -83,12 +83,32 @@ push notifications to APND.
83
83
  APND::Notification.upstream_host = 'localhost'
84
84
  APND::Notification.upstream_port = 22195
85
85
 
86
- notification = APND::Notification.create(
86
+ notification1 = APND::Notification.new(
87
87
  :alert => 'Alert!',
88
88
  :token => 'fe15a27d5df3c34778defb1f4f3880265cc52c0c047682223be59fb68500a9a2',
89
+ :badge => 1
90
+ )
91
+
92
+ notification2 = APND::Notification.new(
93
+ :alert => 'Red Alert!',
94
+ :token => 'fe15a27d5df3c34778defb1f4f3880265cc52c0c047682223be59fb68500a9a2',
89
95
  :badge => 99
90
96
  )
91
97
 
98
+ # Send multiple notifications at once to avoid overhead in
99
+ # opening/closing the upstream socket connection each time
100
+ APND::Notification.open_upstream_socket do |sock|
101
+ sock.puts notification1
102
+ sock.puts notification2
103
+ end
104
+
105
+ # Send a notification to the upstream socket immediately
106
+ notification3 = APND::Notification.create(
107
+ :alert => 'Alert!',
108
+ :token => 'fe15a27d5df3c34778defb1f4f3880265cc52c0c047682223be59fb68500a9a2',
109
+ :badge => 0
110
+ )
111
+
92
112
 
93
113
  ## Prerequisites
94
114
 
@@ -105,6 +125,9 @@ at [developer.apple.com](http://developer.apple.com/).
105
125
 
106
126
  Ruby must be compiled with OpenSSL support.
107
127
 
128
+ Tests use [Shoulda](http://github.com/thoughtbot/shoulda), and optionally
129
+ [TURN](https://github.com/TwP/turn).
130
+
108
131
 
109
132
  ## Installation
110
133
 
@@ -34,7 +34,7 @@ module APND
34
34
  #
35
35
  def run!
36
36
  EventMachine::run do
37
- ohai "Starting APND Daemon on #{@bind}:#{@port}"
37
+ ohai "Starting APND Daemon v#{APND::Version} on #{@bind}:#{@port}"
38
38
  EventMachine::start_server(@bind, @port, APND::Daemon::Protocol) do |server|
39
39
  server.queue = @queue
40
40
  end
@@ -9,5 +9,14 @@ module APND
9
9
  super("Payload is larger than 256 bytes: '#{message}'")
10
10
  end
11
11
  end
12
+
13
+ #
14
+ # Raised when parsing a Notification with an invalid header
15
+ #
16
+ class InvalidNotificationHeader < StandardError
17
+ def initialize(header)
18
+ super("Invalid Notification header: #{header.inspect}")
19
+ end
20
+ end
12
21
  end
13
22
  end
@@ -81,6 +81,8 @@ module APND
81
81
  #
82
82
  def self.valid?(data)
83
83
  parse(data)
84
+ rescue
85
+ false
84
86
  end
85
87
 
86
88
  #
@@ -93,7 +95,7 @@ module APND
93
95
  header = buffer.slice!(0, 3).unpack('ccc')
94
96
 
95
97
  if header[0] != 0
96
- raise RuntimeError, "Invalid Notification header: #{header.inspect}"
98
+ raise APND::Errors::InvalidNotificationHeader.new(header)
97
99
  end
98
100
 
99
101
  notification.token = buffer.slice!(0, 32).unpack('H*').first
@@ -117,8 +119,6 @@ module APND
117
119
  end
118
120
 
119
121
  notification
120
- rescue
121
- false
122
122
  end
123
123
 
124
124
  #
@@ -171,7 +171,7 @@ module APND
171
171
  def aps_json
172
172
  return @aps_json if @aps_json
173
173
  json = aps.to_json
174
- raise APND::InvalidPayload.new(json) if json.size > 256
174
+ raise APND::Errors::InvalidPayload.new(json) if json.size > 256
175
175
  @aps_json = json
176
176
  end
177
177
 
@@ -111,6 +111,18 @@ module APND
111
111
  @apple ||= APND::Settings::AppleConnection.new
112
112
  end
113
113
 
114
+ #
115
+ # Mass assign AppleConnection settings
116
+ #
117
+ def apple=(options = {})
118
+ if options.respond_to?(:keys)
119
+ apple.cert = options[:cert] if options[:cert]
120
+ apple.cert_pass = options[:cert_pass] if options[:cert_pass]
121
+ apple.host = options[:host] if options[:host]
122
+ apple.port = options[:port] if options[:port]
123
+ end
124
+ end
125
+
114
126
  #
115
127
  # Returns the Daemon settings
116
128
  #
@@ -118,11 +130,33 @@ module APND
118
130
  @daemon ||= APND::Settings::Daemon.new
119
131
  end
120
132
 
133
+ #
134
+ # Mass assign Daemon settings
135
+ #
136
+ def daemon=(options = {})
137
+ if options.respond_to?(:keys)
138
+ daemon.bind = options[:bind] if options[:bind]
139
+ daemon.port = options[:port] if options[:port]
140
+ daemon.log_file = options[:log_file] if options[:log_file]
141
+ daemon.timer = options[:timer] if options[:timer]
142
+ end
143
+ end
144
+
121
145
  #
122
146
  # Returns the Notification settings
123
147
  #
124
148
  def notification
125
149
  @notification ||= APND::Settings::Notification.new
126
150
  end
151
+
152
+ #
153
+ # Mass assign Notification settings
154
+ #
155
+ def notification=(options = {})
156
+ if options.respond_to?(:keys)
157
+ notification.port = options[:port] if options[:port]
158
+ notification.host = options[:host] if options[:host]
159
+ end
160
+ end
127
161
  end
128
162
  end
@@ -2,7 +2,7 @@ module APND
2
2
  class Version #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 1
5
- TINY = 4
5
+ TINY = 5
6
6
 
7
7
  def self.to_s
8
8
  [MAJOR, MINOR, TINY].join('.')
@@ -1,40 +1,69 @@
1
1
  require File.dirname(__FILE__) + '/test_helper.rb'
2
2
 
3
- context "APND" do
4
- setup do
5
- @bytes = %|\000\000 \376\025\242}]\363\303Gx\336\373\037O8\200&\\\305,\f\004v\202";\345\237\266\205\000\251\242\000;{"aps":{"sound":"default","alert":"Red Alert, Numba One!"}}|
6
- @notification = APND::Notification.new({
7
- :token => 'fe15a27d5df3c34778defb1f4f3880265cc52c0c047682223be59fb68500a9a2',
8
- :alert => 'Red Alert, Numba One!',
9
- :sound => 'default'
10
- })
11
- end
3
+ class APNDTest < Test::Unit::TestCase
4
+ @@bytes = %|\000\000 \376\025\242}]\363\303Gx\336\373\037O8\200&\\\305,\f\004v\202\";\345\237\266\205\000\251\242\000\\{\"location\":\"New York\",\"aps\":{\"badge\":10,\"sound\":\"default\",\"alert\":\"Red Alert, Numba One!\"}}|
12
5
 
13
- test "Notification returns a valid hex_token" do
14
- expected = %|\376\025\242}]\363\303Gx\336\373\037O8\200&\\\305,\f\004v\202";\345\237\266\205\000\251\242|
15
- assert_equal @notification.hex_token, expected
16
- end
6
+ context "APND Notification" do
7
+ setup do
8
+ @notification = APND::Notification.new({
9
+ :token => 'fe15a27d5df3c34778defb1f4f3880265cc52c0c047682223be59fb68500a9a2',
10
+ :alert => 'Red Alert, Numba One!',
11
+ :sound => 'default',
12
+ :badge => 10,
13
+ :custom => { 'location' => 'New York' }
14
+ })
15
+ end
17
16
 
18
- test "Notification returns a valid byte string for Apple" do
19
- assert_equal @notification.to_bytes, @bytes
20
- end
17
+ context "instances" do
18
+ should "be initialized with a hash of options" do
19
+ [:token, :alert, :sound, :badge, :custom].each do |key|
20
+ assert_not_nil @notification.send(key)
21
+ end
22
+ end
23
+
24
+ should "return a valid hex_token" do
25
+ expected = %|\376\025\242}]\363\303Gx\336\373\037O8\200&\\\305,\f\004v\202";\345\237\266\205\000\251\242|
26
+ assert_equal @notification.hex_token, expected
27
+ end
21
28
 
22
- test "Notification.parse returns a Notification when given a valid string" do
23
- notification = APND::Notification.parse(@bytes)
29
+ should "return a valid byte string" do
30
+ assert_equal @notification.to_bytes, @@bytes
31
+ end
32
+ end
33
+
34
+ should "parse a valid packet" do
35
+ notification = APND::Notification.parse(@@bytes)
24
36
 
25
- assert notification
37
+ assert notification
26
38
 
27
- [:alert, :badge, :custom, :sound, :token, :hex_token, :to_bytes, :aps, :aps_json].each do |key|
28
- assert_equal @notification.send(key), notification.send(key)
39
+ [:alert, :badge, :custom, :sound, :token, :hex_token, :to_bytes, :aps, :aps_json].each do |key|
40
+ assert_equal @notification.send(key), notification.send(key)
41
+ end
29
42
  end
30
43
 
31
- assert ! APND::Notification.parse("I'm not a packet!")
44
+ should "raise InvalidNotificationHeader parsing a bad packet" do
45
+ assert_raise APND::Errors::InvalidNotificationHeader do
46
+ APND::Notification.parse("I'm not a packet!")
47
+ end
48
+ end
49
+
50
+ should "raise InvalidPayload if custom hash is too large" do
51
+ assert_raise APND::Errors::InvalidPayload do
52
+ notification = @notification.dup
53
+ notification.custom = {
54
+ 'lorem' => "Hi! " * 200
55
+ }
56
+ APND::Notification.parse(notification.to_bytes)
57
+ end
58
+ end
32
59
  end
33
60
 
34
- test "Notification multiple apns to be sent" do
35
- notifications = [@bytes, @bytes, @bytes].join("\n")
36
- notifications.each_line do |line|
37
- assert APND::Notification.valid?(line)
61
+ context "APND Daemon" do
62
+ should "receive multiple Notifications in a single packet" do
63
+ notifications = [@@bytes, @@bytes, @@bytes].join("\n")
64
+ notifications.each_line do |line|
65
+ assert APND::Notification.valid?(line)
66
+ end
38
67
  end
39
68
  end
40
69
 
@@ -1,33 +1,10 @@
1
1
  require 'rubygems'
2
2
  require 'test/unit'
3
-
4
- dir = File.dirname(File.expand_path(__FILE__))
5
- $LOAD_PATH.unshift(File.join(dir, '..', 'lib'))
6
- $LOAD_PATH.unshift(dir)
7
-
8
- require 'apnd'
3
+ require 'shoulda'
9
4
 
10
5
  begin
11
6
  require 'turn'
12
7
  rescue LoadError
13
8
  end
14
9
 
15
- ##
16
- # test/spec/mini 3
17
- # http://gist.github.com/25455
18
- # chris@ozmm.org
19
- #
20
- def context(*args, &block)
21
- return super unless (name = args.first) && block
22
- require 'test/unit'
23
- klass = Class.new(defined?(ActiveSupport::TestCase) ? ActiveSupport::TestCase : Test::Unit::TestCase) do
24
- def self.test(name, &block)
25
- define_method("test_#{name.gsub(/\W/,'_')}", &block) if block
26
- end
27
- def self.xtest(*args) end
28
- def self.setup(&block) define_method(:setup, &block) end
29
- def self.teardown(&block) define_method(:teardown, &block) end
30
- end
31
- (class << klass; self end).send(:define_method, :name) { name.gsub(/\W/,'_') }
32
- klass.class_eval &block
33
- end
10
+ require 'apnd'
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 4
9
- version: 0.1.4
8
+ - 5
9
+ version: 0.1.5
10
10
  platform: ruby
11
11
  authors:
12
12
  - Joshua Priddle
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-12-08 00:00:00 -05:00
17
+ date: 2010-12-09 00:00:00 -05:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -59,6 +59,18 @@ dependencies:
59
59
  version: 1.1.0
60
60
  type: :runtime
61
61
  version_requirements: *id003
62
+ - !ruby/object:Gem::Dependency
63
+ name: shoulda
64
+ prerelease: false
65
+ requirement: &id004 !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ segments:
70
+ - 0
71
+ version: "0"
72
+ type: :development
73
+ version_requirements: *id004
62
74
  description: " APND (Apple Push Notification Daemon) is a ruby library to send Apple Push\n Notifications to iPhones.\n"
63
75
  email: jpriddle@nevercraft.net
64
76
  executables: