five_mobile_push 0.4.6 → 0.4.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -15,6 +15,7 @@ module FiveMobilePush
15
15
  class GeneralError < StandardError; end
16
16
  class ServerError < StandardError; end
17
17
  class InvalidPlatformError < StandardError; end
18
+ class InvalidToken < StandardError; end
18
19
 
19
20
  DEFAULT_ID_TYPE = 'native'
20
21
 
@@ -1,4 +1,3 @@
1
- require 'uri'
2
1
  require 'faraday'
3
2
 
4
3
  module FiveMobilePush
@@ -10,7 +9,7 @@ module FiveMobilePush
10
9
 
11
10
  def initialize(options={})
12
11
  self.application_uid = options[:application_uid] || FiveMobilePush.application_uid
13
- self.api_token = options[:api_token] || FiveMobilePush.api_token
12
+ self.api_token = options[:api_token] || FiveMobilePush.api_token
14
13
  end
15
14
 
16
15
  def get(path, options={})
@@ -21,31 +20,38 @@ module FiveMobilePush
21
20
  perform_request(:post, path, options)
22
21
  end
23
22
 
24
- def device(device_uid)
25
- FiveMobilePush::Device.new(self, device_uid)
23
+ def device(device_uid, device_token=nil)
24
+ FiveMobilePush::Device.new(self, device_uid, device_token)
26
25
  end
27
26
 
28
27
  def notifier
29
28
  FiveMobilePush::Notifier.new(self)
30
29
  end
31
30
 
32
- def tag(device_uid)
33
- FiveMobilePush::Tag.new(self, device_uid)
31
+ def tag(device_uid, device_token)
32
+ FiveMobilePush::Tag.new(self, device_uid, device_token)
34
33
  end
35
34
 
36
35
  private
37
36
 
38
37
  def perform_request(method, path, options={})
39
- options.merge!({:api_token => self.api_token, :application_id => self.application_uid })
40
-
41
- uri = [DEFAULT_ENDPOINT, path].join('/')
38
+ options.merge!(
39
+ :api_token => options[:api_token] || api_token,
40
+ :application_id => application_uid
41
+ )
42
+
43
+ conn = Faraday.new(:url => DEFAULT_ENDPOINT)
44
+ resp = conn.send(method) do |req|
45
+ req.url path, options
46
+ end
42
47
 
43
- case method
44
- when :get
45
- Faraday.get(uri, options)
46
- when :post
47
- Faraday.post(uri, options)
48
+ # TODO Add error processor here.
49
+ # Basic error checking
50
+ if resp.status == 400
51
+ raise InvalidToken if resp.body =~ /Invalid API token/i
48
52
  end
53
+
54
+ resp
49
55
  end
50
56
  end
51
57
  end
@@ -3,15 +3,16 @@ module FiveMobilePush
3
3
 
4
4
  VALID_OPTION_KEYS = [:alias, :email]
5
5
 
6
- attr_reader :device_uid
6
+ attr_reader :uid, :token
7
7
 
8
8
  # @param [FiveMobilePush::Client] client The Client to use to send this request
9
9
  #
10
- # @param [String] device_uid The ID of the device being registered.
10
+ # @param [String] uid The ID of the device being registered.
11
11
  # Maximum of 64 characters.
12
- def initialize(client, device_uid)
13
- @client = client
14
- @device_uid = device_uid
12
+ def initialize(client, uid, token=nil)
13
+ @client = client
14
+ @uid = uid
15
+ @token = token
15
16
  end
16
17
 
17
18
  # Registers a device for receiving push notifications from an application.
@@ -34,29 +35,43 @@ module FiveMobilePush
34
35
  # @option device_info [String] :platform_ver Software platform version.
35
36
  #
36
37
  # @return [Hash] Has unique device API key. Required for many other calls.
37
- def register(device_info, registration_data=nil)
38
+ def register(info, registration_data=nil)
38
39
  options = {
39
- :device_id => @device_uid,
40
- :device_info => MultiJson.encode(device_info)
40
+ :device_id => @uid,
41
+ :device_info => MultiJson.encode(info)
41
42
  }
42
43
 
43
44
  options[:reg_data] = registration_data unless registration_data.nil?
44
45
  response = @client.post 'device/register', options
45
- MultiJson.decode(response.body)
46
+
47
+ if response.headers['content-type'] =~ /json/i
48
+ MultiJson.decode(response.body)
49
+ else
50
+ response.body
51
+ end
46
52
  end
47
53
 
48
54
  def resume
49
- @client.post 'device/resume', :id_type => FiveMobilePush::DEFAULT_ID_TYPE, :id_value => @device_uid
55
+ client_operation 'device/resume'
50
56
  end
51
57
 
52
58
  def suspend
53
- @client.post 'device/suspend', :id_type => FiveMobilePush::DEFAULT_ID_TYPE, :id_value => @device_uid
59
+ client_operation 'device/suspend'
54
60
  end
55
61
 
56
62
  def unregister
57
- @client.post 'device/unregister', :id_type => FiveMobilePush::DEFAULT_ID_TYPE, :id_value => @device_uid
63
+ client_operation 'device/unregister'
58
64
  end
59
65
 
66
+ private
67
+
68
+ def client_operation(method)
69
+ @client.post method,
70
+ :id_type => FiveMobilePush::DEFAULT_ID_TYPE,
71
+ :id_value => @uid,
72
+ :api_token => token
73
+ end
74
+
60
75
  end
61
76
 
62
77
  end
@@ -1,19 +1,42 @@
1
1
  module FiveMobilePush
2
2
  class Tag
3
+ attr_reader :client
3
4
 
4
- attr_accessor :device_uid
5
+ attr_accessor :device_uid, :device_token
5
6
 
6
- def initialize(client, device_uid)
7
- @client = client
8
- self.device_uid = device_uid
7
+ def initialize(client, device_uid, device_token)
8
+ @client = client
9
+ self.device_uid = device_uid
10
+ self.device_token = device_token
9
11
  end
10
-
12
+
11
13
  def create(*tags)
12
- @client.post(end_point(:add), :id_type => FiveMobilePush::DEFAULT_ID_TYPE, :id_value => self.device_uid, :tags => normalize_tags(tags))
14
+ client.post end_point(:add),
15
+ :id_type => FiveMobilePush::DEFAULT_ID_TYPE,
16
+ :id_value => device_uid,
17
+ :tags => normalize_tags(tags),
18
+ :api_token => device_token
13
19
  end
14
20
 
15
21
  def delete(*tags)
16
- @client.post(end_point(:delete), :id_type => FiveMobilePush::DEFAULT_ID_TYPE, :id_value => self.device_uid, :tags => normalize_tags(tags))
22
+ client.post end_point(:delete),
23
+ :id_type => FiveMobilePush::DEFAULT_ID_TYPE,
24
+ :id_value => device_uid,
25
+ :tags => normalize_tags(tags),
26
+ :api_token => device_token
27
+ end
28
+
29
+ def get
30
+ response = client.get end_point(:get),
31
+ :id_type => FiveMobilePush::DEFAULT_ID_TYPE,
32
+ :id_value => device_uid,
33
+ :api_token => device_token
34
+
35
+ if response.headers['content-type'] =~ /json/i
36
+ MultiJson.decode(response.body)
37
+ else
38
+ response.body
39
+ end
17
40
  end
18
41
 
19
42
  private
@@ -25,6 +48,5 @@ module FiveMobilePush
25
48
  def end_point(action)
26
49
  "device/tags/#{action}"
27
50
  end
28
-
29
51
  end
30
52
  end
@@ -1,3 +1,3 @@
1
1
  module FiveMobilePush
2
- VERSION = "0.4.6"
2
+ VERSION = "0.4.7"
3
3
  end
@@ -5,8 +5,12 @@ FiveMobilePush.configure do |config|
5
5
  config.application_uid = ''
6
6
  end
7
7
 
8
+ FakeDevice = Struct.new(:id, :uid, :token) unless defined?(FakeDevice)
9
+
8
10
  describe FiveMobilePush::Client do
9
- let(:device) { double('Device', id: 12345, uid: 'abcdef') }
11
+ subject { described_class.new }
12
+
13
+ let(:device) { FakeDevice.new(12345, 'abcdef') }
10
14
 
11
15
  let(:device_info) {
12
16
  {
@@ -19,11 +23,168 @@ describe FiveMobilePush::Client do
19
23
 
20
24
  let(:reg_data) { 'cafebabe' }
21
25
 
22
- subject { described_class.new }
23
-
24
- it "register device" do
25
- expect {
26
- subject.device(device.uid).register(device_info, reg_data)
27
- }.to_not raise_error
26
+ # Registers the device on the service, sets its token, and returns the response
27
+ def register_device(device, args={})
28
+ device_info.merge!(args)
29
+ response = subject.device(device.uid).register(device_info, reg_data)
30
+ device.token = response['data']
31
+ response
32
+ end
33
+
34
+ # Unregisters the device
35
+ def unregister_device(device)
36
+ subject.device(device.uid, device.token).unregister
37
+ end
38
+
39
+ context 'device end points' do
40
+ context 'valid device registration' do
41
+ after(:each) do
42
+ unregister_device(device)
43
+ end
44
+
45
+ it 'registers the device device' do
46
+ expect {
47
+ register_device(device)
48
+ }.to_not raise_error
49
+ end
50
+
51
+ it 'receives a device token' do
52
+ response = register_device(device)
53
+ response['data'].should_not be_nil
54
+ response['type'].should == 'api_token'
55
+ end
56
+ end
57
+
58
+ context 'attempt to register device with invalid info' do
59
+ it 'invalid device manufacturer' do
60
+ response = register_device(device, 'manufacturer' => 'jello')
61
+ response.should include('data')
62
+ end
63
+
64
+ it 'invalid device model' do
65
+ response = register_device(device, 'model' => '###F#F23f23f!@!@xyz')
66
+ response.should include('data')
67
+ end
68
+
69
+ it 'invalid device platform' do
70
+ response = register_device(device, 'platform' => 'xyz')
71
+ response.should =~ /Unrecognized platform/
72
+ end
73
+
74
+ it 'invalid device platform_ver' do
75
+ response = register_device(device, 'platform_ver' => '###F#F23f23f!@!@xyz')
76
+ response.should include('data')
77
+ end
78
+ end
79
+
80
+ context 'unregistration' do
81
+ before(:each) do
82
+ register_device(device)
83
+ end
84
+
85
+ it 'is successful for a valid device' do
86
+ resp = unregister_device(device)
87
+ resp.status.should == 200
88
+ resp.body.should == ''
89
+ end
90
+
91
+ it 'raises an InvalidToken exception for an invalid device' do
92
+ unregister_device(device) # Once to clean up...
93
+
94
+ expect {
95
+ unregister_device(device) # Again to cause an error...
96
+ }.to raise_error(FiveMobilePush::InvalidToken)
97
+ end
98
+ end
99
+
100
+ context 'with a valid device' do
101
+ before(:each) do
102
+ register_device(device)
103
+ end
104
+
105
+ after(:each) do
106
+ unregister_device(device)
107
+ end
108
+
109
+ it 'suspends a device' do
110
+ resp = subject.device(device.uid, device.token).suspend
111
+ resp.status.should == 200
112
+ resp.body.should == ''
113
+ end
114
+
115
+ it 'suspends with an invalid token' do
116
+ expect {
117
+ subject.device(device.uid, 'wooohoo').suspend
118
+ }.to raise_error(FiveMobilePush::InvalidToken)
119
+ end
120
+
121
+ it 'resumes a subscription' do
122
+ resp = subject.device(device.uid, device.token).resume
123
+ resp.status.should == 200
124
+ resp.body.should == ''
125
+ end
126
+ end
127
+ end
128
+
129
+ context 'notification end points' do
130
+ let(:notifier) { subject.notifier }
131
+
132
+ it "broadcasts a message to all platforms" do
133
+ resp = notifier.broadcast(FiveMobilePush::Platform::ALL) do |message|
134
+ message.body "Heyyo it's an rspec party"
135
+ end
136
+
137
+ resp.status.should == 200
138
+ end
139
+
140
+ it "send a message to a faulty device" do
141
+ resp = notifier.notify_devices(['no-one']) do |message|
142
+ message.body "No one should get this"
143
+ end
144
+
145
+ resp.status.should == 200
146
+ end
147
+
148
+ it "send a message to devices tagged" do
149
+ resp = notifier.notify_by_tags(FiveMobilePush::Platform::ALL, ['mmmm', 'bacon']) do |message|
150
+ message.body "eat your bacon"
151
+ end
152
+
153
+ resp.status.should == 200
154
+ end
155
+ end
156
+
157
+ context "tag end points" do
158
+ let(:tag1) { 'toronto' }
159
+
160
+ let(:tag2) { 'summer' }
161
+
162
+ let(:tags) { [tag1, tag2] }
163
+
164
+ before(:each) do
165
+ register_device(device)
166
+ end
167
+
168
+ after(:each) do
169
+ unregister_device(device)
170
+ end
171
+
172
+ it "create a tag" do
173
+ resp = subject.tag(device.uid, device.token).create(tags)
174
+ resp.body.should == ''
175
+ resp.status.should == 200
176
+ end
177
+
178
+ it "delete a tag" do
179
+ resp = subject.tag(device.uid, device.token).delete(tag2)
180
+ resp.body.should == ''
181
+ resp.status.should == 200
182
+ end
183
+
184
+ it "get a device's tags" do
185
+ subject.tag(device.uid, device.token).create(tags)
186
+ resp = subject.tag(device.uid, device.token).get
187
+ resp.should == tags
188
+ end
28
189
  end
29
190
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: five_mobile_push
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.4.6
5
+ version: 0.4.7
6
6
  platform: ruby
7
7
  authors:
8
8
  - Kevin Faustino
@@ -11,7 +11,7 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2011-07-05 00:00:00 Z
14
+ date: 2011-07-06 00:00:00 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: multi_json