rapns 1.0.3 → 1.0.4

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.
@@ -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: