rapns 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,18 +7,22 @@ class RapnsGenerator < Rails::Generators::Base
7
7
  end
8
8
 
9
9
  def copy_migration
10
- migration_dir = File.expand_path("db/migrate")
11
-
12
- if !self.class.migration_exists?(migration_dir, 'create_rapns_notifications')
13
- migration_template "create_rapns_notifications.rb", "db/migrate/create_rapns_notifications.rb"
14
- end
15
-
16
- if !self.class.migration_exists?(migration_dir, 'create_rapns_feedback')
17
- migration_template "create_rapns_feedback.rb", "db/migrate/create_rapns_feedback.rb"
18
- end
10
+ add_rapns_migration('create_rapns_notifications')
11
+ add_rapns_migration('create_rapns_feedback')
12
+ add_rapns_migration('add_alert_is_json_to_rapns_notifications')
19
13
  end
20
14
 
21
15
  def copy_config
22
- copy_file "rapns.yml", "config/rapns/rapns.yml"
16
+ copy_file 'rapns.yml', 'config/rapns/rapns.yml'
17
+ end
18
+
19
+ protected
20
+
21
+ def add_rapns_migration(template)
22
+ migration_dir = File.expand_path('db/migrate')
23
+
24
+ if !self.class.migration_exists?(migration_dir, template)
25
+ migration_template "#{template}.rb", "db/migrate/#{template}.rb"
26
+ end
23
27
  end
24
28
  end
@@ -0,0 +1,9 @@
1
+ class AddAlertIsJsonToRapnsNotifications < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :rapns_notifications, :alert_is_json, :boolean, :null => true, :default => false
4
+ end
5
+
6
+ def self.down
7
+ remove_column :rapns_notifications, :alert_is_json
8
+ end
9
+ end
@@ -2,7 +2,7 @@ module Rapns
2
2
  class BinaryNotificationValidator < ActiveModel::Validator
3
3
 
4
4
  def validate(record)
5
- if record.to_binary(:for_validation => true).size > 256
5
+ if record.payload_size > 256
6
6
  record.errors[:base] << "APN notification cannot be larger than 256 bytes. Try condensing your alert and device attributes."
7
7
  end
8
8
  end
@@ -44,7 +44,7 @@ module Rapns
44
44
 
45
45
  def self.parse_tuple(tuple)
46
46
  failed_at, _, device_token = tuple.unpack("N1n1H*")
47
- [Time.at(failed_at), device_token]
47
+ [Time.at(failed_at).utc, device_token]
48
48
  end
49
49
 
50
50
  def self.create_feedback(failed_at, device_token)
@@ -4,10 +4,14 @@ module Rapns
4
4
  def interruptible_sleep(seconds)
5
5
  @_sleep_check, @_sleep_interrupt = IO.pipe
6
6
  IO.select([@_sleep_check], nil, nil, seconds)
7
+ @_sleep_check.close rescue IOError
8
+ @_sleep_interrupt.close rescue IOError
7
9
  end
8
10
 
9
11
  def interrupt_sleep
10
- @_sleep_interrupt.close if @_sleep_interrupt
12
+ if @_sleep_interrupt
13
+ @_sleep_interrupt.close rescue IOError
14
+ end
11
15
  end
12
16
  end
13
17
  end
@@ -1,6 +1,6 @@
1
1
  module Rapns
2
2
  class Notification < ActiveRecord::Base
3
- set_table_name "rapns_notifications"
3
+ self.table_name = 'rapns_notifications'
4
4
 
5
5
  validates :device_token, :presence => true
6
6
  validates :badge, :numericality => true, :allow_nil => true
@@ -18,14 +18,25 @@ module Rapns
18
18
  def alert=(alert)
19
19
  if alert.is_a?(Hash)
20
20
  write_attribute(:alert, ActiveSupport::JSON.encode(alert))
21
+ self.alert_is_json = true if has_attribute?(:alert_is_json)
21
22
  else
22
23
  write_attribute(:alert, alert)
24
+ self.alert_is_json = false if has_attribute?(:alert_is_json)
23
25
  end
24
26
  end
25
27
 
26
28
  def alert
27
29
  string_or_json = read_attribute(:alert)
28
- ActiveSupport::JSON.decode(string_or_json) rescue string_or_json
30
+
31
+ if has_attribute?(:alert_is_json)
32
+ if alert_is_json?
33
+ ActiveSupport::JSON.decode(string_or_json)
34
+ else
35
+ string_or_json
36
+ end
37
+ else
38
+ ActiveSupport::JSON.decode(string_or_json) rescue string_or_json
39
+ end
29
40
  end
30
41
 
31
42
  def attributes_for_device=(attrs)
@@ -47,12 +58,19 @@ module Rapns
47
58
  json
48
59
  end
49
60
 
61
+ def payload
62
+ as_json.to_json
63
+ end
64
+
65
+ def payload_size
66
+ payload.bytesize
67
+ end
68
+
50
69
  # This method conforms to the enhanced binary format.
51
70
  # http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingWIthAPS/CommunicatingWIthAPS.html#//apple_ref/doc/uid/TP40008194-CH101-SW4
52
71
  def to_binary(options = {})
53
72
  id_for_pack = options[:for_validation] ? 0 : id
