rest_api_builder 0.1.3 → 0.2.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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d192a166c3b73c990be9893ac5f08bfd601aed7c4cc9c8bd8419ce2fe20c32be
|
4
|
+
data.tar.gz: 9d9974f0d2451412333dec8979a8bcdd3268b7bba8d15f58d7ef9ce4ccb63f31
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 23676f348f1feb5cb3b6d66b452af4ced13358ceec0f91591279d0db73e48b02bb06e415252c2a08708afc12fc6916c2d679dcffef3b6f625b58e2194ef36077
|
7
|
+
data.tar.gz: ce0e28889a73b8cc2924cc855e3feef7da8dbbca0d78551ad5cfd5c23ade751ffd9e11b42af711d19826614993fa94fa31544c371221e617f94ad06ef3fe57d5
|
data/README.md
CHANGED
@@ -8,193 +8,339 @@ RestClient is great, but after building a few API clients with it you will almos
|
|
8
8
|
- Handling and extracting details from non-200 responses
|
9
9
|
- Creating testing interfaces for your API clients
|
10
10
|
|
11
|
-
This library
|
11
|
+
This library tries to solve these and similar issues by providing a set of self-contained helper methods to improve on [rest-client](https://github.com/rest-client/rest-client) features with an optional [WebMock](https://github.com/bblimke/webmock) testing interface.
|
12
12
|
|
13
13
|
## Installation
|
14
14
|
```
|
15
15
|
gem install rest_api_builder
|
16
16
|
```
|
17
17
|
|
18
|
-
##
|
19
|
-
|
18
|
+
## RestAPIBuilder::Request
|
19
|
+
Main RestAPIBuilder module which includes various helper methods for parsing RestClient responses, catching errors and composing request details. `handle_*` and `compose_*` methods are intended to be used in conjunction, but you can use any of them in any combination without relying on the rest.
|
20
|
+
|
20
21
|
```rb
|
21
|
-
|
22
|
-
|
23
|
-
|
22
|
+
# Basic usage
|
23
|
+
require 'rest_api_builder'
|
24
|
+
include RestAPIBuilder::Request
|
25
|
+
|
26
|
+
logger = Logger.new(STDOUT)
|
27
|
+
response = handle_json_response(logger: logger) do
|
28
|
+
RestClient::Request.execute(
|
29
|
+
{
|
30
|
+
**compose_json_request_options(
|
31
|
+
base_url: 'https://api.github.com',
|
32
|
+
path: '/users/octocat/orgs',
|
33
|
+
method: :get
|
34
|
+
),
|
35
|
+
log: logger
|
36
|
+
}
|
37
|
+
)
|
38
|
+
end
|
24
39
|
|
25
|
-
|
40
|
+
response[:success] # => true
|
41
|
+
response[:status] # => 200
|
42
|
+
response[:body] # => []
|
43
|
+
```
|
26
44
|
|
27
|
-
|
28
|
-
require 'test_helper'
|
45
|
+
Included methods:
|
29
46
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
47
|
+
### `#handle_response(options, &block)`
|
48
|
+
Executes given block, expecting to receive RestClient::Response as a result.\
|
49
|
+
Returns plain ruby hash with following keys: `:success, :status, :body, :headers`\
|
50
|
+
This will gracefully handle non-200 responses, but will throw on any error without defined response(e.g server timeout)
|
34
51
|
|
35
|
-
|
36
|
-
|
37
|
-
|
52
|
+
```rb
|
53
|
+
require 'rest_api_builder'
|
54
|
+
include RestAPIBuilder::Request
|
55
|
+
|
56
|
+
# normal response
|
57
|
+
response = handle_response do
|
58
|
+
RestClient::Request.execute(method: :get, url: 'https://api.github.com/users/octocat/orgs')
|
59
|
+
end
|
60
|
+
|
61
|
+
response[:success] # => true
|
62
|
+
response[:status] # => 200
|
63
|
+
response[:body] # => '[]'
|
64
|
+
response[:headers] # => {:accept_ranges=>"bytes", :access_control_allow_origin=>"*", ...}
|
65
|
+
|
66
|
+
# non-200 response that would result in RestClient::RequestFailed exception otherwise
|
67
|
+
response = handle_response do
|
68
|
+
RestClient::Request.execute(method: :get, url: 'https://api.github.com/users/octocat/foobar')
|
69
|
+
end
|
70
|
+
|
71
|
+
response[:success] # => false
|
72
|
+
response[:status] # => 404
|
73
|
+
response[:body] # => "{\"message\":\"Not Found\",..."}"
|
74
|
+
```
|
75
|
+
|
76
|
+
#### Accepted Options:
|
77
|
+
| Name | Description |
|
78
|
+
|--------|-------------|
|
79
|
+
| logger | Any object with `<<` method, e.g `Logger` instance. Will be used to log *response* details in the same way that [RestClient's `log` option](https://github.com/rest-client/rest-client#logging) logs the request details. Optional |
|
80
|
+
|
81
|
+
### `#handle_json_response(options, &block)`
|
82
|
+
Behaves just like `#handle_response`, but will also attempt to decode response `:body`, returning it as is if a parsing error occurs.
|
83
|
+
|
84
|
+
```rb
|
85
|
+
require 'rest_api_builder'
|
86
|
+
include RestAPIBuilder::Request
|
87
|
+
|
88
|
+
# decodes JSON response body
|
89
|
+
response = handle_json_response do
|
90
|
+
RestClient::Request.execute(method: :get, url: 'https://api.github.com/users/octocat/orgs')
|
91
|
+
end
|
92
|
+
|
93
|
+
response[:success] # => true
|
94
|
+
response[:status] # => 200
|
95
|
+
response[:body] # => []
|
96
|
+
|
97
|
+
# returns body as is if it cannot be decoded
|
98
|
+
response = handle_json_response do
|
99
|
+
RestClient::Request.execute(method: :get, url: 'https://github.com/foo/bar/test')
|
100
|
+
end
|
101
|
+
|
102
|
+
response[:success] # => false
|
103
|
+
response[:status] # => 404
|
104
|
+
response[:body] # => "Not Found"
|
38
105
|
```
|
39
106
|
|
40
|
-
`
|
107
|
+
### `handle_response_error(&block)`
|
108
|
+
Low-level API.\
|
109
|
+
You can use this method if you want to work with regular `RestClient::Response` objects directly(e.g when using `block_response` or `raw_response` options). This will handle non-200 exceptions but will not do anything else.\
|
110
|
+
Returns plain ruby hash with `:success` and `:raw_response` keys.
|
41
111
|
|
42
|
-
## Usage
|
43
112
|
```rb
|
44
|
-
require
|
113
|
+
require 'rest_api_builder'
|
114
|
+
include RestAPIBuilder::Request
|
45
115
|
|
46
|
-
|
47
|
-
|
116
|
+
# returns RestClient::Response as :raw_response
|
117
|
+
response = handle_response_error do
|
118
|
+
RestClient::Request.execute(method: :get, url: 'https://api.github.com/users/octocat/orgs')
|
119
|
+
end
|
48
120
|
|
49
|
-
|
50
|
-
|
51
|
-
RestClient::Request.execute(compose_request_options(**options))
|
52
|
-
end
|
53
|
-
end
|
121
|
+
response[:success] # => true
|
122
|
+
response[:raw_response] # => <RestClient::Response 200 "[]">
|
54
123
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
124
|
+
# handles non-200 responses
|
125
|
+
response = handle_response_error do
|
126
|
+
RestClient::Request.execute(
|
127
|
+
method: :get,
|
128
|
+
url: 'https://api.github.com/users/octocat/foobar',
|
129
|
+
raw_response: true
|
130
|
+
)
|
60
131
|
end
|
61
132
|
|
62
|
-
|
63
|
-
|
64
|
-
# Simple request:
|
65
|
-
response = my_request.execute(base_url: "example.com", method: :get)
|
66
|
-
response[:success] #=> true
|
67
|
-
response[:status] #=> 200
|
68
|
-
response[:body] #=> "<!doctype html>\n<html>..."
|
69
|
-
response[:headers] #=> {:accept_ranges=>"bytes", ...}
|
70
|
-
|
71
|
-
# Non-200 responses:
|
72
|
-
response = my_request.execute(base_url: "example.com", path: "/foo", method: :get)
|
73
|
-
response[:success] #=> false
|
74
|
-
response[:status] #=> 404
|
75
|
-
response[:body] #=> "<!doctype html>\n<html>..."
|
76
|
-
|
77
|
-
# JSON requests:
|
78
|
-
response = my_request.json_execute(base_url: "api.github.com", path: "/users/octocat/orgs", method: :get)
|
79
|
-
response[:success] #=> true
|
80
|
-
response[:body] #=> []
|
133
|
+
response[:success] # => false
|
134
|
+
response[:raw_response] # => <RestClient::RawResponse @code=404, @file=#<Tempfile...>>
|
81
135
|
```
|
82
136
|
|
83
|
-
|
137
|
+
### `#compose_request_options(options)`
|
138
|
+
Provides a more consistent interface for `RestClient::Request#execute`.\
|
139
|
+
This method returns a hash of options which you can then pass to `RestClient::Request#execute`.
|
140
|
+
|
141
|
+
```rb
|
142
|
+
require 'rest_api_builder'
|
143
|
+
include RestAPIBuilder::Request
|
144
|
+
|
145
|
+
# basic usage
|
146
|
+
response = RestClient::Request.execute(
|
147
|
+
compose_request_options(
|
148
|
+
base_url: 'https://api.github.com',
|
149
|
+
path: '/users/octocat/orgs',
|
150
|
+
method: :get
|
151
|
+
)
|
152
|
+
)
|
153
|
+
|
154
|
+
response.request.url # => "https://api.github.com/users/octocat/orgs"
|
155
|
+
response.body # => '[]'
|
156
|
+
|
157
|
+
# advanced options
|
158
|
+
result = handle_response_error do
|
159
|
+
RestClient::Request.execute(
|
160
|
+
compose_request_options(
|
161
|
+
base_url: 'https://api.github.com',
|
162
|
+
path: '/users/octocat/orgs',
|
163
|
+
method: :post,
|
164
|
+
body: 'Hello',
|
165
|
+
headers: { content_type: 'foobar' },
|
166
|
+
query: { foo: 'bar' }
|
167
|
+
)
|
168
|
+
)
|
169
|
+
end
|
170
|
+
request = result[:raw_response].request
|
171
|
+
|
172
|
+
request.url # => "https://api.github.com/users/octocat/orgs?foo=bar"
|
173
|
+
request.headers # => {:content_type=>"foobar"}
|
174
|
+
request.payload # => <RestClient::Payload 'Hello'>
|
175
|
+
```
|
176
|
+
|
177
|
+
#### Accepted Options:
|
178
|
+
| Name | Description |
|
179
|
+
|----------|-------------|
|
180
|
+
| base_url | Base URL of the request. Required. |
|
181
|
+
| method | HTTP method of the request(e.g :get, :post, :patch). Required. |
|
182
|
+
| path | Path to be appended to `base_url`. Optional. |
|
183
|
+
| body | Request Body. Optional. |
|
184
|
+
| headers | Request Headers. Optional. |
|
185
|
+
| query | Query hash to be appended to the resulting url. Optional. |
|
186
|
+
|
187
|
+
### `#compose_json_request_options(options)`
|
188
|
+
Same as `compose_request_options` but will also convert provided `body`(if any) to JSON and append `Content-Type: 'application/json'` to `headers`
|
189
|
+
|
84
190
|
```rb
|
85
|
-
require
|
86
|
-
|
87
|
-
|
191
|
+
require 'rest_api_builder'
|
192
|
+
include RestAPIBuilder::Request
|
193
|
+
|
194
|
+
# basic usage
|
195
|
+
result = handle_response_error do
|
196
|
+
RestClient::Request.execute(
|
197
|
+
compose_json_request_options(
|
198
|
+
base_url: 'https://api.github.com',
|
199
|
+
path: '/users/octocat/orgs',
|
200
|
+
method: :post,
|
201
|
+
body: {a: 1}
|
202
|
+
)
|
203
|
+
)
|
204
|
+
end
|
205
|
+
request = result[:raw_response].request
|
88
206
|
|
89
|
-
|
207
|
+
request.headers # => {:content_type=>:json}
|
208
|
+
request.payload # => <RestClient::Payload "{\"a\":1}">
|
209
|
+
```
|
210
|
+
|
211
|
+
## RestAPIBuilder::APIClient
|
90
212
|
|
91
|
-
|
92
|
-
|
213
|
+
### `#define_resource_shortcuts(resources, resources_scope:, init_with:)`
|
214
|
+
Dynamically defines attribute readers for given resources
|
93
215
|
|
94
|
-
|
95
|
-
|
96
|
-
|
216
|
+
```rb
|
217
|
+
require 'rest_api_builder'
|
218
|
+
|
219
|
+
module ReadmeExamples
|
220
|
+
module Resources
|
221
|
+
class Octocat
|
222
|
+
def orgs
|
223
|
+
RestClient::Request.execute(method: :get, url: 'https://api.github.com/users/octocat/orgs')
|
224
|
+
end
|
97
225
|
end
|
98
226
|
end
|
99
227
|
|
100
|
-
|
101
|
-
|
102
|
-
|
228
|
+
class APIClient
|
229
|
+
include RestAPIBuilder::APIClient
|
230
|
+
|
231
|
+
def initialize
|
232
|
+
define_resource_shortcuts(
|
233
|
+
[:octocat],
|
234
|
+
resources_scope: ReadmeExamples::Resources,
|
235
|
+
init_with: ->(resource_class) { resource_class.new }
|
236
|
+
)
|
103
237
|
end
|
104
238
|
end
|
105
239
|
end
|
106
240
|
|
107
|
-
my_request = MyRequest.new
|
108
241
|
|
109
|
-
|
242
|
+
GITHUB_API = ReadmeExamples::APIClient.new
|
110
243
|
|
111
|
-
|
112
|
-
|
113
|
-
response
|
244
|
+
response = GITHUB_API.octocat.orgs
|
245
|
+
response.body # => '[]'
|
246
|
+
response.code # => 200
|
247
|
+
```
|
114
248
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
249
|
+
#### Accepted Arguments:
|
250
|
+
| Name | Description |
|
251
|
+
|-----------------|-------------|
|
252
|
+
| resources | Array of resources to define shortcuts for |
|
253
|
+
| resources_scope | Module or String(path to Module) within which resource classes are contained |
|
254
|
+
| init_with | Lambda which will be called for each resource class. The result will be returned from the defined shortcut. **Note:** `init_with` lambda is only called once so resource class must be able to function as a singleton. |
|
119
255
|
|
120
|
-
|
121
|
-
|
122
|
-
.expect_execute(base_url: "test.com", method: :get)
|
123
|
-
.to_return(status: 404, body: "not found")
|
124
|
-
response = my_request.execute(base_url: "test.com", method: :get)
|
256
|
+
## RestAPIBuilder::WebMockRequestExpectations
|
257
|
+
Optional wrapper around WebMock mocking interface with various improvements. This module must be required explicitly and expects [WebMock](https://github.com/bblimke/webmock) to be installed as a dependency in your project.
|
125
258
|
|
126
|
-
|
127
|
-
|
128
|
-
|
259
|
+
### `#expect_execute(options)`
|
260
|
+
Defines a request expectation using WebMock's `stub_request`.
|
261
|
+
```rb
|
262
|
+
require 'rest_api_builder'
|
263
|
+
require 'rest_api_builder/webmock_request_expectations'
|
264
|
+
include RestAPIBuilder::Request
|
265
|
+
include RestAPIBuilder::WebMockRequestExpectations
|
266
|
+
|
267
|
+
# basic usage with regular webmock interface
|
268
|
+
expect_execute(
|
269
|
+
base_url: 'https://api.github.com',
|
270
|
+
path: '/users/octocat/orgs',
|
271
|
+
method: :post
|
272
|
+
).with(body: {foo: 'bar'}).to_return(body: '[hello]')
|
273
|
+
|
274
|
+
response = RestClient::Request.execute(
|
275
|
+
compose_request_options(
|
276
|
+
base_url: 'https://api.github.com',
|
277
|
+
path: '/users/octocat/orgs',
|
278
|
+
method: :post,
|
279
|
+
body: {foo: 'bar'}
|
280
|
+
)
|
281
|
+
)
|
282
|
+
|
283
|
+
response.body # => '[hello]'
|
284
|
+
|
285
|
+
# using expect_execute's request and response options
|
286
|
+
expect_execute(
|
287
|
+
base_url: 'https://api.github.com',
|
288
|
+
path: '/users/octocat',
|
289
|
+
method: :post,
|
290
|
+
# matches request body and query hashes partially by default
|
291
|
+
request: { body: {foo: 'bar'}, query: {a: 1, b: 2} },
|
292
|
+
response: { body: 'hello' }
|
293
|
+
)
|
129
294
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
295
|
+
response = RestClient::Request.execute(
|
296
|
+
compose_request_options(
|
297
|
+
base_url: 'https://api.github.com',
|
298
|
+
path: '/users/octocat',
|
299
|
+
method: :post,
|
300
|
+
body: { foo: 'bar', bar: 'baz' },
|
301
|
+
query: { a: 1, b: 2 }
|
302
|
+
)
|
136
303
|
)
|
137
|
-
response = my_request.json_execute(base_url: "test.com", method: :post, body: { foo: "bar", bar: "baz" })
|
138
|
-
response[:success] #=> true
|
139
|
-
response[:body] #=> 'hello'
|
140
304
|
|
141
|
-
|
305
|
+
response.body # => 'hello'
|
306
|
+
```
|
307
|
+
|
308
|
+
#### Accepted Options:
|
309
|
+
| Name | Description |
|
310
|
+
|----------|-------------|
|
311
|
+
| base_url | Base URL of the request expectation. Required. |
|
312
|
+
| path | HTTP method of the request. Required. |
|
313
|
+
| method | Path to be appended to `base_url`. Regular expressions are also supported. Optional. |
|
314
|
+
| request | Hash of options which will be passed to WebMock's `with` method with following changes: `body` hash is converted to `hash_including` expectation and `query` hash values are transformed to strings and then it's converted into `hash_including` expectation. Optional |
|
315
|
+
| response | Hash of options which will be passed to WebMock's `to_return` method unchanged. Optional |
|
142
316
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
317
|
+
### `#expect_json_execute(options)`
|
318
|
+
Same as `expect_execute` but will also call JSON encode on `response.body`(if one is provided).
|
319
|
+
|
320
|
+
```rb
|
321
|
+
require 'rest_api_builder'
|
322
|
+
require 'rest_api_builder/webmock_request_expectations'
|
323
|
+
include RestAPIBuilder::Request
|
324
|
+
include RestAPIBuilder::WebMockRequestExpectations
|
325
|
+
|
326
|
+
expect_json_execute(
|
327
|
+
base_url: 'https://api.github.com',
|
328
|
+
path: '/users/octocat/orgs',
|
329
|
+
method: :get,
|
330
|
+
response: { body: { foo: 'bar' } }
|
148
331
|
)
|
149
|
-
|
150
|
-
response
|
151
|
-
|
332
|
+
|
333
|
+
response = RestClient::Request.execute(
|
334
|
+
compose_request_options(
|
335
|
+
base_url: 'https://api.github.com',
|
336
|
+
path: '/users/octocat/orgs',
|
337
|
+
method: :get
|
338
|
+
)
|
339
|
+
)
|
340
|
+
|
341
|
+
response.body # => "{\"foo\":\"bar\"}"
|
152
342
|
```
|
153
343
|
|
154
|
-
## Request API
|
155
|
-
### RestAPIBuilder#compose_request_options(options)
|
156
|
-
Composes request options that can be passed to `RestClient::Request.execute`.
|
157
|
-
#### Options:
|
158
|
-
* **base_url**: Base URL of the request. Required.
|
159
|
-
* **method**: HTTP method of the request(e.g :get, :post, :patch). Required.
|
160
|
-
* **path**: Path to be appended to the :base_url. Optional.
|
161
|
-
* **body**: Request Body. Optional.
|
162
|
-
* **headers**: Request Headers. Optional.
|
163
|
-
* **query**: Query hash to be appended to the resulting url. Optional.
|
164
|
-
|
165
|
-
### RestAPIBuilder#compose_json_request_options(options)
|
166
|
-
Accepts same options as `compose_request_options` but will also:
|
167
|
-
- Add `Content-Type: 'application/json'` to request `headers`
|
168
|
-
- Convert request `body` to JSON if it's present
|
169
|
-
|
170
|
-
### RestAPIBuilder#handle_response(options, &block)
|
171
|
-
Executes given block, expecting to receive `RestClient::Response` as a result.\
|
172
|
-
Returns **plain ruby hash** with following keys: `:success`, `:status`, `:body`, `:headers`\
|
173
|
-
This will also gracefully handle non-200 responses, but will throw on any error without defined response(e.g server timeout)
|
174
|
-
|
175
|
-
#### Options:
|
176
|
-
* **logger**: A `Logger` instance. If provided, will log response details as RestClient wont do this by default. Optional
|
177
|
-
|
178
|
-
### RestAPIBuilder#handle_json_response(options, &block)
|
179
|
-
Same as `#handle_response` but will also attempt to decode response `:body`, returning it as is if a parsing error occurrs
|
180
|
-
|
181
|
-
### RestAPIBuilder#handle_response_error(options, &block)
|
182
|
-
Low-level API, you can use this method if you want to work with the RestClient's responses directly without any conversions(e.g when using `block_response` or `raw_response` options of RestClient). This will handle errors in the same way as `#handle_response` does, but will not do anything else.\
|
183
|
-
Returns ruby hash with `:success` and `:raw_response` keys.
|
184
|
-
|
185
|
-
## WebMockRequestExpectations API
|
186
|
-
### RestAPIBuilder::WebMockRequestExpectations.expect_execute(options)
|
187
|
-
Defines a request expectation using WebMock's `stub_request`. Returns an instance of `WebMock::RequestStub` on which methods such as `with`, `to_return`, `to_timeout` can be called.
|
188
|
-
|
189
|
-
#### Options:
|
190
|
-
* **base_url**: Base URL of the request. Required.
|
191
|
-
* **method**: HTTP method of the request(e.g :get, :post, :patch). Required.
|
192
|
-
* **path**: Path to be appended to the :base_url. Optional.
|
193
|
-
* **request**: request details which will be passed to `WebMock::RequestStub#with` if provided. If `query` or `body` keys are present and are hashes, they will be converted into WebMock's `hash_including` matcher. Optional
|
194
|
-
* **response**: response details which will be passed to `WebMock::RequestStub#to_return` if provided. Optional
|
195
|
-
|
196
|
-
### RestAPIBuilder::WebMockRequestExpectations.expect_json_execute(options)
|
197
|
-
A convenience shortcut for `#json_execute` which will convert `request[:body]` to JSON if it's present
|
198
344
|
|
199
345
|
## License
|
200
|
-
MIT
|
346
|
+
MIT
|
data/lib/rest_api_builder.rb
CHANGED
@@ -1,45 +1,10 @@
|
|
1
|
-
require '
|
2
|
-
require 'rest_api_builder/
|
1
|
+
require 'forwardable'
|
2
|
+
require 'rest_api_builder/webmock_request_expectations/expectations'
|
3
3
|
|
4
4
|
module RestAPIBuilder
|
5
|
-
|
6
|
-
|
7
|
-
include RestAPIBuilder::Helpers::UrlHelper
|
5
|
+
module WebMockRequestExpectations
|
6
|
+
extend Forwardable
|
8
7
|
|
9
|
-
|
10
|
-
if response && response[:body]
|
11
|
-
response = response.merge(body: JSON.generate(response[:body]))
|
12
|
-
end
|
13
|
-
|
14
|
-
expect_execute(**options, response: response)
|
15
|
-
end
|
16
|
-
|
17
|
-
def expect_execute(base_url:, method:, path: nil, request: nil, response: nil)
|
18
|
-
url = path.is_a?(Regexp) ? /#{base_url}#{path}/ : full_url(base_url, path)
|
19
|
-
expectation = stub_request(method, url)
|
20
|
-
|
21
|
-
if !request.nil? && request.any?
|
22
|
-
add_request_expectations(expectation, request)
|
23
|
-
end
|
24
|
-
|
25
|
-
expectation.to_return(response) if response
|
26
|
-
|
27
|
-
expectation
|
28
|
-
end
|
29
|
-
|
30
|
-
def add_request_expectations(expectation, request)
|
31
|
-
if request[:body].is_a?(Hash)
|
32
|
-
request = request.merge(body: hash_including(request[:body]))
|
33
|
-
end
|
34
|
-
|
35
|
-
if request[:query].is_a?(Hash)
|
36
|
-
query = request[:query].transform_values(&:to_s)
|
37
|
-
request = request.merge(query: hash_including(query))
|
38
|
-
end
|
39
|
-
|
40
|
-
expectation.with(request)
|
41
|
-
end
|
8
|
+
def_delegators Expectations, :expect_json_execute, :expect_execute
|
42
9
|
end
|
43
|
-
|
44
|
-
WebMockRequestExpectations = WebMockRequestExpectationsSingleton.new
|
45
10
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'webmock'
|
2
|
+
require 'rest_api_builder/helpers/url_helper'
|
3
|
+
|
4
|
+
module RestAPIBuilder
|
5
|
+
module WebMockRequestExpectations
|
6
|
+
module Expectations
|
7
|
+
extend WebMock::API
|
8
|
+
extend RestAPIBuilder::Helpers::UrlHelper
|
9
|
+
|
10
|
+
module_function
|
11
|
+
|
12
|
+
def expect_json_execute(response: nil, **options)
|
13
|
+
if response && response[:body]
|
14
|
+
response = response.merge(body: JSON.generate(response[:body]))
|
15
|
+
end
|
16
|
+
|
17
|
+
expect_execute(**options, response: response)
|
18
|
+
end
|
19
|
+
|
20
|
+
def expect_execute(base_url:, method:, path: nil, request: nil, response: nil)
|
21
|
+
url = path.is_a?(Regexp) ? /#{base_url}#{path}/ : full_url(base_url, path)
|
22
|
+
expectation = stub_request(method, url)
|
23
|
+
|
24
|
+
if !request.nil? && request.any?
|
25
|
+
add_request_expectations(expectation, request)
|
26
|
+
end
|
27
|
+
|
28
|
+
expectation.to_return(response) if response
|
29
|
+
|
30
|
+
expectation
|
31
|
+
end
|
32
|
+
|
33
|
+
def add_request_expectations(expectation, request)
|
34
|
+
if request[:body].is_a?(Hash)
|
35
|
+
request = request.merge(body: hash_including(request[:body]))
|
36
|
+
end
|
37
|
+
|
38
|
+
if request[:query].is_a?(Hash)
|
39
|
+
query = request[:query].transform_values(&:to_s)
|
40
|
+
request = request.merge(query: hash_including(query))
|
41
|
+
end
|
42
|
+
|
43
|
+
expectation.with(request)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/rest_api_builder.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'rest_api_builder'
|
3
|
-
s.version = '0.
|
3
|
+
s.version = '0.2.0'
|
4
4
|
s.summary = "A simple wrapper for rest-client"
|
5
5
|
s.description = "A simple wrapper for rest-client aiming to make creation and testing of API clients easier."
|
6
6
|
s.authors = ["Alexey D"]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rest_api_builder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexey D
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-10-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|
@@ -69,6 +69,7 @@ files:
|
|
69
69
|
- lib/rest_api_builder/request/request_options.rb
|
70
70
|
- lib/rest_api_builder/request/response_handler.rb
|
71
71
|
- lib/rest_api_builder/webmock_request_expectations.rb
|
72
|
+
- lib/rest_api_builder/webmock_request_expectations/expectations.rb
|
72
73
|
- rest_api_builder.gemspec
|
73
74
|
homepage: https://github.com/alexeyds/rest_api_builder
|
74
75
|
licenses:
|