messagebus_ruby_apn_api 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.rvmrc ADDED
@@ -0,0 +1,2 @@
1
+ rvm use ruby-1.9.2-p180-patched@messagebus_ruby_api --create
2
+
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'activesupport'
4
+
5
+ group :test, :development do
6
+ gem 'rspec', '2.5.0'
7
+ gem 'rr', '1.0.2'
8
+ gem 'fakeweb'
9
+ end
10
+
11
+ # Specify your gem's dependencies in messagebus.gemspec
12
+ gemspec
data/README.rdoc ADDED
@@ -0,0 +1,64 @@
1
+ = Message Bus Ruby APN API
2
+
3
+ == Installation
4
+
5
+ gem install messagebus_ruby_apn_api
6
+
7
+ == Basic Use
8
+
9
+ === Start by requiring MessabusApi:
10
+
11
+ require 'messagebus_ruby_apn_api'
12
+
13
+ === Then create an instance of the Messagebus class with your account information
14
+
15
+ client = MessagebusApnApi::Messagebus.new("<INSERT_YOUR_API_KEY>")
16
+
17
+ === Sending a single notification
18
+
19
+ ==== Create Required Parameters
20
+
21
+ params = { :userName => 'apitest1@messagebus.com',
22
+ :alert => 'Hello push notification world.',
23
+ :platform => Messagebus::PLATFORM_IOS,
24
+ :customFields => {}
25
+ }
26
+
27
+ ==== Send the message
28
+
29
+ client.add_apn_message(params)
30
+
31
+ == Examples
32
+
33
+ The provided examples illustrate how to:
34
+ - send a single notification to a registered device
35
+ - register a device
36
+
37
+ == SSL Certificates
38
+
39
+ If you encounter SSL certificate problems, use the cacert_info() method to specify a
40
+ cacert.pem file (remember to specify the full path).
41
+
42
+ The curl site has an up to date version of the file:
43
+
44
+ http://curl.haxx.se/ca/cacert.pem
45
+
46
+ == Tests
47
+ To run the tests, issue the following command from the root of the project:
48
+ bundle exec rspec spec/messagebus_ruby_apn_api/client_spec.rb
49
+
50
+ == License
51
+ Copyright 2012 Mail Bypass, Inc.
52
+
53
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
54
+ except in compliance with the License. You may obtain a copy of the License at
55
+
56
+ http://www.apache.org/licenses/LICENSE-2.0
57
+
58
+ Unless required by applicable law or agreed to in writing, software distributed under the
59
+ License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
60
+ either express or implied. See the License for the specific language governing permissions
61
+ and limitations under the License.
62
+
63
+ == More info
64
+ Contact Message Bus if you have questions or problems (https://www.messagebus.com/contact)
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,23 @@
1
+ # Copyright 2012 Mail Bypass, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+ # not use this file except in compliance with the License. You may obtain
5
+ # a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+ # License for the specific language governing permissions and limitations
13
+ # under the License.
14
+
15
+ dir = File.dirname(__FILE__)
16
+
17
+ require 'net/https'
18
+ require 'uri'
19
+ require 'cgi'
20
+
21
+ require "#{dir}/messagebus_ruby_apn_api/errors"
22
+ require "#{dir}/messagebus_ruby_apn_api/messagebus"
23
+ require "#{dir}/messagebus_ruby_apn_api/version"
@@ -0,0 +1,37 @@
1
+ # Copyright 2012 Mail Bypass, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+ # not use this file except in compliance with the License. You may obtain
5
+ # a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+ # License for the specific language governing permissions and limitations
13
+ # under the License.
14
+
15
+ module MessagebusApi
16
+
17
+ class APIParameterError < StandardError
18
+ def initialize(problematic_parameter="")
19
+ super("missing or malformed parameter #{problematic_parameter}")
20
+ end
21
+ end
22
+
23
+ class BadAPIKeyError < StandardError
24
+ end
25
+
26
+ class MissingFileError <StandardError
27
+ end
28
+
29
+ class RemoteServerError < StandardError
30
+ attr_reader :result
31
+ def initialize(message, result={})
32
+ super(message)
33
+ @result = result
34
+ end
35
+ end
36
+
37
+ end
@@ -0,0 +1,283 @@
1
+ # Copyright 2012 Mail Bypass, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+ # not use this file except in compliance with the License. You may obtain
5
+ # a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+ # License for the specific language governing permissions and limitations
13
+ # under the License.
14
+ require 'json'
15
+
16
+ require 'json'
17
+
18
+ module MessagebusApnApi
19
+ DEFAULT_API_APN_ENDPOINT_STRING = 'https://apn.messagebus.com'
20
+
21
+ class Messagebus
22
+
23
+ PLATFORM_IOS = 'ios'
24
+ PLATFORM_ANDROID = 'android'
25
+
26
+ attr_writer :send_common_info
27
+
28
+ def initialize(api_key)
29
+ @api_key = api_key
30
+ init_http_connection(domain)
31
+
32
+ @msg_buffer_size = 20
33
+ @msg_buffer = []
34
+ @msg_buffer_flushed = false
35
+
36
+ @register_buffer_size = 20
37
+ @register_buffer = []
38
+ @register_buffer_flushed = false
39
+
40
+ @send_common_info = {}
41
+ @results = base_response_params
42
+ @rest_endpoints = define_rest_endpoints
43
+ @rest_http_errors = define_rest_http_errors
44
+ end
45
+
46
+ def results
47
+ @results
48
+ end
49
+
50
+ def send_buffer_size=(size)
51
+ @msg_buffer_size = size if (size >= 1 && size <= 100)
52
+ end
53
+
54
+ def send_buffer_size
55
+ @msg_buffer_size
56
+ end
57
+
58
+ def send_flushed?
59
+ @msg_buffer_flushed
60
+ end
61
+
62
+ def register_buffer_size=(size)
63
+ @register_buffer_size = size if (size >= 1 && size <= 100)
64
+ end
65
+
66
+ def register_buffer_size
67
+ @register_buffer_size
68
+ end
69
+
70
+ def register_flushed?
71
+ @register_buffer_flushed
72
+ end
73
+
74
+ def api_version
75
+ make_api_get_call(@rest_endpoints[:version])
76
+ end
77
+
78
+ def add_apn_send(params, app_key, flush_buffer = false)
79
+ @msg_buffer << base_apn_send_params.merge!(params)
80
+
81
+ @msg_buffer_flushed = false
82
+ if flush_buffer || @msg_buffer.size >= @msg_buffer_size
83
+ apn_send_flush(app_key)
84
+ end
85
+ return
86
+ end
87
+
88
+ def apn_send_flush(app_key)
89
+ if (@msg_buffer.size==0)
90
+ @results=@empty_send_results
91
+ return
92
+ end
93
+
94
+ endpoint = @rest_endpoints[:apn_send].gsub("%KEY%", app_key)
95
+
96
+ json = json_apn_send_from_list(@msg_buffer)
97
+ if (@last_init_time < Time.now.utc - 60)
98
+ init_http_connection(domain)
99
+ end
100
+ @results=make_api_post_call(endpoint, json)
101
+ @msg_buffer.clear
102
+
103
+ @msg_buffer_flushed = true
104
+ return
105
+ end
106
+
107
+ def add_apn_register(params, app_key, flush_buffer = false)
108
+ @register_buffer << base_apn_register_params.merge!(params)
109
+
110
+ @register_buffer_flushed = false
111
+ if flush_buffer || @register_buffer.size >= @register_buffer_size
112
+ apn_register_flush(app_key)
113
+ end
114
+ return
115
+ end
116
+
117
+ def apn_register_flush(app_key)
118
+ if (@register_buffer.size==0)
119
+ @results=@empty_send_results
120
+ return
121
+ end
122
+
123
+ endpoint = @rest_endpoints[:apn_register].gsub("%KEY%", app_key)
124
+
125
+ json = json_apn_register_from_list(@register_buffer)
126
+ if (@last_init_time < Time.now.utc - 60)
127
+ init_http_connection(domain)
128
+ end
129
+ @results=make_api_post_call(endpoint, json)
130
+ @register_buffer.clear
131
+ @register_buffer_flushed = true
132
+ return
133
+ end
134
+
135
+ def get_apn_apps
136
+ path = @rest_endpoints[:apn_apps]
137
+ @results = make_api_get_call(path)
138
+ @results
139
+ end
140
+
141
+ def cacert_info(cert_file)
142
+ @http.verify_mode = OpenSSL::SSL::VERIFY_PEER
143
+ if !File.exists?(cert_file)
144
+ raise MessagebusApi::MissingFileError.new("Unable to read file #{cert_file}")
145
+ end
146
+ @http.ca_file = File.join(cert_file)
147
+ end
148
+
149
+ private
150
+
151
+ def init_http_connection(target_server)
152
+ if (@http and @http.started?)
153
+ @http.finish
154
+ end
155
+ @last_init_time = Time.now.utc
156
+ endpoint_url = URI.parse(target_server)
157
+ @http = Net::HTTP.new(endpoint_url.host, endpoint_url.port)
158
+ @http.use_ssl = true
159
+ @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
160
+ @http
161
+ end
162
+
163
+ def domain
164
+ DEFAULT_API_APN_ENDPOINT_STRING
165
+ end
166
+
167
+ def common_http_headers
168
+ {'User-Agent' => MessagebusApi::Info.get_user_agent, 'X-MessageBus-Key' => @api_key}
169
+ end
170
+
171
+ def rest_post_headers
172
+ {"Content-Type" => "application/json; charset=utf-8"}
173
+ end
174
+
175
+ def json_apn_send_from_list(messages)
176
+ {:messages => messages}.to_json
177
+ end
178
+
179
+ def json_apn_register_from_list(users)
180
+ {:users => users}.to_json
181
+ end
182
+
183
+ def make_api_post_call(path, data)
184
+ headers = common_http_headers.merge(rest_post_headers)
185
+ response = @http.request_post(path, data, headers)
186
+ check_response(response)
187
+ end
188
+
189
+ def make_api_get_call(path)
190
+ headers = common_http_headers
191
+ response = @http.request_get(path, headers)
192
+ check_response(response)
193
+ end
194
+
195
+ def check_response(response, symbolize_names=true)
196
+ case response
197
+ when Net::HTTPSuccess
198
+ begin
199
+ return JSON.parse(response.body, :symbolize_names => symbolize_names)
200
+ rescue JSON::ParserError => e
201
+ raise MessagebusApi::RemoteServerError.new("JSON parsing error. Response started with #{response.body.slice(0..9)}")
202
+ end
203
+ when Net::HTTPClientError, Net::HTTPServerError
204
+ if (response.body && response.body.size > 0)
205
+ result = begin
206
+ JSON.parse(response.body, :symbolize_names => symbolize_names)
207
+ rescue JSON::ParserError
208
+ nil
209
+ end
210
+ raise MessagebusApi::RemoteServerError.new("#{response.code.to_s}:#{rest_http_error_message(response.code.to_s)}")
211
+ else
212
+ raise MessagebusApi::RemoteServerError.new("#{response.code.to_s}:#{rest_http_error_message(response.code.to_s)}")
213
+ end
214
+ else
215
+ raise "Unexpected HTTP Response: #{response.class.name}"
216
+ end
217
+ raise "Could not determine response"
218
+ end
219
+
220
+ def rest_http_error?(status_code)
221
+ @rest_http_errors.key?(status_code)
222
+ end
223
+
224
+ def rest_http_error_message(status_code)
225
+ message = "Unknown Error Code"
226
+ message = @rest_http_errors[status_code] if rest_http_error?(status_code)
227
+ message
228
+ end
229
+
230
+ def define_rest_endpoints
231
+ {
232
+ :apn_register => "/api/v3/app/%KEY%/register",
233
+ :apn_send => "/api/v3/app/%KEY%/send",
234
+ :apn_apps => "/api/v3/apps",
235
+ :version => "/api/version"
236
+ }
237
+ end
238
+
239
+ def define_rest_http_errors
240
+ {
241
+ "400" => "Invalid Request",
242
+ "401" => "Unauthorized-Missing API Key",
243
+ "403" => "Unauthorized-Invalid API Key",
244
+ "404" => "Incorrect URL",
245
+ "405" => "Method not allowed",
246
+ "406" => "Format not acceptable",
247
+ "408" => "Request Timeout",
248
+ "409" => "Conflict",
249
+ "410" => "Object missing or deleted",
250
+ "413" => "Too many messages in request",
251
+ "415" => "POST JSON data invalid",
252
+ "422" => "Unprocessable Entity",
253
+ "500" => "Internal Server Error",
254
+ "501" => "Not Implemented",
255
+ "503" => "Service Unavailable",
256
+ "507" => "Insufficient Storage"
257
+ }
258
+ end
259
+
260
+ def base_apn_register_params
261
+ {
262
+ :userName => '',
263
+ :deviceToken => '',
264
+ :platform => ''
265
+ }
266
+ end
267
+
268
+ def base_apn_send_params
269
+ {
270
+ :userName => '',
271
+ :alert => '',
272
+ :platform => '',
273
+ :customFields => {}
274
+ }
275
+ end
276
+
277
+ def base_response_params
278
+ {:statusCode => 0,
279
+ :statusMessage => "",
280
+ :statusTime => "1970-01-01T00:00:00.000Z"}
281
+ end
282
+ end
283
+ end
@@ -0,0 +1,27 @@
1
+ # Copyright 2012 Mail Bypass, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+ # not use this file except in compliance with the License. You may obtain
5
+ # a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+ # License for the specific language governing permissions and limitations
13
+ # under the License.
14
+
15
+ module MessagebusApi
16
+ VERSION = "1.0.0"
17
+
18
+ class Info
19
+ @@ClientVersion = MessagebusApi::VERSION
20
+ @@RubyVersion = RUBY_VERSION
21
+ @@UserAgent = "MessagebusAPI:#{@@ClientVersion}-Ruby:#{@@RubyVersion}";
22
+
23
+ def self.get_user_agent
24
+ return @@UserAgent
25
+ end
26
+ end
27
+ end
@@ -0,0 +1 @@
1
+ # THIS IS ONLY FOR TESTING
@@ -0,0 +1,319 @@
1
+ # Copyright 2012 Mail Bypass, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+ # not use this file except in compliance with the License. You may obtain
5
+ # a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+ # License for the specific language governing permissions and limitations
13
+ # under the License.
14
+
15
+
16
+ dir = File.dirname(__FILE__)
17
+ require "#{dir}/../spec_helper"
18
+
19
+ class MessagebusTest < MessagebusApnApi::Messagebus
20
+ attr_accessor :last_init_time
21
+ end
22
+
23
+ describe MessagebusApnApi::Messagebus do
24
+ attr_reader :client, :api_key, :required_params
25
+
26
+
27
+
28
+ def default_apn_send_params
29
+ {
30
+ :userName => 'mark@example.com',
31
+ :alert => 'Message Bus application push',
32
+ :platform => 'ios',
33
+ :customFields => ["badge"=>"23"]
34
+ }
35
+ end
36
+
37
+ def default_apn_register_params
38
+ {
39
+ :userName => 'mark@messagebus.com',
40
+ :deviceToken => '835012e8d4640406818e8c7',
41
+ :platform => 'ios'
42
+ }
43
+ end
44
+
45
+ def create_success_result(num_result)
46
+ list=[]
47
+ num_result.times do
48
+ list << @success_message
49
+ end
50
+
51
+ success_result = {
52
+ "statusMessage" => "OK",
53
+ "successCount" => num_result,
54
+ "failureCount" => 0,
55
+ "results" => list
56
+ }
57
+ success_result
58
+ end
59
+
60
+ def create_results_array
61
+ results = {
62
+ "statusMessage" => "OK",
63
+ "results" => []
64
+ }
65
+ results
66
+ end
67
+
68
+ def json_parse(data)
69
+ JSON.parse(data, :symbolize_names => true)
70
+ end
71
+
72
+ before do
73
+ FakeWeb.allow_net_connect = false
74
+
75
+ @app_key = 'test_key'
76
+ @api_key = "7215ee9c7d9dc229d2921a40e899ec5f"
77
+ @client = MessagebusTest.new(@api_key)
78
+ @success_message={
79
+ "status" => 200,
80
+ "messageId" => "abcdefghijklmnopqrstuvwxyz012345"
81
+ }
82
+ @simple_success_result = create_success_result(1)
83
+ @apn_endpoint = "https://apn.messagebus.com/api/v3/"
84
+ end
85
+
86
+ describe "messagebus object set up correctly" do
87
+ it "has correct headers set for api calls" do
88
+ client = MessagebusApnApi::Messagebus.new(@api_key)
89
+ end
90
+ end
91
+
92
+ describe "add cacert file to http communications" do
93
+ it "raises error if cert file does not exist" do
94
+ client = MessagebusApnApi::Messagebus.new(@api_key)
95
+ cert_file_path = File.join(File.dirname(__FILE__), "nofile.pem")
96
+ expect do
97
+ client.cacert_info(cert_file_path)
98
+ end.should raise_error
99
+ end
100
+
101
+ it "accepts a cert file that exists" do
102
+ client = MessagebusApnApi::Messagebus.new(@api_key)
103
+ cert_file_path = File.join(File.dirname(__FILE__), "cacert.pem")
104
+ expect do
105
+ client.cacert_info(cert_file_path)
106
+ end.should_not raise_error
107
+ end
108
+ end
109
+
110
+ describe "#add_apn_send" do
111
+ it "buffered send that adds to empty buffer" do
112
+ client.add_apn_send(default_apn_send_params, @app_key)
113
+ client.send_flushed?.should be_false
114
+ end
115
+ it "buffered send that adds to empty buffer and sends with flush_buffer flag" do
116
+ expected_request="#{@apn_endpoint}app/#{@app_key}/send"
117
+ FakeWeb.register_uri(:post, expected_request, :body => json_valid_apn_send)
118
+ client.add_apn_send(default_apn_send_params, @app_key, true)
119
+ client.send_flushed?.should be_true
120
+ end
121
+ it "should have user-agent and x-messagebus-key set in request headers" do
122
+ FakeWeb.register_uri(:post, "#{@apn_endpoint}app/#{@app_key}/send", :body => json_valid_apn_send)
123
+ client.add_apn_send(default_apn_send_params, @app_key, true)
124
+ client.send_flushed?.should be_true
125
+
126
+ FakeWeb.last_request.get_fields("X-MessageBus-Key").should_not be_nil
127
+ FakeWeb.last_request.get_fields("User-Agent").should_not be_nil
128
+ FakeWeb.last_request.get_fields("Content-Type").should_not be_nil
129
+ end
130
+ it "buffered send that adds to a buffer and auto-flushes" do
131
+ FakeWeb.register_uri(:post, "#{@apn_endpoint}app/#{@app_key}/send", :body => create_success_result(client.send_buffer_size).to_json)
132
+ (client.send_buffer_size-1).times do |idx|
133
+ client.add_apn_send(default_apn_send_params, @app_key)
134
+ client.send_flushed?.should be_false
135
+ end
136
+ client.add_apn_send(default_apn_send_params, @app_key)
137
+ client.send_flushed?.should be_true
138
+ client.results[:results].size.should == client.send_buffer_size
139
+
140
+ end
141
+ end
142
+
143
+ describe "#apn_app_register" do
144
+ it "buffered register that adds to empty buffer" do
145
+ client.add_apn_register(default_apn_register_params, @app_key)
146
+ client.register_flushed?.should be_false
147
+ end
148
+ it "buffered register that adds to empty buffer and registers with flush_buffer flag" do
149
+ FakeWeb.register_uri(:post, "#{@apn_endpoint}app/#{@app_key}/register", :body => json_valid_apn_register)
150
+ client.add_apn_register(default_apn_register_params, @app_key, true)
151
+ client.register_flushed?.should be_true
152
+ end
153
+ it "should have user-agent and x-messagebus-key set in request headers" do
154
+ FakeWeb.register_uri(:post, "#{@apn_endpoint}app/#{@app_key}/register", :body => json_valid_apn_register)
155
+ client.add_apn_register(default_apn_register_params, @app_key, true)
156
+ client.register_flushed?.should be_true
157
+
158
+ FakeWeb.last_request.get_fields("X-MessageBus-Key").should_not be_nil
159
+ FakeWeb.last_request.get_fields("User-Agent").should_not be_nil
160
+ FakeWeb.last_request.get_fields("Content-Type").should_not be_nil
161
+ end
162
+ it "buffered register that adds to a buffer and auto-flushes" do
163
+ FakeWeb.register_uri(:post, "#{@apn_endpoint}app/#{@app_key}/register", :body => create_success_result(client.register_buffer_size).to_json)
164
+ (client.send_buffer_size-1).times do |idx|
165
+ client.add_apn_register(default_apn_register_params, @app_key)
166
+ client.register_flushed?.should be_false
167
+ end
168
+ client.add_apn_register(default_apn_register_params, @app_key)
169
+ client.register_flushed?.should be_true
170
+ client.results[:results].size.should == client.register_buffer_size
171
+ end
172
+ end
173
+
174
+ describe "#apn_send_flush" do
175
+ it "apn send flush called on empty buffer" do
176
+ client.apn_send_flush(@app_key)
177
+ client.send_flushed?.should be_false
178
+ end
179
+
180
+ it "apn send flush called on partially filled buffer" do
181
+ message_count = 9
182
+ FakeWeb.register_uri(:post, "#{@apn_endpoint}app/#{@app_key}/send", :body => create_success_result(message_count).to_json)
183
+ (message_count).times do |idx|
184
+ client.add_apn_send(default_apn_send_params, @app_key)
185
+ client.send_flushed?.should be_false
186
+ end
187
+ client.apn_send_flush(@app_key)
188
+ client.send_flushed?.should be_true
189
+ client.results[:results].size.should == message_count
190
+ end
191
+
192
+ it "doesnt reset connection if under a minute old" do
193
+ current_init_time=client.last_init_time
194
+ current_init_time.should be > Time.now.utc-5
195
+ FakeWeb.register_uri(:post, "#{@apn_endpoint}app/#{@app_key}/send", :body => create_success_result(1).to_json)
196
+ client.add_apn_send(default_apn_send_params, @app_key)
197
+ client.apn_send_flush(@app_key)
198
+ client.send_flushed?.should be_true
199
+ client.results[:results].size.should == 1
200
+ client.last_init_time.should == current_init_time
201
+ end
202
+
203
+ it "resets connection if over a minute old" do
204
+ client.last_init_time=Time.now.utc-60
205
+ current_init_time=client.last_init_time
206
+ current_init_time.should be < Time.now.utc-59
207
+ FakeWeb.register_uri(:post, "#{@apn_endpoint}app/#{@app_key}/send", :body => create_success_result(1).to_json)
208
+ client.add_apn_send(default_apn_send_params, @app_key)
209
+ client.apn_send_flush(@app_key)
210
+ client.send_flushed?.should be_true
211
+ client.results[:results].size.should == 1
212
+ client.last_init_time.should be > current_init_time
213
+ end
214
+ end
215
+
216
+ describe "#send_buffer_size=" do
217
+ it "can set the buffer size" do
218
+ client.send_buffer_size=(10)
219
+ client.send_buffer_size.should == 10
220
+ end
221
+
222
+ it "cannot set an invalid buffer size" do
223
+ default_buffer_size = 20
224
+ client.send_buffer_size=(-1)
225
+ client.send_buffer_size.should == default_buffer_size
226
+
227
+ client.send_buffer_size=(0)
228
+ client.send_buffer_size.should == default_buffer_size
229
+
230
+ client.send_buffer_size=(101)
231
+ client.send_buffer_size.should == default_buffer_size
232
+
233
+ client.send_buffer_size=(1)
234
+ client.send_buffer_size.should == 1
235
+
236
+ client.send_buffer_size=(100)
237
+ client.send_buffer_size.should == 100
238
+ end
239
+ end
240
+
241
+ describe "#apn_register_flush" do
242
+ it "apn register flush called on empty buffer" do
243
+ client.apn_register_flush(@app_key)
244
+ client.register_flushed?.should be_false
245
+ end
246
+
247
+ it "apn register flush called on partially filled buffer" do
248
+ message_count = 9
249
+ FakeWeb.register_uri(:post, "#{@apn_endpoint}app/#{@app_key}/register", :body => create_success_result(message_count).to_json)
250
+ (message_count).times do |idx|
251
+ client.add_apn_register(default_apn_register_params, @app_key)
252
+ client.register_flushed?.should be_false
253
+ end
254
+ client.apn_register_flush(@app_key)
255
+ client.register_flushed?.should be_true
256
+ client.results[:results].size.should == message_count
257
+ end
258
+
259
+ it "doesnt reset connection if under a minute old" do
260
+ current_init_time=client.last_init_time
261
+ current_init_time.should be > Time.now.utc-5
262
+ FakeWeb.register_uri(:post, "#{@apn_endpoint}app/#{@app_key}/register", :body => create_success_result(1).to_json)
263
+ client.add_apn_register(default_apn_register_params, @app_key)
264
+ client.apn_register_flush(@app_key)
265
+ client.register_flushed?.should be_true
266
+ client.results[:results].size.should == 1
267
+ client.last_init_time.should == current_init_time
268
+ end
269
+
270
+ it "resets connection if over a minute old" do
271
+ client.last_init_time=Time.now.utc-60
272
+ current_init_time=client.last_init_time
273
+ current_init_time.should be < Time.now.utc-59
274
+ FakeWeb.register_uri(:post, "#{@apn_endpoint}app/#{@app_key}/register", :body => create_success_result(1).to_json)
275
+ client.add_apn_register(default_apn_register_params, @app_key)
276
+ client.apn_register_flush(@app_key)
277
+ client.register_flushed?.should be_true
278
+ client.results[:results].size.should == 1
279
+ client.last_init_time.should be > current_init_time
280
+ end
281
+ end
282
+
283
+ describe "#register_buffer_size=" do
284
+ it "can set the buffer size" do
285
+ client.register_buffer_size=(10)
286
+ client.register_buffer_size.should == 10
287
+ end
288
+
289
+ it "cannot set an invalid buffer size" do
290
+ default_buffer_size = 20
291
+ client.register_buffer_size=(-1)
292
+ client.register_buffer_size.should == default_buffer_size
293
+
294
+ client.register_buffer_size=(0)
295
+ client.register_buffer_size.should == default_buffer_size
296
+
297
+ client.register_buffer_size=(101)
298
+ client.register_buffer_size.should == default_buffer_size
299
+
300
+ client.register_buffer_size=(1)
301
+ client.register_buffer_size.should == 1
302
+
303
+ client.register_buffer_size=(100)
304
+ client.register_buffer_size.should == 100
305
+ end
306
+ end
307
+
308
+
309
+ describe "#get_apn_apps" do
310
+ it "can return a list of apps with name and app key" do
311
+ FakeWeb.register_uri(:get, "#{@apn_endpoint}apps", :body => json_valid_apn_apps)
312
+ expect do
313
+ response = client.get_apn_apps
314
+ FakeWeb.last_request.body.should be_nil
315
+ response.should == json_parse(json_valid_apn_apps)
316
+ end.should_not raise_error
317
+ end
318
+ end
319
+ end
@@ -0,0 +1,19 @@
1
+ # Copyright 2012 Mail Bypass, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+ # not use this file except in compliance with the License. You may obtain
5
+ # a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+ # License for the specific language governing permissions and limitations
13
+ # under the License.
14
+
15
+ class Hash
16
+ def without(key)
17
+ self.dup.tap{|hash| hash.delete(key)}
18
+ end
19
+ end
@@ -0,0 +1,42 @@
1
+ # Copyright 2012 Mail Bypass, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+ # not use this file except in compliance with the License. You may obtain
5
+ # a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+ # License for the specific language governing permissions and limitations
13
+ # under the License.
14
+
15
+ dir = File.dirname(__FILE__)
16
+
17
+ require 'rubygems'
18
+ require 'fakeweb'
19
+ require 'rr'
20
+ require 'json'
21
+
22
+ require "#{dir}/spec_core_extensions"
23
+ require "#{dir}/../lib/messagebus_ruby_apn_api"
24
+
25
+ def json_valid_apn_send
26
+ json = <<JAVASCRIPT
27
+ {"statusCode":202,"statusMessage":"","statusTime":"2011-09-19T22:40:45.123Z","successCount":1,"failureCount":0,"results":[{"userName":"mark@messagebus.com","registrationStatus":"0"}]}
28
+ JAVASCRIPT
29
+ json
30
+ end
31
+
32
+ def json_valid_apn_register
33
+ json = <<JAVASCRIPT
34
+ {"statusCode":202,"statusMessage":"","statusTime":"2011-09-19T22:40:45.123Z","successCount":1,"failureCount":0,"results":[{"userName":"mark@messagebus.com","platform":"ios","messageStatus":0}]}
35
+ JAVASCRIPT
36
+ end
37
+
38
+ def json_valid_apn_apps
39
+ json = <<JAVASCRIPT
40
+ {"statusCode":202, "statusMessage":"", "statusTime":"2011-09-19T22:40:45.123Z","results":[{"appName":"Sample App","appKey":"<app key>"}]}
41
+ JAVASCRIPT
42
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: messagebus_ruby_apn_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Message Bus dev team
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-02 00:00:00.000000000Z
13
+ dependencies: []
14
+ description: ! 'Allows you to use the Message Bus API '
15
+ email:
16
+ - messagebus@googlegroups.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - lib/messagebus_ruby_apn_api/errors.rb
22
+ - lib/messagebus_ruby_apn_api/messagebus.rb
23
+ - lib/messagebus_ruby_apn_api/version.rb
24
+ - lib/messagebus_ruby_apn_api.rb
25
+ - spec/messagebus_ruby_apn_api/cacert.pem
26
+ - spec/messagebus_ruby_apn_api/messagebus_spec.rb
27
+ - spec/spec_core_extensions.rb
28
+ - spec/spec_helper.rb
29
+ - README.rdoc
30
+ - Gemfile
31
+ - Rakefile
32
+ - .rvmrc
33
+ homepage: ''
34
+ licenses:
35
+ - APACHE2
36
+ post_install_message:
37
+ rdoc_options: []
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ! '>='
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ requirements: []
53
+ rubyforge_project: messagebus_ruby_apn_api
54
+ rubygems_version: 1.8.15
55
+ signing_key:
56
+ specification_version: 3
57
+ summary: Send application push notifications through the Message Bus service
58
+ test_files:
59
+ - spec/messagebus_ruby_apn_api/cacert.pem
60
+ - spec/messagebus_ruby_apn_api/messagebus_spec.rb
61
+ - spec/spec_core_extensions.rb
62
+ - spec/spec_helper.rb