realpush 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rspec +2 -0
- data/.travis.yml +21 -0
- data/Gemfile +4 -0
- data/Guardfile +77 -0
- data/LICENSE +21 -0
- data/README.md +24 -0
- data/Rakefile +2 -0
- data/lib/realpush.rb +55 -0
- data/lib/realpush/api/app.rb +11 -0
- data/lib/realpush/api/base.rb +155 -0
- data/lib/realpush/api/base_create.rb +21 -0
- data/lib/realpush/api/base_destroy.rb +22 -0
- data/lib/realpush/api/base_list.rb +22 -0
- data/lib/realpush/api/base_update.rb +21 -0
- data/lib/realpush/client.rb +188 -0
- data/lib/realpush/request.rb +89 -0
- data/lib/realpush/resource.rb +36 -0
- data/lib/realpush/version.rb +6 -0
- data/realpush.gemspec +39 -0
- data/spec/realpush/api/app_spec.rb +182 -0
- data/spec/realpush/client_spec.rb +146 -0
- data/spec/realpush/request_spec.rb +52 -0
- data/spec/spec_helper.rb +27 -0
- metadata +288 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
module RealPush
|
2
|
+
module API
|
3
|
+
module BaseList
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def self.included(base)
|
7
|
+
base.class_eval do
|
8
|
+
def list
|
9
|
+
content = execute :get, url("#{self.class.params[:base_path]}.json")
|
10
|
+
parse_content content
|
11
|
+
rescue RealPush::HTTPError => e
|
12
|
+
{
|
13
|
+
status: :ERROR,
|
14
|
+
message: e.message
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module RealPush
|
2
|
+
module API
|
3
|
+
module BaseUpdate
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def self.included(base)
|
7
|
+
base.class_eval do
|
8
|
+
def update(id, data)
|
9
|
+
valid_params? data
|
10
|
+
content = execute :patch, url("#{self.class.params[:base_path]}/#{id}.json"), {}, data
|
11
|
+
parse_content content
|
12
|
+
rescue RealPush::HTTPError,
|
13
|
+
RealPush::ConfigurationError => e
|
14
|
+
raise RealPush::ConfigurationError, e.message
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
require 'signature'
|
2
|
+
require 'multi_json'
|
3
|
+
|
4
|
+
module RealPush
|
5
|
+
|
6
|
+
class Client
|
7
|
+
|
8
|
+
attr_accessor :scheme, :app_id, :privatekey, :hostname, :port
|
9
|
+
attr_writer :connect_timeout, :send_timeout, :receive_timeout,
|
10
|
+
:keep_alive_timeout
|
11
|
+
|
12
|
+
def initialize(options={})
|
13
|
+
options = {
|
14
|
+
port: 443,
|
15
|
+
scheme: 'http',
|
16
|
+
hostname: '127.0.0.1',
|
17
|
+
app_id: nil,
|
18
|
+
privatekey: nil
|
19
|
+
}.merge options
|
20
|
+
|
21
|
+
@encrypted = false
|
22
|
+
|
23
|
+
@scheme, @app_id, @privatekey, @hostname, @port = options.values_at(
|
24
|
+
:scheme, :app_id, :privatekey, :hostname, :port
|
25
|
+
)
|
26
|
+
|
27
|
+
# Default timeouts
|
28
|
+
@connect_timeout = 5
|
29
|
+
@send_timeout = 5
|
30
|
+
@receive_timeout = 5
|
31
|
+
@keep_alive_timeout = 30
|
32
|
+
end
|
33
|
+
|
34
|
+
def authenticate(publickey, privatekey)
|
35
|
+
@app_id, @privatekey = publickey, privatekey
|
36
|
+
end
|
37
|
+
|
38
|
+
# Generate the expected response for an authentication endpoint.
|
39
|
+
#
|
40
|
+
# @example Private channels
|
41
|
+
# render :json => RealPush.default_client.authenticate(params[:realpush])
|
42
|
+
#
|
43
|
+
# @param custom_string [String | Hash]
|
44
|
+
#
|
45
|
+
# @return [Hash]
|
46
|
+
def authentication_string(custom_string=nil)
|
47
|
+
custom_string = MultiJson.encode(custom_string) if custom_string.kind_of?(Hash)
|
48
|
+
unless custom_string.nil? || custom_string.kind_of?(String)
|
49
|
+
raise Error, 'Custom argument must be a string'
|
50
|
+
end
|
51
|
+
|
52
|
+
string_to_sign = [app_id, custom_string].compact.map(&:to_s).join(':')
|
53
|
+
digest = OpenSSL::Digest::SHA256.new
|
54
|
+
signature = OpenSSL::HMAC.hexdigest(digest, privatekey, string_to_sign)
|
55
|
+
{auth:signature}
|
56
|
+
end
|
57
|
+
|
58
|
+
# @private Returns the authentication token for the client
|
59
|
+
def authentication_token
|
60
|
+
Signature::Token.new(app_id, privatekey)
|
61
|
+
end
|
62
|
+
|
63
|
+
def config(&block)
|
64
|
+
raise ConfigurationError, 'You need a block' unless block_given?
|
65
|
+
yield self
|
66
|
+
end
|
67
|
+
|
68
|
+
def encrypted=(bool)
|
69
|
+
@scheme = bool ? 'https' : 'http'
|
70
|
+
# Configure port if it hasn't already been configured
|
71
|
+
@port = bool ? 443 : 80
|
72
|
+
end
|
73
|
+
|
74
|
+
def encrypted?
|
75
|
+
scheme == 'https'
|
76
|
+
end
|
77
|
+
|
78
|
+
def get(path, params)
|
79
|
+
Resource.new(self, "/#{app_id}#{path}").get params
|
80
|
+
end
|
81
|
+
|
82
|
+
def get_async(path, params)
|
83
|
+
Resource.new(self, "/#{app_id}#{path}").get_async params
|
84
|
+
end
|
85
|
+
|
86
|
+
def post(path, body)
|
87
|
+
Resource.new(self, "/#{app_id}#{path}").post body
|
88
|
+
end
|
89
|
+
|
90
|
+
def post_async(path, body)
|
91
|
+
Resource.new(self, "/#{app_id}#{path}").post_async body
|
92
|
+
end
|
93
|
+
|
94
|
+
# @private Construct a net/http http client
|
95
|
+
def sync_http_client
|
96
|
+
@client ||= begin
|
97
|
+
require 'httpclient'
|
98
|
+
|
99
|
+
HTTPClient.new(default_header: {'X-RealPush-Secret-Key' => @privatekey}).tap do |c|
|
100
|
+
c.connect_timeout = @connect_timeout
|
101
|
+
c.send_timeout = @send_timeout
|
102
|
+
c.receive_timeout = @receive_timeout
|
103
|
+
c.keep_alive_timeout = @keep_alive_timeout
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Convenience method to set all timeouts to the same value (in seconds).
|
109
|
+
# For more control, use the individual writers.
|
110
|
+
def timeout=(value)
|
111
|
+
@connect_timeout, @send_timeout, @receive_timeout = value, value, value
|
112
|
+
end
|
113
|
+
|
114
|
+
# Trigger an event on one or more channels
|
115
|
+
#
|
116
|
+
# POST /api/[api_version]/events/[event_name]/
|
117
|
+
#
|
118
|
+
# @param channels [String or Array] 1-10 channel names
|
119
|
+
# @param event_name [String]
|
120
|
+
# @param data [Object] Event data to be triggered in javascript.
|
121
|
+
# Objects other than strings will be converted to JSON
|
122
|
+
#
|
123
|
+
# @return [Hash] See Thunderpush API docs
|
124
|
+
#
|
125
|
+
# @raise [ThunderPush::Error] Unsuccessful response - see the error message
|
126
|
+
# @raise [ThunderPush::HTTPError] Error raised inside http client. The original error is wrapped in error.original_error
|
127
|
+
#
|
128
|
+
def trigger(channels, event_name, data)
|
129
|
+
post("/events/#{event_name}/", trigger_params(channels, data))
|
130
|
+
end
|
131
|
+
|
132
|
+
# Trigger an event on one or more channels
|
133
|
+
#
|
134
|
+
# POST /apps/[app_id]/events/[event_name]/
|
135
|
+
#
|
136
|
+
# @param channels [String or Array] 1-10 channel names
|
137
|
+
# @param event_name [String]
|
138
|
+
# @param data [Object] Event data to be triggered in javascript.
|
139
|
+
# Objects other than strings will be converted to JSON
|
140
|
+
#
|
141
|
+
# @raise [ThunderPush::Error] Unsuccessful response - see the error message
|
142
|
+
# @raise [ThunderPush::HTTPError] Error raised inside http client. The original error is wrapped in error.original_error
|
143
|
+
#
|
144
|
+
def trigger_async(channels, event_name, data)
|
145
|
+
post_async("/events/#{event_name}/", trigger_params(channels, data))
|
146
|
+
end
|
147
|
+
|
148
|
+
# Configure Thunderpush connection by providing a url rather than specifying
|
149
|
+
# scheme, key, secret, and app_id separately.
|
150
|
+
#
|
151
|
+
# @example
|
152
|
+
# ThunderPush.default_client.url = http://key:secret@127.0.0.1:5678
|
153
|
+
#
|
154
|
+
def url=(str)
|
155
|
+
regex = /^(?<scheme>http|https):\/\/((?<app_id>[\d-]+)(:(?<privatekey>[\w-]+){1})?@)?(?<hostname>[\w\.-]+)(:(?<port>[\d]+))?/
|
156
|
+
match = str.match regex
|
157
|
+
@scheme = match[:scheme] unless match[:scheme].nil?
|
158
|
+
self.encrypted= true if scheme == 'https'
|
159
|
+
@port = match[:port].to_i unless match[:port].nil?
|
160
|
+
@hostname = match[:hostname] unless match[:hostname].nil?
|
161
|
+
@app_id = match[:app_id] unless match[:app_id].nil?
|
162
|
+
@privatekey = match[:privatekey] unless match[:privatekey].nil?
|
163
|
+
end
|
164
|
+
|
165
|
+
# @private Builds a url for this app, optionally appending a path
|
166
|
+
def url(path = '')
|
167
|
+
path = "/#{path}" unless path.start_with? '/'
|
168
|
+
URI::Generic.build({
|
169
|
+
:scheme => @scheme,
|
170
|
+
:host => @hostname,
|
171
|
+
:port => @port,
|
172
|
+
:path => "/#{RealPush::API_VERSION_APP}#{path}"
|
173
|
+
})
|
174
|
+
end
|
175
|
+
|
176
|
+
protected
|
177
|
+
|
178
|
+
def trigger_params(channels, data)
|
179
|
+
data.merge! :channels => channels
|
180
|
+
begin
|
181
|
+
MultiJson.encode(data)
|
182
|
+
rescue MultiJson::DecodeError => e
|
183
|
+
ThunderPush.logger.error("Could not convert #{data.inspect} into JSON")
|
184
|
+
raise e
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module RealPush
|
2
|
+
class Request
|
3
|
+
attr_reader :body, :params
|
4
|
+
|
5
|
+
def initialize(client, verb, uri, params={}, body = nil)
|
6
|
+
@client, @verb, @uri, @params = client, verb, uri, params
|
7
|
+
|
8
|
+
raise ConfigurationError, "Invalid verb ('#{verb}')" unless %w{GET POST}.include? verb.to_s.upcase
|
9
|
+
raise ConfigurationError, "Invalid client #{client.inspect}" unless client.is_a? Client
|
10
|
+
raise ConfigurationError, "Invalid uri #{uri.inspect}" unless uri.is_a? URI
|
11
|
+
|
12
|
+
@head = {}
|
13
|
+
|
14
|
+
@body = body
|
15
|
+
if body
|
16
|
+
@params[:body_md5] = Digest::MD5.hexdigest(body)
|
17
|
+
@head['Content-Type'] = 'application/json'
|
18
|
+
end
|
19
|
+
|
20
|
+
sign_params
|
21
|
+
end
|
22
|
+
|
23
|
+
def sign_params
|
24
|
+
auth_hash = {
|
25
|
+
:auth_version => "1.0",
|
26
|
+
:auth_key => @client.app_id,
|
27
|
+
:auth_timestamp => Time.now.to_i.to_s
|
28
|
+
}
|
29
|
+
params_string = auth_hash.sort.map do |k, v|
|
30
|
+
"#{k}=#{v}"
|
31
|
+
end.join('&')
|
32
|
+
string_to_sign = [@verb.to_s.upcase, @uri.path, params_string].join "\n"
|
33
|
+
digest = OpenSSL::Digest::SHA256.new
|
34
|
+
auth_hash[:auth_signature] = OpenSSL::HMAC.hexdigest(digest, @client.privatekey, string_to_sign)
|
35
|
+
@params = @params.merge(auth_hash)
|
36
|
+
end
|
37
|
+
private :sign_params
|
38
|
+
|
39
|
+
def send_sync
|
40
|
+
http = @client.sync_http_client
|
41
|
+
|
42
|
+
begin
|
43
|
+
response = http.request(@verb, @uri, @params, @body, @head)
|
44
|
+
rescue HTTPClient::BadResponseError,
|
45
|
+
HTTPClient::TimeoutError,
|
46
|
+
SocketError,
|
47
|
+
Errno::ECONNREFUSED => e
|
48
|
+
raise RealPush::HTTPError, "#{e.message} (#{e.class})"
|
49
|
+
end
|
50
|
+
|
51
|
+
body = response.body ? response.body.chomp : nil
|
52
|
+
|
53
|
+
return handle_response(response.code.to_i, body)
|
54
|
+
end
|
55
|
+
|
56
|
+
def send_async
|
57
|
+
http = @client.sync_http_client
|
58
|
+
http.request_async(@verb, @uri, @params, @body, @head)
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def handle_response(status_code, body)
|
64
|
+
case status_code
|
65
|
+
when 200
|
66
|
+
return symbolize_first_level(MultiJson.decode(body))
|
67
|
+
when 202
|
68
|
+
return true
|
69
|
+
when 400
|
70
|
+
raise Error, "Bad request: #{body}"
|
71
|
+
when 401
|
72
|
+
raise AuthenticationError, body
|
73
|
+
when 404
|
74
|
+
raise Error, "404 Not found (#{@uri.path})"
|
75
|
+
when 407
|
76
|
+
raise Error, "Proxy Authentication Required"
|
77
|
+
else
|
78
|
+
raise Error, "Unknown error (status code #{status_code}): #{body}"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def symbolize_first_level(hash)
|
83
|
+
hash.inject({}) do |result, (key, value)|
|
84
|
+
result[key.to_sym] = value
|
85
|
+
result
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module RealPush
|
2
|
+
class Resource
|
3
|
+
def initialize(client, path)
|
4
|
+
@client = client
|
5
|
+
@path = path
|
6
|
+
end
|
7
|
+
|
8
|
+
def get(params)
|
9
|
+
create_request(:get, params).send_sync
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_async(params)
|
13
|
+
create_request(:get, params).send_async
|
14
|
+
end
|
15
|
+
|
16
|
+
def post(body)
|
17
|
+
body = MultiJson.encode(body) unless body.is_a? String
|
18
|
+
create_request(:post, {}, body).send_sync
|
19
|
+
end
|
20
|
+
|
21
|
+
def post_async(body)
|
22
|
+
body = MultiJson.encode(body) unless body.is_a? String
|
23
|
+
create_request(:post, {}, body).send_async
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def create_request(verb, params, body = nil)
|
29
|
+
Request.new(@client, verb, url, params, body)
|
30
|
+
end
|
31
|
+
|
32
|
+
def url
|
33
|
+
@_url ||= @client.url(@path)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/realpush.gemspec
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'realpush/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'realpush'
|
8
|
+
spec.version = RealPush::VERSION
|
9
|
+
spec.authors = ['Zaez Team']
|
10
|
+
spec.email = ['contato@zaez.net']
|
11
|
+
spec.summary = %q{Library of integration with RealPush system. Written in Ruby.}
|
12
|
+
spec.description = %q{RealPush is a private and commercial system to send notifications via websocket.
|
13
|
+
The system allows the creation of applications based on its quota through access API.
|
14
|
+
Sending notifications to trigger customers with private and public channels. Synchronous and asynchronous requests..}
|
15
|
+
spec.homepage = 'http://realpush.cc/'
|
16
|
+
spec.license = 'MIT'
|
17
|
+
|
18
|
+
spec.files = `git ls-files -z`.split("\x0")
|
19
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
|
+
spec.require_paths = ['lib']
|
22
|
+
|
23
|
+
spec.add_dependency 'multi_json', '~> 1.0'
|
24
|
+
spec.add_dependency 'httpclient', '~> 2.6'
|
25
|
+
spec.add_dependency 'signature', '~> 0.1.6'
|
26
|
+
spec.add_dependency 'activesupport', '>= 4'
|
27
|
+
|
28
|
+
spec.add_development_dependency 'bundler', '~> 1.7'
|
29
|
+
spec.add_development_dependency 'rspec', '~> 3.1.0'
|
30
|
+
spec.add_development_dependency 'pry', '>= 0.9.12'
|
31
|
+
spec.add_development_dependency 'simplecov'
|
32
|
+
spec.add_development_dependency 'codeclimate-test-reporter'
|
33
|
+
spec.add_development_dependency 'guard'
|
34
|
+
spec.add_development_dependency 'guard-rspec'
|
35
|
+
spec.add_development_dependency 'growl'
|
36
|
+
spec.add_development_dependency 'webmock'
|
37
|
+
spec.add_development_dependency 'em-http-request', '~> 1.1.0'
|
38
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
39
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RealPush::API::App do
|
4
|
+
data = {
|
5
|
+
alias_name: 'APP 1',
|
6
|
+
max_connections: '0',
|
7
|
+
max_daily_messages: '0',
|
8
|
+
status: 'active'
|
9
|
+
}
|
10
|
+
|
11
|
+
it 'should try exception when token has invalid format' do
|
12
|
+
50.times do
|
13
|
+
expect { RealPush::API::App.new( SecureRandom.urlsafe_base64(32, true) ) }.not_to raise_error
|
14
|
+
end
|
15
|
+
expect { RealPush::API::App.new( '' ) }.to raise_error(RealPush::ConfigurationError)
|
16
|
+
expect { RealPush::API::App.new( '@'+('2'*42) ) }.to raise_error(RealPush::ConfigurationError)
|
17
|
+
expect { RealPush::API::App.new( 'a'*44 ) }.to raise_error(RealPush::ConfigurationError)
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'Methods from base configuration' do
|
21
|
+
|
22
|
+
let(:app) { RealPush::API::App.new( SecureRandom.urlsafe_base64(32, true) ) }
|
23
|
+
|
24
|
+
it 'should accept the params in requests (alias_name, max_connections, max_daily_messages, status)' do
|
25
|
+
[:alias_name, :max_connections, :max_daily_messages, :status].each do |p|
|
26
|
+
expect(RealPush::API::App.params_accept.include? p).to eql true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should have a instance method to LIST all APPs' do
|
31
|
+
expect(app.respond_to? :list).to be_truthy
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should have a instance method to DESTROY an app' do
|
35
|
+
expect(app.respond_to? :destroy).to be_truthy
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should have a instance method to CREATE an app' do
|
39
|
+
expect(app.respond_to? :create).to be_truthy
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should have a instance method to UPDATE an app' do
|
43
|
+
expect(app.respond_to? :update).to be_truthy
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
describe 'List method' do
|
49
|
+
|
50
|
+
let(:app) { RealPush::API::App.new( SecureRandom.urlsafe_base64(32, true) ) }
|
51
|
+
|
52
|
+
before do
|
53
|
+
api_path = %r{apps\.json}
|
54
|
+
stub_request(:get, api_path).
|
55
|
+
with({
|
56
|
+
:headers => { 'X-RealPush-Token' => app.token }
|
57
|
+
}).
|
58
|
+
to_return({
|
59
|
+
:status => 200,
|
60
|
+
:body => MultiJson.encode([
|
61
|
+
{id: SecureRandom.hex(12)},
|
62
|
+
{id: SecureRandom.hex(12)},
|
63
|
+
{id: SecureRandom.hex(12)}
|
64
|
+
])
|
65
|
+
})
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'testing connection and requesting' do
|
69
|
+
app.list
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should contains a tree elements in response' do
|
73
|
+
list = app.list
|
74
|
+
expect(list.count).to eql 3
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
describe 'Destroy method' do
|
80
|
+
|
81
|
+
let(:app) { RealPush::API::App.new( SecureRandom.urlsafe_base64(32, true) ) }
|
82
|
+
|
83
|
+
before do
|
84
|
+
api_path = %r{apps/123\.json}
|
85
|
+
stub_request(:delete, api_path).
|
86
|
+
with({
|
87
|
+
:headers => { 'X-RealPush-Token' => app.token }
|
88
|
+
}).
|
89
|
+
to_return({
|
90
|
+
:status => 204
|
91
|
+
})
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'testing connection and requesting, with response 204' do
|
95
|
+
app.destroy(123)
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
describe 'Create method' do
|
101
|
+
let(:app) { RealPush::API::App.new( SecureRandom.urlsafe_base64(32, true) ) }
|
102
|
+
|
103
|
+
before do
|
104
|
+
api_path = %r{apps\.json}
|
105
|
+
stub_request(:post, api_path).
|
106
|
+
with({
|
107
|
+
:headers => { 'X-RealPush-Token' => app.token },
|
108
|
+
:body => data
|
109
|
+
}).
|
110
|
+
to_return({
|
111
|
+
:status => 200,
|
112
|
+
body: MultiJson.encode( data.merge(id: SecureRandom.hex(12) ) )
|
113
|
+
})
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'testing connection and requesting, with response 200' do
|
117
|
+
app.create(data)
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'must try exception when has invalid parameter' do
|
121
|
+
expect {app.create({asd: 1}) }.to raise_error(RealPush::ConfigurationError)
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'should returns a App data when successfully' do
|
125
|
+
app_return = app.create(data).symbolize_keys
|
126
|
+
data.keys.each { |key| expect(app_return.keys.include? key.to_sym).to be_truthy }
|
127
|
+
expect(app_return[:id]).to be_truthy
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'should returns error in Hash, when invalid data' do
|
131
|
+
api_path = %r{apps\.json}
|
132
|
+
stub_request(:post, api_path).
|
133
|
+
with({
|
134
|
+
:headers => { 'X-RealPush-Token' => app.token }
|
135
|
+
}).
|
136
|
+
to_return({
|
137
|
+
:status => 500,
|
138
|
+
body: MultiJson.encode( { error: 'Message' } )
|
139
|
+
})
|
140
|
+
app_return = app.create(data).symbolize_keys
|
141
|
+
data.keys.each { |key| expect(app_return.keys.include? key.to_sym).to be_falsey }
|
142
|
+
expect(app_return[:id]).to be_falsey
|
143
|
+
expect(app_return[:error]).to be_truthy
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
describe 'Update method' do
|
149
|
+
let(:app) { RealPush::API::App.new( SecureRandom.urlsafe_base64(32, true) ) }
|
150
|
+
|
151
|
+
before do
|
152
|
+
api_path = %r{apps/123\.json}
|
153
|
+
stub_request(:patch, api_path).
|
154
|
+
with({
|
155
|
+
:headers => { 'X-RealPush-Token' => app.token },
|
156
|
+
:body => data
|
157
|
+
}).
|
158
|
+
to_return({
|
159
|
+
:status => 200,
|
160
|
+
body: MultiJson.encode( data.merge(id: 123 ) )
|
161
|
+
})
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'testing connection and requesting, with response 200' do
|
165
|
+
app.update(123, data)
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'must try exception when has invalid parameter' do
|
169
|
+
expect {app.update(123, {asd: 1}) }.to raise_error(RealPush::ConfigurationError)
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'should returns a App data when successfully' do
|
173
|
+
app_return = app.update(123, data).symbolize_keys
|
174
|
+
data.keys.each { |key| expect(app_return.keys.include? key.to_sym).to be_truthy }
|
175
|
+
expect(app_return[:id]).to be_truthy
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
|
181
|
+
|
182
|
+
end
|