messagebus_ruby_apn_api 1.0.0
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.
- data/.rvmrc +2 -0
- data/Gemfile +12 -0
- data/README.rdoc +64 -0
- data/Rakefile +2 -0
- data/lib/messagebus_ruby_apn_api.rb +23 -0
- data/lib/messagebus_ruby_apn_api/errors.rb +37 -0
- data/lib/messagebus_ruby_apn_api/messagebus.rb +283 -0
- data/lib/messagebus_ruby_apn_api/version.rb +27 -0
- data/spec/messagebus_ruby_apn_api/cacert.pem +1 -0
- data/spec/messagebus_ruby_apn_api/messagebus_spec.rb +319 -0
- data/spec/spec_core_extensions.rb +19 -0
- data/spec/spec_helper.rb +42 -0
- metadata +62 -0
data/.rvmrc
ADDED
data/Gemfile
ADDED
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,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
|
data/spec/spec_helper.rb
ADDED
@@ -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
|