realpush 0.0.1
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.
- 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
|