cobot_client 5.0.0 → 6.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.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +23 -0
- data/.github/workflows/test.yml +26 -0
- data/.gitignore +3 -0
- data/.rubocop.yml +31 -0
- data/CHANGELOG.md +9 -1
- data/Gemfile +10 -0
- data/Rakefile +6 -2
- data/cobot_client.gemspec +6 -6
- data/lib/cobot_client/api_client.rb +30 -77
- data/lib/cobot_client/engine.rb +2 -0
- data/lib/cobot_client/errors.rb +47 -0
- data/lib/cobot_client/navigation_link.rb +11 -8
- data/lib/cobot_client/navigation_link_service.rb +11 -6
- data/lib/cobot_client/request.rb +89 -0
- data/lib/cobot_client/response.rb +45 -0
- data/lib/cobot_client/url_helper.rb +23 -20
- data/lib/cobot_client/version.rb +3 -1
- data/lib/cobot_client.rb +11 -1
- data/rbs_collection.yaml +20 -0
- data/sig/cobot_client/api_client.rbs +51 -0
- data/sig/cobot_client/errors.rbs +23 -0
- data/sig/cobot_client/navigation_link.rbs +11 -0
- data/sig/cobot_client/navigation_link_service.rbs +17 -0
- data/sig/cobot_client/request.rbs +39 -0
- data/sig/cobot_client/response.rbs +23 -0
- data/sig/cobot_client/url_helper.rbs +25 -0
- data/sig/cobot_client/version.rbs +3 -0
- data/sig/manifests.yaml +4 -0
- data/spec/cobot_client/api_client_spec.rb +186 -111
- data/spec/cobot_client/navigation_link_service_spec.rb +48 -23
- data/spec/cobot_client/url_helper_spec.rb +8 -6
- data/spec/spec_helper.rb +10 -0
- metadata +33 -64
- data/.travis.yml +0 -4
- data/lib/cobot_client/exceptions.rb +0 -17
data/rbs_collection.yaml
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Download sources
|
|
2
|
+
sources:
|
|
3
|
+
- type: git
|
|
4
|
+
name: ruby/gem_rbs_collection
|
|
5
|
+
remote: https://github.com/ruby/gem_rbs_collection.git
|
|
6
|
+
revision: main
|
|
7
|
+
repo_dir: gems
|
|
8
|
+
|
|
9
|
+
# You can specify local directories as sources also.
|
|
10
|
+
# - type: local
|
|
11
|
+
# path: path/to/your/local/repository
|
|
12
|
+
|
|
13
|
+
# A directory to install the downloaded RBSs
|
|
14
|
+
path: .gem_rbs_collection
|
|
15
|
+
|
|
16
|
+
gems:
|
|
17
|
+
- name: auth-sanitizer
|
|
18
|
+
ignore: true # See: https://github.com/ruby-oauth/auth-sanitizer/pull/5
|
|
19
|
+
- name: snaky_hash
|
|
20
|
+
ignore: true # See: https://github.com/ruby-oauth/snaky_hash/pull/11
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module CobotClient
|
|
2
|
+
class ApiClient
|
|
3
|
+
type headers = Hash[String, String]
|
|
4
|
+
type path = String
|
|
5
|
+
type request_params = parsed_json_object
|
|
6
|
+
type request_payload = (request_params | Array[request_params])
|
|
7
|
+
type parsed_json_object = Hash[Symbol, untyped]
|
|
8
|
+
type parsed_response_body = (parsed_json_object | Array[parsed_json_object])?
|
|
9
|
+
type subdomain = String
|
|
10
|
+
type url = String
|
|
11
|
+
|
|
12
|
+
@access_token: String
|
|
13
|
+
|
|
14
|
+
attr_accessor self.retry_time: Integer
|
|
15
|
+
attr_accessor self.user_agent: String
|
|
16
|
+
|
|
17
|
+
def initialize: (String) -> void
|
|
18
|
+
|
|
19
|
+
def delete:
|
|
20
|
+
(subdomain, path) -> Response |
|
|
21
|
+
(url) -> Response
|
|
22
|
+
|
|
23
|
+
def get:
|
|
24
|
+
(subdomain, path, ?request_payload) -> parsed_response_body |
|
|
25
|
+
(url, ?request_payload) -> parsed_response_body
|
|
26
|
+
|
|
27
|
+
def patch:
|
|
28
|
+
(subdomain, path, ?request_payload) -> parsed_response_body |
|
|
29
|
+
(url, ?request_payload) -> parsed_response_body
|
|
30
|
+
|
|
31
|
+
def post:
|
|
32
|
+
(subdomain, path, ?request_payload) -> parsed_response_body |
|
|
33
|
+
(url, ?request_payload) -> parsed_response_body
|
|
34
|
+
|
|
35
|
+
def put:
|
|
36
|
+
(subdomain, path, ?request_payload) -> parsed_response_body |
|
|
37
|
+
(url, ?request_payload) -> parsed_response_body
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def headers: -> headers
|
|
42
|
+
|
|
43
|
+
def request:
|
|
44
|
+
(Request::verb, subdomain, path, ?request_payload) -> Response |
|
|
45
|
+
(Request::verb, url, ?request_payload) -> Response
|
|
46
|
+
|
|
47
|
+
def retry_errors: [R] () { () -> R } -> R
|
|
48
|
+
|
|
49
|
+
def rewrap_errors: () { () -> Response } -> Response
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module CobotClient
|
|
2
|
+
class Error < StandardError
|
|
3
|
+
end
|
|
4
|
+
|
|
5
|
+
class ConnectionError < StandardError
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
class ResponseError < Error
|
|
9
|
+
HTTP_CODE: Integer?
|
|
10
|
+
|
|
11
|
+
def self.build: (String?, response: Response) -> ResponseError
|
|
12
|
+
|
|
13
|
+
attr_reader response: Response?
|
|
14
|
+
|
|
15
|
+
def initialize: (String?, ?response: Response?) -> void
|
|
16
|
+
|
|
17
|
+
def http_body: -> String?
|
|
18
|
+
|
|
19
|
+
def http_code: -> Integer?
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
RESPONSE_CODE_TO_ERROR_CLASS: Hash[Integer, singleton(ResponseError)]
|
|
23
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module CobotClient
|
|
2
|
+
class NavigationLink
|
|
3
|
+
attr_accessor section: String
|
|
4
|
+
attr_accessor label: String
|
|
5
|
+
attr_accessor iframe_url: String
|
|
6
|
+
attr_accessor user_url: String
|
|
7
|
+
attr_accessor user_editable: bool
|
|
8
|
+
|
|
9
|
+
def initialize: (Hash[Symbol, untyped]) -> void
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module CobotClient
|
|
2
|
+
class NavigationLinkService
|
|
3
|
+
@api_client: ApiClient
|
|
4
|
+
|
|
5
|
+
@subdomain: String
|
|
6
|
+
|
|
7
|
+
def initialize: (ApiClient, String) -> void
|
|
8
|
+
|
|
9
|
+
def install_links: (Array[NavigationLink]) -> Array[NavigationLink]
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def create_link: (NavigationLink) -> NavigationLink
|
|
14
|
+
|
|
15
|
+
def fetch_links: -> Array[NavigationLink]
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module CobotClient
|
|
2
|
+
class Request
|
|
3
|
+
type verb = Symbol
|
|
4
|
+
|
|
5
|
+
CONTENT_TYPE_HEADER: ApiClient::headers
|
|
6
|
+
VERBS: Array[verb]
|
|
7
|
+
|
|
8
|
+
@http: Net::HTTP
|
|
9
|
+
|
|
10
|
+
attr_reader body: String?
|
|
11
|
+
attr_reader headers: ApiClient::headers
|
|
12
|
+
attr_reader uri: URI::Generic
|
|
13
|
+
attr_reader verb: verb
|
|
14
|
+
|
|
15
|
+
def initialize:
|
|
16
|
+
(verb, ApiClient::subdomain, ApiClient::path, ?ApiClient::request_payload) -> void |
|
|
17
|
+
(verb, ApiClient::url, ?ApiClient::request_payload) -> void
|
|
18
|
+
|
|
19
|
+
def headers=: (ApiClient::headers) -> ApiClient::headers
|
|
20
|
+
|
|
21
|
+
def submit: -> Response
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def build_uri: (ApiClient::subdomain | ApiClient::url, ApiClient::path?, **untyped) -> URI::Generic
|
|
26
|
+
|
|
27
|
+
def http: -> Net::HTTP
|
|
28
|
+
|
|
29
|
+
def net_http_request: -> Net::HTTPRequest
|
|
30
|
+
|
|
31
|
+
def parse_args:
|
|
32
|
+
(ApiClient::url) -> [ApiClient::url, nil, nil, ApiClient::request_payload] |
|
|
33
|
+
(ApiClient::url, ApiClient::request_payload) -> [ApiClient::url, nil, nil, ApiClient::request_payload] |
|
|
34
|
+
(ApiClient::subdomain, ApiClient::path) -> [nil, ApiClient::subdomain, ApiClient::path, ApiClient::request_payload] |
|
|
35
|
+
(ApiClient::subdomain, ApiClient::path, ApiClient::request_payload) -> [nil, ApiClient::subdomain, ApiClient::path, ApiClient::request_payload]
|
|
36
|
+
|
|
37
|
+
def request_class: -> singleton(Net::HTTPRequest)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module CobotClient
|
|
2
|
+
class Response
|
|
3
|
+
@net_http_response: Net::HTTPResponse
|
|
4
|
+
|
|
5
|
+
def initialize: (Net::HTTPResponse) -> void
|
|
6
|
+
|
|
7
|
+
def body: -> String
|
|
8
|
+
|
|
9
|
+
def client_error?: -> bool
|
|
10
|
+
|
|
11
|
+
def code: -> Integer
|
|
12
|
+
|
|
13
|
+
def headers: -> ApiClient::headers
|
|
14
|
+
|
|
15
|
+
def parsed_body: -> ApiClient::parsed_response_body
|
|
16
|
+
|
|
17
|
+
def server_error?: -> bool
|
|
18
|
+
|
|
19
|
+
def success?: -> bool
|
|
20
|
+
|
|
21
|
+
def to_error: -> ResponseError?
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module CobotClient
|
|
2
|
+
module UrlHelper
|
|
3
|
+
DEFAULT_SITE: String
|
|
4
|
+
|
|
5
|
+
self.@site: String
|
|
6
|
+
|
|
7
|
+
def self.site: -> String
|
|
8
|
+
|
|
9
|
+
def self.site=: (String) -> String
|
|
10
|
+
|
|
11
|
+
def cobot_uri:
|
|
12
|
+
() -> URI::Generic |
|
|
13
|
+
(ApiClient::subdomain) -> URI::Generic |
|
|
14
|
+
(ApiClient::subdomain, params: ApiClient::request_payload) -> URI::Generic |
|
|
15
|
+
(ApiClient::subdomain, ApiClient::path) -> URI::Generic |
|
|
16
|
+
(ApiClient::subdomain, ApiClient::path, params: ApiClient::request_payload) -> URI::Generic
|
|
17
|
+
|
|
18
|
+
def cobot_url:
|
|
19
|
+
() -> String |
|
|
20
|
+
(ApiClient::subdomain) -> String |
|
|
21
|
+
(ApiClient::subdomain, params: ApiClient::request_payload) -> String |
|
|
22
|
+
(ApiClient::subdomain, ApiClient::path) -> String |
|
|
23
|
+
(ApiClient::subdomain, ApiClient::path, params: ApiClient::request_payload) -> String
|
|
24
|
+
end
|
|
25
|
+
end
|
data/sig/manifests.yaml
ADDED
|
@@ -1,68 +1,96 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'spec_helper'
|
|
2
4
|
|
|
3
5
|
describe CobotClient::ApiClient do
|
|
4
|
-
let(:api_client) {
|
|
5
|
-
let(:default_response) {
|
|
6
|
+
let(:api_client) { described_class.new('token-123') }
|
|
7
|
+
let(:default_response) { {status: 200, body: '{}'} }
|
|
8
|
+
|
|
9
|
+
def cobot_client_response(code:, body: '')
|
|
10
|
+
net_http_response = Net::HTTPResponse.new('1.1', code.to_s, nil)
|
|
11
|
+
net_http_response.body = body
|
|
12
|
+
net_http_response.instance_variable_set(:@read, true)
|
|
6
13
|
|
|
7
|
-
|
|
8
|
-
CobotClient::ApiClient.user_agent = 'test agent'
|
|
9
|
-
CobotClient::ApiClient.retry_time = 0
|
|
14
|
+
CobotClient::Response.new(net_http_response)
|
|
10
15
|
end
|
|
11
16
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
before do
|
|
18
|
+
described_class.user_agent = 'test agent'
|
|
19
|
+
described_class.retry_time = 0
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe '#put' do
|
|
23
|
+
it 'accepts a subdomain' do
|
|
24
|
+
request = stub_request(:put, 'https://co-up.cobot.me/api/invoices')
|
|
25
|
+
.with(
|
|
26
|
+
body: {id: '1'}.to_json,
|
|
27
|
+
headers: {
|
|
28
|
+
'Content-Type' => 'application/json',
|
|
29
|
+
'User-Agent' => 'test agent',
|
|
30
|
+
'Authorization' => 'Bearer token-123'
|
|
31
|
+
}
|
|
32
|
+
)
|
|
33
|
+
.and_return(default_response)
|
|
20
34
|
|
|
21
35
|
api_client.put 'co-up', '/invoices', {id: '1'}
|
|
36
|
+
|
|
37
|
+
expect(request).to have_been_made.once
|
|
22
38
|
end
|
|
23
39
|
|
|
24
40
|
it 'passes an array as body' do
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
41
|
+
request = stub_request(:put, 'https://co-up.cobot.me/api/invoices')
|
|
42
|
+
.with(
|
|
43
|
+
body: [{id: '1'}].to_json,
|
|
44
|
+
headers: {
|
|
45
|
+
'Content-Type' => 'application/json',
|
|
46
|
+
'User-Agent' => 'test agent',
|
|
47
|
+
'Authorization' => 'Bearer token-123'
|
|
48
|
+
}
|
|
49
|
+
)
|
|
50
|
+
.and_return(default_response)
|
|
31
51
|
|
|
32
52
|
api_client.put 'co-up', '/invoices', [{id: '1'}]
|
|
53
|
+
|
|
54
|
+
expect(request).to have_been_made.once
|
|
33
55
|
end
|
|
34
56
|
|
|
35
57
|
it 'accepts a url' do
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
58
|
+
request = stub_request(:put, 'https://co-up.cobot.me/api/invoices')
|
|
59
|
+
.with(
|
|
60
|
+
body: {id: '1'}.to_json,
|
|
61
|
+
headers: {
|
|
62
|
+
'Content-Type' => 'application/json',
|
|
63
|
+
'User-Agent' => 'test agent',
|
|
64
|
+
'Authorization' => 'Bearer token-123'
|
|
65
|
+
}
|
|
66
|
+
)
|
|
67
|
+
.and_return(default_response)
|
|
42
68
|
|
|
43
69
|
api_client.put 'https://co-up.cobot.me/api/invoices', {id: '1'}
|
|
70
|
+
|
|
71
|
+
expect(request).to have_been_made.once
|
|
44
72
|
end
|
|
45
73
|
|
|
46
74
|
it 'returns the response json' do
|
|
47
|
-
|
|
75
|
+
allow_any_instance_of(CobotClient::Request).to receive(:submit) { cobot_client_response(code: 200, body: [{number: 1}].to_json) }
|
|
48
76
|
|
|
49
77
|
expect(api_client.put('co-up', '/invoices', {})).to eql([{number: 1}])
|
|
50
78
|
end
|
|
51
79
|
|
|
52
80
|
it 'returns nil when the status code is 204' do
|
|
53
|
-
|
|
81
|
+
allow_any_instance_of(CobotClient::Request).to receive(:submit) { cobot_client_response(body: '', code: 204) }
|
|
54
82
|
|
|
55
83
|
expect(api_client.put('co-up', '/invoices', {})).to be_nil
|
|
56
84
|
end
|
|
57
85
|
|
|
58
86
|
it 'retries a 502 error' do
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if
|
|
62
|
-
|
|
63
|
-
|
|
87
|
+
times = 0
|
|
88
|
+
allow_any_instance_of(CobotClient::Request).to receive(:submit) do
|
|
89
|
+
if times < 3
|
|
90
|
+
times += 1
|
|
91
|
+
cobot_client_response(code: 502)
|
|
64
92
|
else
|
|
65
|
-
|
|
93
|
+
cobot_client_response(code: 200, body: {success: true}.to_json)
|
|
66
94
|
end
|
|
67
95
|
end
|
|
68
96
|
|
|
@@ -70,49 +98,61 @@ describe CobotClient::ApiClient do
|
|
|
70
98
|
end
|
|
71
99
|
end
|
|
72
100
|
|
|
73
|
-
|
|
74
|
-
it '
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
101
|
+
describe '#patch' do
|
|
102
|
+
it 'accepts a subdomain' do
|
|
103
|
+
request = stub_request(:patch, 'https://co-up.cobot.me/api/invoices')
|
|
104
|
+
.with(
|
|
105
|
+
body: {id: '1'}.to_json,
|
|
106
|
+
headers: {
|
|
107
|
+
'Content-Type' => 'application/json',
|
|
108
|
+
'User-Agent' => 'test agent',
|
|
109
|
+
'Authorization' => 'Bearer token-123'
|
|
110
|
+
}
|
|
111
|
+
)
|
|
112
|
+
.and_return(default_response)
|
|
81
113
|
|
|
82
114
|
api_client.patch 'co-up', '/invoices', {id: '1'}
|
|
115
|
+
|
|
116
|
+
expect(request).to have_been_made.once
|
|
83
117
|
end
|
|
84
118
|
|
|
85
119
|
it 'accepts a url' do
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
120
|
+
request = stub_request(:patch, 'https://co-up.cobot.me/api/invoices')
|
|
121
|
+
.with(
|
|
122
|
+
body: {id: '1'}.to_json,
|
|
123
|
+
headers: {
|
|
124
|
+
'Content-Type' => 'application/json',
|
|
125
|
+
'User-Agent' => 'test agent',
|
|
126
|
+
'Authorization' => 'Bearer token-123'
|
|
127
|
+
}
|
|
128
|
+
)
|
|
129
|
+
.and_return(default_response)
|
|
92
130
|
|
|
93
131
|
api_client.patch 'https://co-up.cobot.me/api/invoices', {id: '1'}
|
|
132
|
+
|
|
133
|
+
expect(request).to have_been_made.once
|
|
94
134
|
end
|
|
95
135
|
|
|
96
136
|
it 'returns the response json' do
|
|
97
|
-
|
|
137
|
+
allow_any_instance_of(CobotClient::Request).to receive(:submit) { cobot_client_response(code: 200, body: [{number: 1}].to_json) }
|
|
98
138
|
|
|
99
139
|
expect(api_client.patch('co-up', '/invoices', {})).to eql([{number: 1}])
|
|
100
140
|
end
|
|
101
141
|
|
|
102
142
|
it 'returns nil when the status code is 204' do
|
|
103
|
-
|
|
143
|
+
allow_any_instance_of(CobotClient::Request).to receive(:submit) { cobot_client_response(body: '', code: 204) }
|
|
104
144
|
|
|
105
145
|
expect(api_client.patch('co-up', '/invoices', {})).to be_nil
|
|
106
146
|
end
|
|
107
147
|
|
|
108
148
|
it 'retries a 502 error' do
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
if
|
|
112
|
-
|
|
113
|
-
|
|
149
|
+
times = 0
|
|
150
|
+
allow_any_instance_of(CobotClient::Request).to receive(:submit) do
|
|
151
|
+
if times < 3
|
|
152
|
+
times += 1
|
|
153
|
+
cobot_client_response(code: 502)
|
|
114
154
|
else
|
|
115
|
-
|
|
155
|
+
cobot_client_response(code: 200, body: {success: true}.to_json)
|
|
116
156
|
end
|
|
117
157
|
end
|
|
118
158
|
|
|
@@ -120,127 +160,162 @@ describe CobotClient::ApiClient do
|
|
|
120
160
|
end
|
|
121
161
|
end
|
|
122
162
|
|
|
123
|
-
|
|
124
|
-
it '
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
163
|
+
describe '#post' do
|
|
164
|
+
it 'accepts a subdomain' do
|
|
165
|
+
request = stub_request(:post, 'https://co-up.cobot.me/api/invoices')
|
|
166
|
+
.with(
|
|
167
|
+
body: {id: '1'}.to_json,
|
|
168
|
+
headers: {
|
|
169
|
+
'Content-Type' => 'application/json',
|
|
170
|
+
'User-Agent' => 'test agent',
|
|
171
|
+
'Authorization' => 'Bearer token-123'
|
|
172
|
+
}
|
|
173
|
+
)
|
|
174
|
+
.and_return(default_response)
|
|
131
175
|
|
|
132
176
|
api_client.post 'co-up', '/invoices', {id: '1'}
|
|
177
|
+
|
|
178
|
+
expect(request).to have_been_made.once
|
|
133
179
|
end
|
|
134
180
|
|
|
135
181
|
it 'accepts a url' do
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
182
|
+
request = stub_request(:post, 'https://co-up.cobot.me/api/invoices')
|
|
183
|
+
.with(
|
|
184
|
+
body: {id: '1'}.to_json,
|
|
185
|
+
headers: {
|
|
186
|
+
'Content-Type' => 'application/json',
|
|
187
|
+
'User-Agent' => 'test agent',
|
|
188
|
+
'Authorization' => 'Bearer token-123'
|
|
189
|
+
}
|
|
190
|
+
)
|
|
191
|
+
.and_return(default_response)
|
|
142
192
|
|
|
143
193
|
api_client.post 'https://co-up.cobot.me/api/invoices', {id: '1'}
|
|
194
|
+
|
|
195
|
+
expect(request).to have_been_made.once
|
|
144
196
|
end
|
|
145
197
|
|
|
146
198
|
it 'returns the response json' do
|
|
147
|
-
|
|
148
|
-
code: 201, body: [{number: 1}].to_json)
|
|
199
|
+
allow_any_instance_of(CobotClient::Request).to receive(:submit) {
|
|
200
|
+
cobot_client_response(code: 201, body: [{number: 1}].to_json)
|
|
201
|
+
}
|
|
149
202
|
|
|
150
203
|
expect(api_client.post('co-up', '/invoices', {})).to eql([{number: 1}])
|
|
151
204
|
end
|
|
152
205
|
|
|
153
206
|
it 'returns nil when the status code is 204' do
|
|
154
|
-
|
|
155
|
-
body: '')
|
|
207
|
+
allow_any_instance_of(CobotClient::Request).to receive(:submit) {
|
|
208
|
+
cobot_client_response(code: 204, body: '')
|
|
209
|
+
}
|
|
156
210
|
|
|
157
211
|
expect(api_client.post('co-up', '/invoices', {})).to be_nil
|
|
158
212
|
end
|
|
159
213
|
end
|
|
160
214
|
|
|
161
|
-
|
|
162
|
-
it '
|
|
163
|
-
|
|
164
|
-
|
|
215
|
+
describe '#get' do
|
|
216
|
+
it 'accepts a subdomain' do
|
|
217
|
+
request = stub_request(:get, 'https://co-up.cobot.me/api/invoices?from=2013-10-6&to=2013-10-12')
|
|
218
|
+
.with(headers:
|
|
219
|
+
{
|
|
220
|
+
'User-Agent' => 'test agent',
|
|
221
|
+
'Authorization' => 'Bearer token-123'
|
|
222
|
+
})
|
|
223
|
+
.and_return(default_response)
|
|
165
224
|
|
|
166
225
|
api_client.get 'co-up', '/invoices', {from: '2013-10-6', to: '2013-10-12'}
|
|
226
|
+
|
|
227
|
+
expect(request).to have_been_made.once
|
|
167
228
|
end
|
|
168
229
|
|
|
169
230
|
it 'accepts a url' do
|
|
170
|
-
|
|
171
|
-
|
|
231
|
+
request = stub_request(:get, 'https://co-up.cobot.me/api/invoices?from=2013-10-6&to=2013-10-12')
|
|
232
|
+
.with(headers:
|
|
233
|
+
{
|
|
234
|
+
'User-Agent' => 'test agent',
|
|
235
|
+
'Authorization' => 'Bearer token-123'
|
|
236
|
+
})
|
|
237
|
+
.and_return(default_response)
|
|
172
238
|
|
|
173
239
|
api_client.get 'https://co-up.cobot.me/api/invoices', {from: '2013-10-6', to: '2013-10-12'}
|
|
240
|
+
|
|
241
|
+
expect(request).to have_been_made.once
|
|
174
242
|
end
|
|
175
243
|
|
|
176
244
|
it 'returns the response json' do
|
|
177
|
-
|
|
245
|
+
allow_any_instance_of(CobotClient::Request).to receive(:submit) { cobot_client_response(code: 200, body: [{number: 1}].to_json) }
|
|
178
246
|
|
|
179
247
|
expect(api_client.get('co-up', '/invoices')).to eql([{number: 1}])
|
|
180
248
|
end
|
|
181
249
|
|
|
182
|
-
it 'converts a
|
|
183
|
-
|
|
250
|
+
it 'converts a net/http error into a cobot error' do
|
|
251
|
+
allow_any_instance_of(CobotClient::Request).to receive(:submit).and_raise(Timeout::Error.new)
|
|
184
252
|
|
|
185
253
|
expect do
|
|
186
254
|
api_client.get('co-up', '/invoices')
|
|
187
|
-
end.to raise_error(CobotClient::
|
|
255
|
+
end.to raise_error(CobotClient::ConnectionError)
|
|
188
256
|
end
|
|
189
257
|
|
|
190
|
-
it 'retries a
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
count += 1
|
|
195
|
-
fail RestClient::RequestTimeout
|
|
196
|
-
else
|
|
197
|
-
double(:response, body: '{}')
|
|
198
|
-
end
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
expect(RestClient).to receive(:get).exactly(2).times
|
|
258
|
+
it 'retries a Net::ReadTimeout' do
|
|
259
|
+
stub_request(:get, 'https://co-up.cobot.me/api/invoices')
|
|
260
|
+
.to_raise(Net::ReadTimeout.new)
|
|
261
|
+
.to_return(status: 200, body: '{}')
|
|
202
262
|
|
|
203
263
|
api_client.get('co-up', '/invoices')
|
|
264
|
+
|
|
265
|
+
expect(a_request(:get, 'https://co-up.cobot.me/api/invoices')).to have_been_made.twice
|
|
204
266
|
end
|
|
205
267
|
|
|
206
|
-
it 'converts a
|
|
207
|
-
|
|
268
|
+
it 'converts a Net::ReadTimeout into a CobotClient::ConnectionError' do
|
|
269
|
+
allow_any_instance_of(CobotClient::Request).to receive(:submit).and_raise(Net::ReadTimeout.new)
|
|
208
270
|
|
|
209
271
|
expect do
|
|
210
272
|
api_client.get('co-up', '/invoices')
|
|
211
|
-
end.to raise_error(CobotClient::
|
|
273
|
+
end.to raise_error(CobotClient::ConnectionError, /^Net::ReadTimeout: /)
|
|
212
274
|
end
|
|
213
275
|
|
|
214
276
|
it 'includes the response, http code and http body in the exception' do
|
|
215
|
-
response =
|
|
216
|
-
error =
|
|
217
|
-
|
|
277
|
+
response = cobot_client_response(code: 404, body: 'boom')
|
|
278
|
+
error = response.to_error
|
|
279
|
+
allow_any_instance_of(CobotClient::Request).to receive(:submit).and_raise(error)
|
|
218
280
|
|
|
219
281
|
begin
|
|
220
282
|
api_client.get('co-up', '/invoices')
|
|
221
|
-
rescue CobotClient::
|
|
283
|
+
rescue CobotClient::ResponseError => e
|
|
284
|
+
expect(e).to be_a(CobotClient::NotFound)
|
|
222
285
|
expect(e.response).to eql(response)
|
|
223
|
-
expect(e.http_code).to
|
|
286
|
+
expect(e.http_code).to be(404)
|
|
224
287
|
expect(e.http_body).to eql('boom')
|
|
225
288
|
end
|
|
226
289
|
end
|
|
227
290
|
end
|
|
228
291
|
|
|
229
|
-
|
|
230
|
-
it '
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
292
|
+
describe '#delete' do
|
|
293
|
+
it 'accepts a subdomain' do
|
|
294
|
+
request = stub_request(:delete, 'https://co-up.cobot.me/api/invoices/1')
|
|
295
|
+
.with(
|
|
296
|
+
headers: {
|
|
297
|
+
'User-Agent' => 'test agent',
|
|
298
|
+
'Authorization' => 'Bearer token-123'
|
|
299
|
+
}
|
|
300
|
+
).and_return(default_response)
|
|
234
301
|
|
|
235
302
|
api_client.delete 'co-up', '/invoices/1'
|
|
303
|
+
|
|
304
|
+
expect(request).to have_been_made.once
|
|
236
305
|
end
|
|
237
306
|
|
|
238
307
|
it 'accepts a url' do
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
308
|
+
request = stub_request(:delete, 'https://co-up.cobot.me/api/invoices/1')
|
|
309
|
+
.with(
|
|
310
|
+
headers: {
|
|
311
|
+
'User-Agent' => 'test agent',
|
|
312
|
+
'Authorization' => 'Bearer token-123'
|
|
313
|
+
}
|
|
314
|
+
).and_return(default_response)
|
|
242
315
|
|
|
243
316
|
api_client.delete 'https://co-up.cobot.me/api/invoices/1'
|
|
317
|
+
|
|
318
|
+
expect(request).to have_been_made.once
|
|
244
319
|
end
|
|
245
320
|
end
|
|
246
321
|
end
|