api_struct 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9b4ddea2489ecf3ef083cd6b4ba06a1e5b1d2fdf
4
- data.tar.gz: 5d55b25bec067bccf2fe8785badf9770937fc077
3
+ metadata.gz: 1846d9253d9d3bb8e7d8ed18ba445cebabf26b27
4
+ data.tar.gz: cdd2bc6c8104216e2938c2369120daeaaa1c0f0f
5
5
  SHA512:
6
- metadata.gz: e596aef0eb1223dc8477f18822153b92505599d4cd8cc5657d32cdade2a80c0a10febfb1b73e0a33d37b103b653084723c0f633356d032b8a361bb613ee1fe58
7
- data.tar.gz: 1ac9539e5216151b7cffae6b6973a369a0f095adea730613e9284059c91a2b129f55a42ff4cbad416d43927b51aebb2e9da890ead281be1893f51bd993787fc2
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.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.3)
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.7)
27
+ dry-core (0.4.8)
27
28
  concurrent-ruby (~> 1.0)
28
- dry-equalizer (0.2.1)
29
- dry-monads (1.1.0)
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.0.0)
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.5)
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.1
108
+ 1.17.3
data/README.md CHANGED
@@ -38,7 +38,7 @@ ApiStruct::Settings.configure do |config|
38
38
  },
39
39
  second_api: {
40
40
  root: 'http://localhost:3001/api/v1',
41
- # etc...
41
+ params: { token: 'Default token' }
42
42
  }
43
43
  }
44
44
  end
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
@@ -1,6 +1,7 @@
1
1
  require 'http'
2
2
  require 'dry/monads/result'
3
3
  require 'dry-configurable'
4
+ require 'dry/inflector'
4
5
  require 'json'
5
6
  require 'hashie'
6
7
 
@@ -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
- camel_cased_word.gsub(/::/, '/')
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
@@ -76,7 +76,12 @@ module ApiStruct
76
76
  private
77
77
 
78
78
  def extract_attributes(attributes)
79
- attributes.select { |key, _value| self.class.entity_attributes.include?(key.to_sym) }
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
 
@@ -1,3 +1,3 @@
1
1
  module ApiStruct
2
- VERSION = '1.0.1'
2
+ VERSION = '1.0.2'
3
3
  end
@@ -1,7 +1,10 @@
1
1
  describe ApiStruct::Client do
2
2
  extend Support::Stub
3
- let(:api_root) { 'https://jsonplaceholder.typicode.com' }
4
- stub_api('https://jsonplaceholder.typicode.com')
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 = StubClient.new.get(prefix: 'users/:id', id: 1)
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 = StubClient.new.get(path: 'todos/1')
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 = StubClient.new.get(path: [:todos, 1])
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 = StubClient.new.show(1)
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 = StubClient.new.show(101)
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 = StubClient.new.show(101)
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 = StubClient.new.update(1, title: FFaker::Name.name)
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
@@ -1,8 +1,8 @@
1
1
  module Support
2
2
  module Stub
3
- def stub_api(root)
3
+ def stub_api(root, params = {})
4
4
  ApiStruct::Settings.configure do |config|
5
- config.endpoints = { stub_api: { root: root } }
5
+ config.endpoints = { stub_api: { root: root, params: params } }
6
6
  end
7
7
  end
8
8
  end
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.1
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: 2018-11-27 00:00:00.000000000 Z
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