54
- json = as_json.to_json
55
- [1, id_for_pack, expiry, 0, 32, device_token, 0, json.size, json].pack("cNNccH*cca*")
73
+ [1, id_for_pack, expiry, 0, 32, device_token, 0, payload_size, payload].pack("cNNccH*cca*")
56
74
  end
57
75
  end
58
76
  end
data/lib/rapns/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rapns
2
- VERSION = '1.0.3'
2
+ VERSION = '1.0.4'
3
3
  end
@@ -5,6 +5,9 @@ describe Rapns::Daemon::InterruptibleSleep do
5
5
  extend Rapns::Daemon::InterruptibleSleep
6
6
  end
7
7
 
8
+ let(:rd) { stub(:close => nil) }
9
+ let(:wr) { stub(:close => nil) }
10
+
8
11
  before do
9
12
  IO.stub(:pipe)
10
13
  IO.stub(:select)
@@ -16,15 +19,20 @@ describe Rapns::Daemon::InterruptibleSleep do
16
19
  end
17
20
 
18
21
  it 'selects on the reader' do
19
- rd = stub
20
- IO.stub(:pipe => [rd, stub])
22
+ IO.stub(:pipe => [rd, wr])
21
23
  IO.should_receive(:select).with([rd], nil, nil, 1)
22
24
  SleepTest.interruptible_sleep 1
23
25
  end
24
26
 
27
+ it 'closes both ends of the pipe after the timeout' do
28
+ IO.stub(:pipe => [rd, wr])
29
+ rd.should_receive(:close)
30
+ wr.should_receive(:close)
31
+ SleepTest.interruptible_sleep 1
32
+ end
33
+
25
34
  it 'closes the writer' do
26
- wr = stub
27
- IO.stub(:pipe => [stub, wr])
35
+ IO.stub(:pipe => [rd, wr])
28
36
  SleepTest.interruptible_sleep 1
29
37
  wr.should_receive(:close)
30
38
  SleepTest.interrupt_sleep
@@ -115,3 +115,31 @@ describe Rapns::Notification, "to_binary" do
115
115
  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\"}"
116
116
  end
117
117
  end
118
+
119
+ describe Rapns::Notification, "bug #31" do
120
+ it 'does not confuse a JSON looking string as JSON' do
121
+ notification = Rapns::Notification.new
122
+ notification.alert = "{\"one\":2}"
123
+ notification.alert.should == "{\"one\":2}"
124
+ end
125
+
126
+ it 'does confuse a JSON looking string as JSON if the alert_is_json attribute is not present' do
127
+ notification = Rapns::Notification.new
128
+ notification.stub(:has_attribute? => false)
129
+ notification.alert = "{\"one\":2}"
130
+ notification.alert.should == {"one" => 2}
131
+ end
132
+ end
133
+
134
+ describe Rapns::Notification, "bug #35" do
135
+ it "should limit payload size to 256 bytes but not the entire packet" do
136
+ notification = Rapns::Notification.new do |n|
137
+ n.device_token = "a" * 64
138
+ n.alert = "a" * 210
139
+ end
140
+
141
+ notification.to_binary(:for_validation => true).size.should > 256
142
+ notification.payload_size.should < 256
143
+ notification.should be_valid
144
+ end
145
+ end
data/spec/spec_helper.rb CHANGED
@@ -18,8 +18,9 @@ puts "Using #{$adapter} adapter."
18
18
  ActiveRecord::Base.establish_connection('adapter' => $adapter, 'database' => 'rapns_test')
19
19
  require 'generators/templates/create_rapns_notifications'
20
20
  require 'generators/templates/create_rapns_feedback'
21
+ require 'generators/templates/add_alert_is_json_to_rapns_notifications'
21
22
 
22
- [CreateRapnsNotifications, CreateRapnsFeedback].each do |migration|
23
+ [CreateRapnsNotifications, CreateRapnsFeedback, AddAlertIsJsonToRapnsNotifications].each do |migration|
23
24
  migration.down rescue ActiveRecord::StatementInvalid
24
25
  migration.up
25
26
  end
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: 1.0.3
4
+ version: 1.0.4
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-01-13 00:00:00.000000000 Z
12
+ date: 2012-01-31 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Easy to use library for Apple's Push Notification Service with Rails
15
15
  3
@@ -21,6 +21,7 @@ extensions: []
21
21
  extra_rdoc_files: []
22
22
  files:
23
23
  - lib/generators/rapns_generator.rb
24
+ - lib/generators/templates/add_alert_is_json_to_rapns_notifications.rb
24
25
  - lib/generators/templates/create_rapns_feedback.rb
25
26
  - lib/generators/templates/create_rapns_notifications.rb
26
27
  - lib/generators/templates/rapns.yml
@@ -86,7 +87,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
86
87
  version: '0'
87
88
  requirements: []
88
89
  rubyforge_project:
89
- rubygems_version: 1.8.15
90
+ rubygems_version: 1.8.10
90
91
  signing_key:
91
92
  specification_version: 3
92
93
  summary: Easy to use library for Apple's Push Notification Service with Rails 3
@@ -107,4 +108,3 @@ test_files:
107
108
  - spec/rapns/feedback_spec.rb
108
109
  - spec/rapns/notification_spec.rb
109
110
  - spec/spec_helper.rb
110
- has_rdoc: