houston 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +22 -16
  3. data/README.md +19 -1
  4. data/bin/apn +3 -0
  5. data/coverage/assets/0.8.0/application.css +799 -0
  6. data/coverage/assets/0.8.0/application.js +1559 -0
  7. data/coverage/assets/0.8.0/colorbox/border.png +0 -0
  8. data/coverage/assets/0.8.0/colorbox/controls.png +0 -0
  9. data/coverage/assets/0.8.0/colorbox/loading.gif +0 -0
  10. data/coverage/assets/0.8.0/colorbox/loading_background.png +0 -0
  11. data/coverage/assets/0.8.0/favicon_green.png +0 -0
  12. data/coverage/assets/0.8.0/favicon_red.png +0 -0
  13. data/coverage/assets/0.8.0/favicon_yellow.png +0 -0
  14. data/coverage/assets/0.8.0/loading.gif +0 -0
  15. data/coverage/assets/0.8.0/magnify.png +0 -0
  16. data/coverage/assets/0.8.0/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  17. data/coverage/assets/0.8.0/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  18. data/coverage/assets/0.8.0/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  19. data/coverage/assets/0.8.0/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  20. data/coverage/assets/0.8.0/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  21. data/coverage/assets/0.8.0/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  22. data/coverage/assets/0.8.0/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  23. data/coverage/assets/0.8.0/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  24. data/coverage/assets/0.8.0/smoothness/images/ui-icons_222222_256x240.png +0 -0
  25. data/coverage/assets/0.8.0/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  26. data/coverage/assets/0.8.0/smoothness/images/ui-icons_454545_256x240.png +0 -0
  27. data/coverage/assets/0.8.0/smoothness/images/ui-icons_888888_256x240.png +0 -0
  28. data/coverage/assets/0.8.0/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  29. data/coverage/index.html +319 -163
  30. data/houston.gemspec +1 -1
  31. data/lib/houston/client.rb +1 -0
  32. data/lib/houston/notification.rb +30 -5
  33. data/lib/houston/version.rb +1 -1
  34. data/spec/client_spec.rb +2 -2
  35. data/spec/notification_spec.rb +23 -10
  36. metadata +28 -4
data/houston.gemspec CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |s|
16
16
  s.add_dependency "commander", "~> 4.1"
17
17
  s.add_dependency "json"
18
18
 
19
- s.add_development_dependency "rspec", "~> 2.0"
19
+ s.add_development_dependency "rspec", "~> 3.0"
20
20
  s.add_development_dependency "rake"
21
21
  s.add_development_dependency "simplecov"
22
22
 
@@ -72,6 +72,7 @@ module Houston
72
72
 
73
73
  if error
74
74
  command, status, index = error.unpack("ccN")
75
+ notifications[index].apns_error_code = status
75
76
  notifications.slice!(0..index)
76
77
  notifications.each(&:mark_as_unsent!)
77
78
  push(*notifications)
@@ -2,10 +2,28 @@ require 'json'
2
2
 
3
3
  module Houston
4
4
  class Notification
5
- MAXIMUM_PAYLOAD_SIZE = 256
5
+ class APNSError < RuntimeError
6
+ # See: https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/CommunicatingWIthAPS.html#//apple_ref/doc/uid/TP40008194-CH101-SW12
7
+ CODES = {
8
+ 0 => "No errors encountered",
9
+ 1 => "Processing error",
10
+ 2 => "Missing device token",
11
+ 3 => "Missing topic",
12
+ 4 => "Missing payload",
13
+ 5 => "Invalid token size",
14
+ 6 => "Invalid topic size",
15
+ 7 => "Invalid payload size",
16
+ 8 => "Invalid token",
17
+ 10 => "Shutdown",
18
+ 255 => "Unknown error"
19
+ }
20
+ end
21
+
22
+ MAXIMUM_PAYLOAD_SIZE = 2048
6
23
 
7
- attr_accessor :token, :alert, :badge, :sound, :content_available, :custom_data, :id, :expiry, :priority
24
+ attr_accessor :token, :alert, :badge, :sound, :category, :content_available, :custom_data, :id, :expiry, :priority
8
25
  attr_reader :sent_at
26
+ attr_writer :apns_error_code
9
27
 
10
28
  alias :device :token
11
29
  alias :device= :token=
@@ -15,6 +33,7 @@ module Houston
15
33
  @alert = options.delete(:alert)
16
34
  @badge = options.delete(:badge)
17
35
  @sound = options.delete(:sound)
36
+ @category = options.delete(:category)
18
37
  @expiry = options.delete(:expiry)
19
38
  @id = options.delete(:id)
20
39
  @priority = options.delete(:priority)
@@ -24,11 +43,13 @@ module Houston
24
43
  end
25
44
 
26
45
  def payload
27
- json = {}.merge(@custom_data || {})
46
+ json = {}.merge(@custom_data || {}).inject({}){|h,(k,v)| h[k.to_s] = v; h}
47
+
28
48
  json['aps'] ||= {}
29
49
  json['aps']['alert'] = @alert if @alert
30
50
  json['aps']['badge'] = @badge.to_i rescue 0 if @badge
31
51
  json['aps']['sound'] = @sound if @sound
52
+ json['aps']['category'] = @category if @category
32
53
  json['aps']['content-available'] = 1 if @content_available
33
54
 
34
55
  json
@@ -59,10 +80,14 @@ module Houston
59
80
  payload.to_json.bytesize <= MAXIMUM_PAYLOAD_SIZE
60
81
  end
61
82
 
83
+ def error
84
+ APNSError.new(APNSError::CODES[@apns_error_code]) if @apns_error_code.nonzero?
85
+ end
86
+
62
87
  private
63
-
88
+
64
89
  def device_token_item
65
- [1, 32, @token.gsub(/[<\s>]/, '')].pack('cnH*')
90
+ [1, 32, @token.gsub(/[<\s>]/, '')].pack('cnH64')
66
91
  end
67
92
 
68
93
  def payload_item
@@ -1,3 +1,3 @@
1
1
  module Houston
2
- VERSION = "2.1.0"
2
+ VERSION = "2.2.0"
3
3
  end
data/spec/client_spec.rb CHANGED
@@ -83,7 +83,7 @@ describe Houston::Client do
83
83
 
84
84
  describe '#unregistered_devices' do
85
85
  it 'should correctly parse the feedback response and create a dictionary of unregistered devices with timestamps' do
86
- subject.unregistered_devices.should == [
86
+ expect(subject.unregistered_devices).to eq [
87
87
  {:token=>"ce8be627 2e43e855 16033e24 b4c28922 0eeda487 9c477160 b2545e95 b68b5969", :timestamp=>443779200},
88
88
  {:token=>"ce8be627 2e43e855 16033e24 b4c28922 0eeda487 9c477160 b2545e95 b68b5970", :timestamp=>1388678223}
89
89
  ]
@@ -92,7 +92,7 @@ describe Houston::Client do
92
92
 
93
93
  describe '#devices' do
94
94
  it 'should correctly parse the feedback response and create an array of unregistered devices' do
95
- subject.devices.should == [
95
+ expect(subject.devices).to eq [
96
96
  "ce8be627 2e43e855 16033e24 b4c28922 0eeda487 9c477160 b2545e95 b68b5969",
97
97
  "ce8be627 2e43e855 16033e24 b4c28922 0eeda487 9c477160 b2545e95 b68b5970"
98
98
  ]
@@ -11,7 +11,6 @@ describe Houston::Notification do
11
11
  id: 42,
12
12
  priority: 10,
13
13
  content_available: true,
14
- # custom data
15
14
  key1: 1,
16
15
  key2: 'abc'
17
16
  }
@@ -56,7 +55,7 @@ describe Houston::Notification do
56
55
 
57
56
  describe '#content_available' do
58
57
  subject { super().content_available }
59
- it { should be_true }
58
+ it { should be_truthy }
60
59
  end
61
60
 
62
61
  describe '#custom_data' do
@@ -86,16 +85,16 @@ describe Houston::Notification do
86
85
  'sound' => 'sosumi.aiff',
87
86
  'content-available' => 1
88
87
  },
89
- :key1 => 1,
90
- :key2 => 'abc'
88
+ 'key1' => 1,
89
+ 'key2' => 'abc'
91
90
  })
92
91
  end
93
92
 
94
93
  it 'should create a dictionary of only custom data and empty aps' do
95
94
  expect(Houston::Notification.new(key1: 123, key2: 'xyz').payload).to eq({
96
95
  'aps' => {},
97
- :key1 => 123,
98
- :key2 => 'xyz'
96
+ 'key1' => 123,
97
+ 'key2' => 'xyz'
99
98
  })
100
99
  end
101
100
 
@@ -129,22 +128,29 @@ describe Houston::Notification do
129
128
  'aps' => { 'loc-key' => 'my-key', 'badge' => 567 }
130
129
  })
131
130
  end
131
+
132
+ it 'should create notification from hash with string and symbol keys' do
133
+ notification_options = { :badge => 567, :aps => { 'loc-key' => 'my-key' } }
134
+ expect(Houston::Notification.new(notification_options).payload['aps']).to eq({
135
+ 'loc-key' => 'my-key', 'badge' => 567
136
+ })
137
+ end
132
138
  end
133
139
 
134
140
  describe '#sent?' do
135
141
  it 'should be false initially' do
136
- expect(subject.sent?).to be_false
142
+ expect(subject.sent?).to be_falsey
137
143
  end
138
144
 
139
145
  it 'should be true after marking as sent' do
140
146
  subject.mark_as_sent!
141
- expect(subject.sent?).to be_true
147
+ expect(subject.sent?).to be_truthy
142
148
  end
143
149
 
144
150
  it 'should be false after marking as unsent' do
145
151
  subject.mark_as_sent!
146
152
  subject.mark_as_unsent!
147
- expect(subject.sent?).to be_false
153
+ expect(subject.sent?).to be_falsey
148
154
  end
149
155
  end
150
156
 
@@ -198,12 +204,19 @@ describe Houston::Notification do
198
204
  expect(items).to include([4, 4, [1234567890].pack('N')])
199
205
  end
200
206
 
201
- it 'should include an item #4 with the priority' do
207
+ it 'should include an item #5 with the priority' do
202
208
  _1, _2, items_stream = subject.message.unpack('cNa*')
203
209
  items = parse_items(items_stream)
204
210
  expect(items).to include([5, 1, [10].pack('c')])
205
211
  end
206
212
 
213
+ it 'should pad or truncate token so it is 32 bytes long' do
214
+ notification_options[:token] = '<ce8be627 2e43e855 16033e24 b4c28922>'
215
+ _1, _2, items_stream = subject.message.unpack('cNa*')
216
+ items = parse_items(items_stream)
217
+ expect(items).to include([1, 32, ['ce8be6272e43e85516033e24b4c2892200000000000000000000000000000000'].pack('H*')])
218
+ end
219
+
207
220
  it 'might be missing the identifier item' do
208
221
  notification_options.delete(:id)
209
222
  notification = Houston::Notification.new(notification_options)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: houston
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mattt Thompson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-12 00:00:00.000000000 Z
11
+ date: 2014-08-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: commander
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - ~>
46
46
  - !ruby/object:Gem::Version
47
- version: '2.0'
47
+ version: '3.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ~>
53
53
  - !ruby/object:Gem::Version
54
- version: '2.0'
54
+ version: '3.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -128,6 +128,30 @@ files:
128
128
  - ./coverage/assets/0.7.1/smoothness/images/ui-icons_454545_256x240.png
129
129
  - ./coverage/assets/0.7.1/smoothness/images/ui-icons_888888_256x240.png
130
130
  - ./coverage/assets/0.7.1/smoothness/images/ui-icons_cd0a0a_256x240.png
131
+ - ./coverage/assets/0.8.0/application.css
132
+ - ./coverage/assets/0.8.0/application.js
133
+ - ./coverage/assets/0.8.0/colorbox/border.png
134
+ - ./coverage/assets/0.8.0/colorbox/controls.png
135
+ - ./coverage/assets/0.8.0/colorbox/loading.gif
136
+ - ./coverage/assets/0.8.0/colorbox/loading_background.png
137
+ - ./coverage/assets/0.8.0/favicon_green.png
138
+ - ./coverage/assets/0.8.0/favicon_red.png
139
+ - ./coverage/assets/0.8.0/favicon_yellow.png
140
+ - ./coverage/assets/0.8.0/loading.gif
141
+ - ./coverage/assets/0.8.0/magnify.png
142
+ - ./coverage/assets/0.8.0/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png
143
+ - ./coverage/assets/0.8.0/smoothness/images/ui-bg_flat_75_ffffff_40x100.png
144
+ - ./coverage/assets/0.8.0/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png
145
+ - ./coverage/assets/0.8.0/smoothness/images/ui-bg_glass_65_ffffff_1x400.png
146
+ - ./coverage/assets/0.8.0/smoothness/images/ui-bg_glass_75_dadada_1x400.png
147
+ - ./coverage/assets/0.8.0/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png
148
+ - ./coverage/assets/0.8.0/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png
149
+ - ./coverage/assets/0.8.0/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png
150
+ - ./coverage/assets/0.8.0/smoothness/images/ui-icons_222222_256x240.png
151
+ - ./coverage/assets/0.8.0/smoothness/images/ui-icons_2e83ff_256x240.png
152
+ - ./coverage/assets/0.8.0/smoothness/images/ui-icons_454545_256x240.png
153
+ - ./coverage/assets/0.8.0/smoothness/images/ui-icons_888888_256x240.png
154
+ - ./coverage/assets/0.8.0/smoothness/images/ui-icons_cd0a0a_256x240.png
131
155
  - ./coverage/index.html
132
156
  - ./Gemfile
133
157
  - ./Gemfile.lock