api_struct 1.0.1 → 1.0.2
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/Gemfile.lock +10 -8
- data/README.md +1 -1
- data/api_struct.gemspec +1 -0
- data/lib/api_struct.rb +1 -0
- data/lib/api_struct/client.rb +2 -0
- data/lib/api_struct/concerns/underscore.rb +1 -5
- data/lib/api_struct/entity.rb +6 -1
- data/lib/api_struct/version.rb +1 -1
- data/spec/api_struct/client_spec.rb +32 -10
- data/spec/api_struct/entity_spec.rb +2 -1
- data/spec/fixtures/cassettes/posts/show_success.yml +1 -0
- data/spec/fixtures/cassettes/user_todos.yml +189 -0
- data/spec/support/stub.rb +2 -2
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1846d9253d9d3bb8e7d8ed18ba445cebabf26b27
|
4
|
+
data.tar.gz: cdd2bc6c8104216e2938c2369120daeaaa1c0f0f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 10c829780bff7016d56f7b3f53cd4b8b87e2a17193699c99653d5d7c5cedfb820603686992287198de61bebf05dd2a98e314046b4020a3b71c7301dcd8debb6e
|
7
|
+
data.tar.gz: de365513a4d9f53c31077379b95ae81f7cc47d464bb1043d844ee4cb2eec32670f9b43423130919c39cb481656b275db4fd74f4bf2cbae02ae0ee29a2c17691d
|
data/Gemfile.lock
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
api_struct (1.0.
|
4
|
+
api_struct (1.0.1)
|
5
5
|
dry-configurable (~> 0.7.0)
|
6
|
+
dry-inflector (~> 0.1.2)
|
6
7
|
dry-monads (~> 1.0)
|
7
8
|
hashie (~> 3.5, >= 3.5.6)
|
8
9
|
http (>= 2.0.3)
|
@@ -15,7 +16,7 @@ GEM
|
|
15
16
|
ast (2.3.0)
|
16
17
|
byebug (9.1.0)
|
17
18
|
coderay (1.1.2)
|
18
|
-
concurrent-ruby (1.1.
|
19
|
+
concurrent-ruby (1.1.5)
|
19
20
|
crack (0.4.3)
|
20
21
|
safe_yaml (~> 1.0.0)
|
21
22
|
diff-lcs (1.3)
|
@@ -23,17 +24,18 @@ GEM
|
|
23
24
|
unf (>= 0.0.5, < 1.0.0)
|
24
25
|
dry-configurable (0.7.0)
|
25
26
|
concurrent-ruby (~> 1.0)
|
26
|
-
dry-core (0.4.
|
27
|
+
dry-core (0.4.8)
|
27
28
|
concurrent-ruby (~> 1.0)
|
28
|
-
dry-equalizer (0.2.
|
29
|
-
dry-
|
29
|
+
dry-equalizer (0.2.2)
|
30
|
+
dry-inflector (0.1.2)
|
31
|
+
dry-monads (1.2.0)
|
30
32
|
concurrent-ruby (~> 1.0)
|
31
33
|
dry-core (~> 0.4, >= 0.4.4)
|
32
34
|
dry-equalizer
|
33
35
|
ffaker (2.8.0)
|
34
36
|
hashdiff (0.3.7)
|
35
37
|
hashie (3.6.0)
|
36
|
-
http (4.
|
38
|
+
http (4.1.1)
|
37
39
|
addressable (~> 2.3)
|
38
40
|
http-cookie (~> 1.0)
|
39
41
|
http-form_data (~> 2.0)
|
@@ -80,7 +82,7 @@ GEM
|
|
80
82
|
safe_yaml (1.0.4)
|
81
83
|
unf (0.1.4)
|
82
84
|
unf_ext
|
83
|
-
unf_ext (0.0.7.
|
85
|
+
unf_ext (0.0.7.6)
|
84
86
|
unicode-display_width (1.3.0)
|
85
87
|
vcr (3.0.3)
|
86
88
|
webmock (3.2.1)
|
@@ -103,4 +105,4 @@ DEPENDENCIES
|
|
103
105
|
webmock (~> 3.2, >= 3.2.1)
|
104
106
|
|
105
107
|
BUNDLED WITH
|
106
|
-
1.17.
|
108
|
+
1.17.3
|
data/README.md
CHANGED
data/api_struct.gemspec
CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_dependency 'dry-monads', '~> 1.0'
|
22
22
|
spec.add_dependency 'dry-configurable', '~> 0.7.0'
|
23
|
+
spec.add_dependency 'dry-inflector', '~> 0.1.2'
|
23
24
|
spec.add_dependency 'http', '>= 2.0.3'
|
24
25
|
spec.add_dependency 'hashie', '~> 3.5', '>= 3.5.6'
|
25
26
|
|
data/lib/api_struct.rb
CHANGED
data/lib/api_struct/client.rb
CHANGED
@@ -13,6 +13,7 @@ module ApiStruct
|
|
13
13
|
return super unless endpoints.keys.include?(method_name)
|
14
14
|
|
15
15
|
define_method(:api_root) { endpoints[method_name][:root] }
|
16
|
+
define_method(:default_params) { endpoints[method_name][:params] || {} }
|
16
17
|
define_method(:default_path) { first_arg(args) }
|
17
18
|
|
18
19
|
define_method(:headers) do
|
@@ -25,6 +26,7 @@ module ApiStruct
|
|
25
26
|
HTTP_METHODS.each do |http_method|
|
26
27
|
define_method http_method do |*args, **options|
|
27
28
|
begin
|
29
|
+
options[:params] = default_params.merge(options[:params] || {})
|
28
30
|
wrap client.send(http_method, build_url(args, options), options)
|
29
31
|
rescue HTTP::ConnectionError => e
|
30
32
|
failure(body: e.message, status: :not_connected)
|
@@ -1,11 +1,7 @@
|
|
1
1
|
module Concerns
|
2
2
|
module Underscore
|
3
3
|
def underscore(camel_cased_word)
|
4
|
-
|
5
|
-
.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
6
|
-
.gsub(/([a-z\d])([A-Z])/,'\1_\2')
|
7
|
-
.tr("-", "_")
|
8
|
-
.downcase
|
4
|
+
Dry::Inflector.new.underscore(camel_cased_word)
|
9
5
|
end
|
10
6
|
end
|
11
7
|
end
|
data/lib/api_struct/entity.rb
CHANGED
@@ -76,7 +76,12 @@ module ApiStruct
|
|
76
76
|
private
|
77
77
|
|
78
78
|
def extract_attributes(attributes)
|
79
|
-
attributes.
|
79
|
+
formatted_attributes = attributes.map { |name, value| [format_name(name), value] }.to_h
|
80
|
+
formatted_attributes.select { |key, _value| self.class.entity_attributes.include?(key.to_sym) }
|
81
|
+
end
|
82
|
+
|
83
|
+
def format_name(name)
|
84
|
+
Dry::Inflector.new.underscore(name).to_sym
|
80
85
|
end
|
81
86
|
end
|
82
87
|
|
data/lib/api_struct/version.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
describe ApiStruct::Client do
|
2
2
|
extend Support::Stub
|
3
|
-
|
4
|
-
|
3
|
+
API_ROOT = 'https://jsonplaceholder.typicode.com'
|
4
|
+
|
5
|
+
let(:api_root) { API_ROOT }
|
6
|
+
stub_api(API_ROOT)
|
7
|
+
let(:client) { StubClient.new }
|
5
8
|
|
6
9
|
class StubClient < ApiStruct::Client
|
7
10
|
stub_api :posts
|
@@ -17,7 +20,6 @@ describe ApiStruct::Client do
|
|
17
20
|
|
18
21
|
context 'build url options' do
|
19
22
|
context 'url options' do
|
20
|
-
let(:client) { StubClient.new }
|
21
23
|
it ' should replace /posts/users/:id to /posts/users if URL option didnt provided' do
|
22
24
|
url = client.send(:build_url, 'users/:id', {})
|
23
25
|
expect(url).to eq api_root + '/posts/users'
|
@@ -57,9 +59,10 @@ describe ApiStruct::Client do
|
|
57
59
|
expect(url).to eq api_root + '/users/1/posts/2'
|
58
60
|
end
|
59
61
|
end
|
62
|
+
|
60
63
|
it 'should build url with prefix' do
|
61
64
|
VCR.use_cassette('users/1/posts') do
|
62
|
-
response =
|
65
|
+
response = client.get(prefix: 'users/:id', id: 1)
|
63
66
|
expect(response).to be_success
|
64
67
|
expect(response.value!).to be_kind_of Array
|
65
68
|
expect(response.value!).not_to be_empty
|
@@ -68,7 +71,7 @@ describe ApiStruct::Client do
|
|
68
71
|
|
69
72
|
it 'should build url with custom path' do
|
70
73
|
VCR.use_cassette('todos') do
|
71
|
-
response =
|
74
|
+
response = client.get(path: 'todos/1')
|
72
75
|
expect(response).to be_success
|
73
76
|
expect(response.value![:id]).to eq(1)
|
74
77
|
expect(response.value![:title]).not_to be_empty
|
@@ -76,9 +79,28 @@ describe ApiStruct::Client do
|
|
76
79
|
end
|
77
80
|
end
|
78
81
|
|
82
|
+
context 'Default params' do
|
83
|
+
let(:user_id) { 2 }
|
84
|
+
|
85
|
+
before do
|
86
|
+
allow(client).to receive(:default_params).and_return(userId: user_id)
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should build url with default params' do
|
90
|
+
VCR.use_cassette('user_todos') do
|
91
|
+
response = client.get(path: 'todos')
|
92
|
+
|
93
|
+
expect(response).to be_success
|
94
|
+
response.value!.each do |response|
|
95
|
+
expect(response[:userId]).to eq(user_id)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
79
101
|
it 'should build url with prefix as array' do
|
80
102
|
VCR.use_cassette('todos') do
|
81
|
-
response =
|
103
|
+
response = client.get(path: [:todos, 1])
|
82
104
|
expect(response).to be_success
|
83
105
|
expect(response.value![:id]).to eq(1)
|
84
106
|
expect(response.value![:title]).not_to be_empty
|
@@ -90,7 +112,7 @@ describe ApiStruct::Client do
|
|
90
112
|
context 'GET' do
|
91
113
|
it 'when successful response' do
|
92
114
|
VCR.use_cassette('posts/show_success') do
|
93
|
-
response =
|
115
|
+
response = client.show(1)
|
94
116
|
expect(response).to be_success
|
95
117
|
expect(response.value![:id]).to eq(1)
|
96
118
|
expect(response.value![:title]).not_to be_empty
|
@@ -99,7 +121,7 @@ describe ApiStruct::Client do
|
|
99
121
|
|
100
122
|
it 'when failed response' do
|
101
123
|
VCR.use_cassette('posts/show_failure') do
|
102
|
-
response =
|
124
|
+
response = client.show(101)
|
103
125
|
expect(response).to be_failure
|
104
126
|
expect(response.failure.status).to eq(404)
|
105
127
|
end
|
@@ -107,7 +129,7 @@ describe ApiStruct::Client do
|
|
107
129
|
|
108
130
|
it 'when failed response with html response' do
|
109
131
|
VCR.use_cassette('posts/show_failure_html') do
|
110
|
-
response =
|
132
|
+
response = client.show(101)
|
111
133
|
body = response.failure.body
|
112
134
|
expect(response).to be_failure
|
113
135
|
expect(response.failure.status).to eq(404)
|
@@ -120,7 +142,7 @@ describe ApiStruct::Client do
|
|
120
142
|
context 'PATCH' do
|
121
143
|
it 'when successful response' do
|
122
144
|
VCR.use_cassette('posts/update_success') do
|
123
|
-
response =
|
145
|
+
response = client.update(1, title: FFaker::Name.name)
|
124
146
|
expect(response).to be_success
|
125
147
|
expect(response.value![:id]).to eq(1)
|
126
148
|
end
|
@@ -26,7 +26,7 @@ describe ApiStruct::Entity do
|
|
26
26
|
client_service StubClient, prefix: :only, only: :index
|
27
27
|
client_service StubClient, prefix: :except, except: :show
|
28
28
|
|
29
|
-
attr_entity :id, :title
|
29
|
+
attr_entity :id, :title, :camel_case
|
30
30
|
|
31
31
|
has_entity :nested_entity, as: StubNestedEntity
|
32
32
|
has_entities :another_nested_entities, as: StubNestedEntity
|
@@ -119,6 +119,7 @@ describe ApiStruct::Entity do
|
|
119
119
|
expect(entity).to be_success
|
120
120
|
expect(entity.id).to eq(1)
|
121
121
|
expect(entity.title).not_to be_empty
|
122
|
+
expect(entity.camel_case).not_to be_empty
|
122
123
|
end
|
123
124
|
end
|
124
125
|
|
@@ -66,6 +66,7 @@ http_interactions:
|
|
66
66
|
"userId": 1,
|
67
67
|
"id": 1,
|
68
68
|
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
|
69
|
+
"camelCase": "camel case property",
|
69
70
|
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
|
70
71
|
}
|
71
72
|
http_version:
|
@@ -0,0 +1,189 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: https://jsonplaceholder.typicode.com/todos?userId=2
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Accept:
|
11
|
+
- application/json
|
12
|
+
Content-Type:
|
13
|
+
- application/json
|
14
|
+
Connection:
|
15
|
+
- close
|
16
|
+
Host:
|
17
|
+
- jsonplaceholder.typicode.com
|
18
|
+
User-Agent:
|
19
|
+
- http.rb/4.1.1
|
20
|
+
response:
|
21
|
+
status:
|
22
|
+
code: 200
|
23
|
+
message: OK
|
24
|
+
headers:
|
25
|
+
Date:
|
26
|
+
- Wed, 17 Apr 2019 18:24:07 GMT
|
27
|
+
Content-Type:
|
28
|
+
- application/json; charset=utf-8
|
29
|
+
Transfer-Encoding:
|
30
|
+
- chunked
|
31
|
+
Connection:
|
32
|
+
- close
|
33
|
+
Set-Cookie:
|
34
|
+
- __cfduid=dc82c08fc0528b00d44fd9dc69a3d5bf91555525447; expires=Thu, 16-Apr-20
|
35
|
+
18:24:07 GMT; path=/; domain=.typicode.com; HttpOnly
|
36
|
+
X-Powered-By:
|
37
|
+
- Express
|
38
|
+
Vary:
|
39
|
+
- Origin, Accept-Encoding
|
40
|
+
Access-Control-Allow-Credentials:
|
41
|
+
- 'true'
|
42
|
+
Cache-Control:
|
43
|
+
- public, max-age=14400
|
44
|
+
Pragma:
|
45
|
+
- no-cache
|
46
|
+
Expires:
|
47
|
+
- Wed, 17 Apr 2019 22:24:07 GMT
|
48
|
+
X-Content-Type-Options:
|
49
|
+
- nosniff
|
50
|
+
Etag:
|
51
|
+
- W/"940-PY6FbG4RbU9NVn6pD/xl3LdEHgs"
|
52
|
+
Via:
|
53
|
+
- 1.1 vegur
|
54
|
+
Cf-Cache-Status:
|
55
|
+
- HIT
|
56
|
+
Expect-Ct:
|
57
|
+
- max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
|
58
|
+
Server:
|
59
|
+
- cloudflare
|
60
|
+
Cf-Ray:
|
61
|
+
- 4c906f20ea39cc81-WAW
|
62
|
+
body:
|
63
|
+
encoding: UTF-8
|
64
|
+
string: |-
|
65
|
+
[
|
66
|
+
{
|
67
|
+
"userId": 2,
|
68
|
+
"id": 21,
|
69
|
+
"title": "suscipit repellat esse quibusdam voluptatem incidunt",
|
70
|
+
"completed": false
|
71
|
+
},
|
72
|
+
{
|
73
|
+
"userId": 2,
|
74
|
+
"id": 22,
|
75
|
+
"title": "distinctio vitae autem nihil ut molestias quo",
|
76
|
+
"completed": true
|
77
|
+
},
|
78
|
+
{
|
79
|
+
"userId": 2,
|
80
|
+
"id": 23,
|
81
|
+
"title": "et itaque necessitatibus maxime molestiae qui quas velit",
|
82
|
+
"completed": false
|
83
|
+
},
|
84
|
+
{
|
85
|
+
"userId": 2,
|
86
|
+
"id": 24,
|
87
|
+
"title": "adipisci non ad dicta qui amet quaerat doloribus ea",
|
88
|
+
"completed": false
|
89
|
+
},
|
90
|
+
{
|
91
|
+
"userId": 2,
|
92
|
+
"id": 25,
|
93
|
+
"title": "voluptas quo tenetur perspiciatis explicabo natus",
|
94
|
+
"completed": true
|
95
|
+
},
|
96
|
+
{
|
97
|
+
"userId": 2,
|
98
|
+
"id": 26,
|
99
|
+
"title": "aliquam aut quasi",
|
100
|
+
"completed": true
|
101
|
+
},
|
102
|
+
{
|
103
|
+
"userId": 2,
|
104
|
+
"id": 27,
|
105
|
+
"title": "veritatis pariatur delectus",
|
106
|
+
"completed": true
|
107
|
+
},
|
108
|
+
{
|
109
|
+
"userId": 2,
|
110
|
+
"id": 28,
|
111
|
+
"title": "nesciunt totam sit blanditiis sit",
|
112
|
+
"completed": false
|
113
|
+
},
|
114
|
+
{
|
115
|
+
"userId": 2,
|
116
|
+
"id": 29,
|
117
|
+
"title": "laborum aut in quam",
|
118
|
+
"completed": false
|
119
|
+
},
|
120
|
+
{
|
121
|
+
"userId": 2,
|
122
|
+
"id": 30,
|
123
|
+
"title": "nemo perspiciatis repellat ut dolor libero commodi blanditiis omnis",
|
124
|
+
"completed": true
|
125
|
+
},
|
126
|
+
{
|
127
|
+
"userId": 2,
|
128
|
+
"id": 31,
|
129
|
+
"title": "repudiandae totam in est sint facere fuga",
|
130
|
+
"completed": false
|
131
|
+
},
|
132
|
+
{
|
133
|
+
"userId": 2,
|
134
|
+
"id": 32,
|
135
|
+
"title": "earum doloribus ea doloremque quis",
|
136
|
+
"completed": false
|
137
|
+
},
|
138
|
+
{
|
139
|
+
"userId": 2,
|
140
|
+
"id": 33,
|
141
|
+
"title": "sint sit aut vero",
|
142
|
+
"completed": false
|
143
|
+
},
|
144
|
+
{
|
145
|
+
"userId": 2,
|
146
|
+
"id": 34,
|
147
|
+
"title": "porro aut necessitatibus eaque distinctio",
|
148
|
+
"completed": false
|
149
|
+
},
|
150
|
+
{
|
151
|
+
"userId": 2,
|
152
|
+
"id": 35,
|
153
|
+
"title": "repellendus veritatis molestias dicta incidunt",
|
154
|
+
"completed": true
|
155
|
+
},
|
156
|
+
{
|
157
|
+
"userId": 2,
|
158
|
+
"id": 36,
|
159
|
+
"title": "excepturi deleniti adipisci voluptatem et neque optio illum ad",
|
160
|
+
"completed": true
|
161
|
+
},
|
162
|
+
{
|
163
|
+
"userId": 2,
|
164
|
+
"id": 37,
|
165
|
+
"title": "sunt cum tempora",
|
166
|
+
"completed": false
|
167
|
+
},
|
168
|
+
{
|
169
|
+
"userId": 2,
|
170
|
+
"id": 38,
|
171
|
+
"title": "totam quia non",
|
172
|
+
"completed": false
|
173
|
+
},
|
174
|
+
{
|
175
|
+
"userId": 2,
|
176
|
+
"id": 39,
|
177
|
+
"title": "doloremque quibusdam asperiores libero corrupti illum qui omnis",
|
178
|
+
"completed": false
|
179
|
+
},
|
180
|
+
{
|
181
|
+
"userId": 2,
|
182
|
+
"id": 40,
|
183
|
+
"title": "totam atque quo nesciunt",
|
184
|
+
"completed": true
|
185
|
+
}
|
186
|
+
]
|
187
|
+
http_version:
|
188
|
+
recorded_at: Wed, 17 Apr 2019 18:24:07 GMT
|
189
|
+
recorded_with: VCR 3.0.3
|
data/spec/support/stub.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: api_struct
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- bezrukavyi
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2019-06-25 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: dry-monads
|
@@ -40,6 +40,20 @@ dependencies:
|
|
40
40
|
- - "~>"
|
41
41
|
- !ruby/object:Gem::Version
|
42
42
|
version: 0.7.0
|
43
|
+
- !ruby/object:Gem::Dependency
|
44
|
+
name: dry-inflector
|
45
|
+
requirement: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: 0.1.2
|
50
|
+
type: :runtime
|
51
|
+
prerelease: false
|
52
|
+
version_requirements: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - "~>"
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 0.1.2
|
43
57
|
- !ruby/object:Gem::Dependency
|
44
58
|
name: http
|
45
59
|
requirement: !ruby/object:Gem::Requirement
|
@@ -243,6 +257,7 @@ files:
|
|
243
257
|
- spec/fixtures/cassettes/posts/suffix.yml
|
244
258
|
- spec/fixtures/cassettes/posts/update_success.yml
|
245
259
|
- spec/fixtures/cassettes/todos.yml
|
260
|
+
- spec/fixtures/cassettes/user_todos.yml
|
246
261
|
- spec/fixtures/cassettes/users/1/posts.yml
|
247
262
|
- spec/fixtures/cassettes/users/1/posts/1.yml
|
248
263
|
- spec/spec_helper.rb
|