evil-client 0.3.3 → 1.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.
Files changed (180) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +0 -11
  3. data/.gitignore +1 -0
  4. data/.rspec +0 -1
  5. data/.rubocop.yml +22 -19
  6. data/.travis.yml +1 -0
  7. data/CHANGELOG.md +251 -6
  8. data/LICENSE.txt +3 -1
  9. data/README.md +47 -81
  10. data/docs/helpers/body.md +93 -0
  11. data/docs/helpers/connection.md +19 -0
  12. data/docs/helpers/headers.md +72 -0
  13. data/docs/helpers/http_method.md +39 -0
  14. data/docs/helpers/let.md +14 -0
  15. data/docs/helpers/logger.md +24 -0
  16. data/docs/helpers/middleware.md +56 -0
  17. data/docs/helpers/operation.md +103 -0
  18. data/docs/helpers/option.md +50 -0
  19. data/docs/helpers/path.md +37 -0
  20. data/docs/helpers/query.md +59 -0
  21. data/docs/helpers/response.md +40 -0
  22. data/docs/helpers/scope.md +121 -0
  23. data/docs/helpers/security.md +102 -0
  24. data/docs/helpers/validate.md +68 -0
  25. data/docs/index.md +70 -78
  26. data/docs/license.md +5 -1
  27. data/docs/rspec.md +96 -0
  28. data/evil-client.gemspec +10 -8
  29. data/lib/evil/client.rb +126 -72
  30. data/lib/evil/client/builder.rb +47 -0
  31. data/lib/evil/client/builder/operation.rb +40 -0
  32. data/lib/evil/client/builder/scope.rb +31 -0
  33. data/lib/evil/client/chaining.rb +17 -0
  34. data/lib/evil/client/connection.rb +60 -20
  35. data/lib/evil/client/container.rb +66 -0
  36. data/lib/evil/client/container/operation.rb +23 -0
  37. data/lib/evil/client/container/scope.rb +28 -0
  38. data/lib/evil/client/exceptions/definition_error.rb +15 -0
  39. data/lib/evil/client/exceptions/name_error.rb +32 -0
  40. data/lib/evil/client/exceptions/response_error.rb +42 -0
  41. data/lib/evil/client/exceptions/type_error.rb +29 -0
  42. data/lib/evil/client/exceptions/validation_error.rb +27 -0
  43. data/lib/evil/client/formatter.rb +49 -0
  44. data/lib/evil/client/formatter/form.rb +45 -0
  45. data/lib/evil/client/formatter/multipart.rb +33 -0
  46. data/lib/evil/client/formatter/part.rb +66 -0
  47. data/lib/evil/client/formatter/text.rb +21 -0
  48. data/lib/evil/client/resolver.rb +84 -0
  49. data/lib/evil/client/resolver/body.rb +22 -0
  50. data/lib/evil/client/resolver/format.rb +30 -0
  51. data/lib/evil/client/resolver/headers.rb +46 -0
  52. data/lib/evil/client/resolver/http_method.rb +34 -0
  53. data/lib/evil/client/resolver/middleware.rb +36 -0
  54. data/lib/evil/client/resolver/query.rb +39 -0
  55. data/lib/evil/client/resolver/request.rb +96 -0
  56. data/lib/evil/client/resolver/response.rb +26 -0
  57. data/lib/evil/client/resolver/security.rb +113 -0
  58. data/lib/evil/client/resolver/uri.rb +35 -0
  59. data/lib/evil/client/rspec.rb +127 -0
  60. data/lib/evil/client/schema.rb +105 -0
  61. data/lib/evil/client/schema/operation.rb +177 -0
  62. data/lib/evil/client/schema/scope.rb +73 -0
  63. data/lib/evil/client/settings.rb +172 -0
  64. data/lib/evil/client/settings/validator.rb +64 -0
  65. data/mkdocs.yml +21 -15
  66. data/spec/features/custom_connection_spec.rb +17 -0
  67. data/spec/features/operation/middleware_spec.rb +50 -0
  68. data/spec/features/operation/options_spec.rb +71 -0
  69. data/spec/features/operation/request_spec.rb +94 -0
  70. data/spec/features/operation/response_spec.rb +48 -0
  71. data/spec/features/scope/options_spec.rb +52 -0
  72. data/spec/fixtures/locales/en.yml +16 -0
  73. data/spec/fixtures/test_client.rb +76 -0
  74. data/spec/spec_helper.rb +18 -6
  75. data/spec/support/fixtures_helper.rb +7 -0
  76. data/spec/unit/builder/operation_spec.rb +90 -0
  77. data/spec/unit/builder/scope_spec.rb +84 -0
  78. data/spec/unit/client_spec.rb +137 -0
  79. data/spec/unit/connection_spec.rb +78 -0
  80. data/spec/unit/container/operation_spec.rb +81 -0
  81. data/spec/unit/container/scope_spec.rb +61 -0
  82. data/spec/unit/container_spec.rb +107 -0
  83. data/spec/unit/exceptions/definition_error_spec.rb +15 -0
  84. data/spec/unit/exceptions/name_error_spec.rb +77 -0
  85. data/spec/unit/exceptions/response_error_spec.rb +22 -0
  86. data/spec/unit/exceptions/type_error_spec.rb +71 -0
  87. data/spec/unit/exceptions/validation_error_spec.rb +13 -0
  88. data/spec/unit/formatter/form_spec.rb +27 -0
  89. data/spec/unit/formatter/multipart_spec.rb +23 -0
  90. data/spec/unit/formatter/part_spec.rb +49 -0
  91. data/spec/unit/formatter/text_spec.rb +37 -0
  92. data/spec/unit/formatter_spec.rb +46 -0
  93. data/spec/unit/resolver/body_spec.rb +65 -0
  94. data/spec/unit/resolver/format_spec.rb +66 -0
  95. data/spec/unit/resolver/headers_spec.rb +93 -0
  96. data/spec/unit/resolver/http_method_spec.rb +67 -0
  97. data/spec/unit/resolver/middleware_spec.rb +83 -0
  98. data/spec/unit/resolver/query_spec.rb +85 -0
  99. data/spec/unit/resolver/request_spec.rb +121 -0
  100. data/spec/unit/resolver/response_spec.rb +64 -0
  101. data/spec/unit/resolver/security_spec.rb +156 -0
  102. data/spec/unit/resolver/uri_spec.rb +117 -0
  103. data/spec/unit/rspec_spec.rb +342 -0
  104. data/spec/unit/schema/operation_spec.rb +309 -0
  105. data/spec/unit/schema/scope_spec.rb +110 -0
  106. data/spec/unit/schema_spec.rb +157 -0
  107. data/spec/unit/settings/validator_spec.rb +128 -0
  108. data/spec/unit/settings_spec.rb +248 -0
  109. metadata +192 -135
  110. data/docs/base_url.md +0 -38
  111. data/docs/documentation.md +0 -9
  112. data/docs/headers.md +0 -59
  113. data/docs/http_method.md +0 -31
  114. data/docs/model.md +0 -173
  115. data/docs/operation.md +0 -0
  116. data/docs/overview.md +0 -0
  117. data/docs/path.md +0 -48
  118. data/docs/query.md +0 -99
  119. data/docs/responses.md +0 -66
  120. data/docs/security.md +0 -102
  121. data/docs/settings.md +0 -32
  122. data/lib/evil/client/connection/net_http.rb +0 -57
  123. data/lib/evil/client/dsl.rb +0 -127
  124. data/lib/evil/client/dsl/base.rb +0 -26
  125. data/lib/evil/client/dsl/files.rb +0 -37
  126. data/lib/evil/client/dsl/headers.rb +0 -16
  127. data/lib/evil/client/dsl/http_method.rb +0 -24
  128. data/lib/evil/client/dsl/operation.rb +0 -91
  129. data/lib/evil/client/dsl/operations.rb +0 -41
  130. data/lib/evil/client/dsl/path.rb +0 -25
  131. data/lib/evil/client/dsl/query.rb +0 -16
  132. data/lib/evil/client/dsl/response.rb +0 -61
  133. data/lib/evil/client/dsl/responses.rb +0 -29
  134. data/lib/evil/client/dsl/scope.rb +0 -27
  135. data/lib/evil/client/dsl/security.rb +0 -57
  136. data/lib/evil/client/dsl/verifier.rb +0 -35
  137. data/lib/evil/client/middleware.rb +0 -81
  138. data/lib/evil/client/middleware/base.rb +0 -11
  139. data/lib/evil/client/middleware/merge_security.rb +0 -20
  140. data/lib/evil/client/middleware/normalize_headers.rb +0 -17
  141. data/lib/evil/client/middleware/stringify_form.rb +0 -40
  142. data/lib/evil/client/middleware/stringify_json.rb +0 -19
  143. data/lib/evil/client/middleware/stringify_multipart.rb +0 -36
  144. data/lib/evil/client/middleware/stringify_multipart/part.rb +0 -36
  145. data/lib/evil/client/middleware/stringify_query.rb +0 -35
  146. data/lib/evil/client/operation.rb +0 -34
  147. data/lib/evil/client/operation/request.rb +0 -26
  148. data/lib/evil/client/operation/response.rb +0 -39
  149. data/lib/evil/client/operation/response_error.rb +0 -13
  150. data/lib/evil/client/operation/unexpected_response_error.rb +0 -19
  151. data/spec/features/instantiation_spec.rb +0 -68
  152. data/spec/features/middleware_spec.rb +0 -79
  153. data/spec/features/operation_with_documentation_spec.rb +0 -41
  154. data/spec/features/operation_with_files_spec.rb +0 -40
  155. data/spec/features/operation_with_form_body_spec.rb +0 -158
  156. data/spec/features/operation_with_headers_spec.rb +0 -99
  157. data/spec/features/operation_with_http_method_spec.rb +0 -45
  158. data/spec/features/operation_with_json_body_spec.rb +0 -156
  159. data/spec/features/operation_with_nested_responses_spec.rb +0 -95
  160. data/spec/features/operation_with_path_spec.rb +0 -47
  161. data/spec/features/operation_with_query_spec.rb +0 -84
  162. data/spec/features/operation_with_security_spec.rb +0 -228
  163. data/spec/features/scoping_spec.rb +0 -48
  164. data/spec/support/test_client.rb +0 -15
  165. data/spec/unit/evil/client/connection/net_http_spec.rb +0 -38
  166. data/spec/unit/evil/client/dsl/files_spec.rb +0 -37
  167. data/spec/unit/evil/client/dsl/operation_spec.rb +0 -374
  168. data/spec/unit/evil/client/dsl/operations_spec.rb +0 -29
  169. data/spec/unit/evil/client/dsl/scope_spec.rb +0 -32
  170. data/spec/unit/evil/client/dsl/security_spec.rb +0 -135
  171. data/spec/unit/evil/client/middleware/merge_security_spec.rb +0 -32
  172. data/spec/unit/evil/client/middleware/normalize_headers_spec.rb +0 -17
  173. data/spec/unit/evil/client/middleware/stringify_form_spec.rb +0 -63
  174. data/spec/unit/evil/client/middleware/stringify_json_spec.rb +0 -61
  175. data/spec/unit/evil/client/middleware/stringify_multipart/part_spec.rb +0 -59
  176. data/spec/unit/evil/client/middleware/stringify_multipart_spec.rb +0 -62
  177. data/spec/unit/evil/client/middleware/stringify_query_spec.rb +0 -40
  178. data/spec/unit/evil/client/middleware_spec.rb +0 -46
  179. data/spec/unit/evil/client/operation/request_spec.rb +0 -49
  180. data/spec/unit/evil/client/operation/response_spec.rb +0 -63
@@ -1,95 +0,0 @@
1
- RSpec.describe "operation with nested responses" do
2
- # see Test::Client definition in `/spec/support/test_client.rb`
3
- before do
4
- class Test::User < Evil::Struct
5
- attribute :name
6
- end
7
-
8
- class Test::Client < Evil::Client
9
- operation do
10
- http_method :get
11
- path { "users" }
12
-
13
- response :success, 200, format: :plain
14
- end
15
-
16
- operation :example do
17
- responses format: :plain do
18
- response :created, 201 do |body|
19
- body.to_sym
20
- end
21
-
22
- responses raise: true do
23
- response :not_found, 404
24
-
25
- response :error, 422 do |body|
26
- body.to_sym
27
- end
28
- end
29
- end
30
- end
31
- end
32
- end
33
-
34
- let(:client) { Test::Client.new "foo", user: "bar", version: 3, token: "baz" }
35
-
36
- subject { client.operations[:example].call }
37
-
38
- it "takes default setting" do
39
- stub_request(:get, //).to_return status: 200,
40
- headers: { "Foo" => "BAR" },
41
- body: "Hi!"
42
-
43
- expect(subject).to eq "Hi!"
44
- end
45
-
46
- it "applies block to coerce data" do
47
- stub_request(:get, //).to_return status: 201,
48
- headers: { "Foo" => "BAR" },
49
- body: "Hi!"
50
-
51
- expect(subject).to eq :Hi!
52
- end
53
-
54
- it "raises ResponseError when necessary" do
55
- stub_request(:get, //).to_return status: 404,
56
- headers: { "Foo" => "BAR" },
57
- body: "Hi!"
58
-
59
- begin
60
- subject
61
- rescue Evil::Client::Operation::ResponseError => error
62
- expect(error.data).to eq "Hi!"
63
- else
64
- raise
65
- end
66
- end
67
-
68
- it "can raise ResponseError with coercion" do
69
- stub_request(:get, //).to_return status: 422,
70
- headers: { "Foo" => "BAR" },
71
- body: "Hi!"
72
-
73
- begin
74
- subject
75
- rescue Evil::Client::Operation::ResponseError => error
76
- expect(error.data).to eq :Hi!
77
- else
78
- raise
79
- end
80
- end
81
-
82
- it "raises UnexpectedResponseError when a status not expected" do
83
- stub_request(:get, //).to_return status: 400,
84
- headers: { "Foo" => "BAR" },
85
- body: "Hi!"
86
-
87
- begin
88
- subject
89
- rescue Evil::Client::Operation::UnexpectedResponseError => error
90
- expect(error.data).to eq "Hi!"
91
- else
92
- raise
93
- end
94
- end
95
- end
@@ -1,47 +0,0 @@
1
- RSpec.describe "operation with path" do
2
- # see Test::Client definition in `/spec/support/test_client.rb`
3
- before do
4
- class Test::Client < Evil::Client
5
- operation do
6
- http_method :get
7
- path "users"
8
- response :success, 200
9
- end
10
-
11
- operation :find_users
12
-
13
- operation :find_user do
14
- path { |id:, **| "users/#{id}" }
15
- end
16
-
17
- operation :login do |settings|
18
- path "login/#{settings.token}"
19
- end
20
- end
21
-
22
- stub_request :get, //
23
- end
24
-
25
- let(:client) { Test::Client.new "foo", user: "bar", version: 3, token: "baz" }
26
-
27
- it "uses default path" do
28
- client.operations[:find_users].call
29
-
30
- expect(a_request(:get, "https://foo.example.com/api/v3/users"))
31
- .to have_been_made
32
- end
33
-
34
- it "uses request options" do
35
- client.operations[:find_user].call(id: 42)
36
-
37
- expect(a_request(:get, "https://foo.example.com/api/v3/users/42"))
38
- .to have_been_made
39
- end
40
-
41
- it "uses settings" do
42
- client.operations[:login].call
43
-
44
- expect(a_request(:get, "https://foo.example.com/api/v3/login/baz"))
45
- .to have_been_made
46
- end
47
- end
@@ -1,84 +0,0 @@
1
- RSpec.describe "operation with query" do
2
- # see Test::Client definition in `/spec/support/test_client.rb`
3
- before do
4
- class Test::User < Evil::Struct
5
- attribute :name
6
- end
7
-
8
- class Test::Client < Evil::Client
9
- operation do
10
- http_method :get
11
- path { "users" }
12
- response :success, 200
13
- end
14
-
15
- operation :filter do
16
- query do
17
- attribute :age, type: Dry::Types["coercible.int"]
18
- attribute :male, default: proc { true }
19
- attribute :name, optional: true
20
- end
21
- end
22
-
23
- operation :search do
24
- query model: Test::User
25
- end
26
- end
27
-
28
- stub_request(:get, //)
29
- end
30
-
31
- let(:path) { "https://foo.example.com/api/v3/users" }
32
- let(:client) { Test::Client.new "foo", user: "bar", version: 3, token: "baz" }
33
-
34
- it "provides a query from options ordered by name" do
35
- client.operations[:filter].call age: 48, male: false, name: "John"
36
-
37
- expect(a_request(:get, "#{path}?age=48&male=false&name=John"))
38
- .to have_been_made
39
- end
40
-
41
- it "uses http encoding" do
42
- client.operations[:filter].call age: 7, name: "Ян"
43
-
44
- expect(a_request(:get, "#{path}?age=7&male=true&name=%D0%AF%D0%BD"))
45
- .to have_been_made
46
- end
47
-
48
- it "skips unassigned optional attributes" do
49
- client.operations[:filter].call age: 7
50
-
51
- expect(a_request(:get, "#{path}?age=7&male=true")).to have_been_made
52
- end
53
-
54
- it "accepts a model" do
55
- client.operations[:search].call name: "Joe"
56
-
57
- expect(a_request(:get, "#{path}?name=Joe")).to have_been_made
58
- end
59
-
60
- it "ignores unspecified options" do
61
- client.operations[:search].call id: 1, name: "Joe"
62
-
63
- expect(a_request(:get, "#{path}?name=Joe")).to have_been_made
64
- end
65
-
66
- it "applies type restrictuions" do
67
- expect { client.operations[:filter].call id: 1, name: "Joe" }
68
- .to raise_error(ArgumentError)
69
- end
70
-
71
- it "supports nesting in a Rails style" do
72
- client.operations[:search].call name: {
73
- "first": "John", last: "Doe", middle: %w[Juan Andre]
74
- }
75
- query = [
76
- "name%5Bfirst%5D=John",
77
- "name%5Blast%5D=Doe",
78
- "name%5Bmiddle%5D%5B0%5D=Juan",
79
- "name%5Bmiddle%5D%5B1%5D=Andre"
80
- ].join("&")
81
-
82
- expect(a_request(:get, "#{path}?#{query}")).to have_been_made
83
- end
84
- end
@@ -1,228 +0,0 @@
1
- RSpec.describe "operation with security" do
2
- # see Test::Client definition in `/spec/support/test_client.rb`
3
- before do
4
- class Test::Client < Evil::Client
5
- operation do
6
- http_method :get
7
- path { "data" }
8
- response :success, 200
9
- end
10
- end
11
-
12
- stub_request(:get, //)
13
- end
14
-
15
- let(:path) { "https://foo.example.com/api/v3/data" }
16
- let(:client) do
17
- Test::Client.new "foo",
18
- version: 3,
19
- user: "bar",
20
- password: "baz",
21
- token: "qux"
22
- end
23
-
24
- subject { client.operations[:example].call }
25
-
26
- context "without operation-specific settings" do
27
- before do
28
- class Test::Client < Evil::Client
29
- operation do |settings|
30
- http_method :get
31
- path { "data" }
32
- response :success, 200
33
-
34
- security do
35
- basic_auth settings.user, settings.password
36
- end
37
- end
38
-
39
- operation :example
40
- end
41
- end
42
-
43
- it "uses default settings" do
44
- request = a_request(:get, path).with do |req|
45
- expect(req.headers).to include "Authorization" => "Basic YmFyOmJheg=="
46
- end
47
-
48
- subject
49
- expect(request).to have_been_made
50
- end
51
- end
52
-
53
- context "with basic_auth" do
54
- before do
55
- class Test::Client < Evil::Client
56
- operation :example do |settings|
57
- security { basic_auth settings.user, settings.password }
58
- end
59
- end
60
- end
61
-
62
- it "adds header" do
63
- request = a_request(:get, path).with do |req|
64
- expect(req.headers).to include "Authorization" => "Basic YmFyOmJheg=="
65
- end
66
-
67
- subject
68
- expect(request).to have_been_made
69
- end
70
- end
71
-
72
- context "with prefixed token_auth in headers" do
73
- before do
74
- class Test::Client < Evil::Client
75
- operation :example do |settings|
76
- security { token_auth settings.token, prefix: "Bearer" }
77
- end
78
- end
79
- end
80
-
81
- it "adds header" do
82
- request = a_request(:get, path).with do |req|
83
- expect(req.headers).to include "Authorization" => "Bearer qux"
84
- end
85
-
86
- subject
87
- expect(request).to have_been_made
88
- end
89
- end
90
-
91
- context "with token_auth without prefix in headers" do
92
- before do
93
- class Test::Client < Evil::Client
94
- operation :example do |settings|
95
- security { token_auth settings.token }
96
- end
97
- end
98
- end
99
-
100
- it "adds header" do
101
- request = a_request(:get, path).with do |req|
102
- expect(req.headers).to include "Authorization" => "qux"
103
- end
104
-
105
- subject
106
- expect(request).to have_been_made
107
- end
108
- end
109
-
110
- context "with token_auth in query" do
111
- before do
112
- class Test::Client < Evil::Client
113
- operation :example do |settings|
114
- security { token_auth settings.token, using: :query }
115
- end
116
- end
117
- end
118
-
119
- it "adds options to query" do
120
- request = a_request(:get, "#{path}?access_token=qux").with do |req|
121
- expect(req.headers.keys).not_to include "Authorization"
122
- end
123
-
124
- subject
125
- expect(request).to have_been_made
126
- end
127
- end
128
-
129
- context "with token_auth in json body" do
130
- before do
131
- class Test::Client < Evil::Client
132
- operation :example do |settings|
133
- security { token_auth settings.token, using: :body }
134
- body format: "json"
135
- end
136
- end
137
- end
138
-
139
- it "adds options to body" do
140
- request = a_request(:get, path).with do |req|
141
- expect(req.body).to eq '{"access_token":"qux"}'
142
- end
143
-
144
- subject
145
- expect(request).to have_been_made
146
- end
147
- end
148
-
149
- context "with token_auth in a plain(form) body" do
150
- before do
151
- class Test::Client < Evil::Client
152
- operation :example do |settings|
153
- security { token_auth settings.token, using: :body }
154
- body format: "form"
155
- end
156
- end
157
- end
158
-
159
- it "adds options to body" do
160
- request = a_request(:get, path).with do |req|
161
- expect(req.body).to eq "access_token=qux"
162
- end
163
-
164
- subject
165
- expect(request).to have_been_made
166
- end
167
- end
168
-
169
- context "with key_auth in headers" do
170
- before do
171
- class Test::Client < Evil::Client
172
- operation :example do
173
- security { key_auth "fOo", "bAr" }
174
- end
175
- end
176
- end
177
-
178
- it "adds header" do
179
- request = a_request(:get, path).with do |req|
180
- expect(req.headers).to include "Foo" => "bAr"
181
- end
182
-
183
- subject
184
- expect(request).to have_been_made
185
- end
186
- end
187
-
188
- context "with key_auth in query" do
189
- before do
190
- class Test::Client < Evil::Client
191
- operation :example do |_settings|
192
- security { key_auth :fOo, :bAr, using: :query }
193
- end
194
- end
195
- end
196
-
197
- it "adds options to query" do
198
- request = a_request(:get, "#{path}?fOo=bAr")
199
-
200
- subject
201
- expect(request).to have_been_made
202
- end
203
- end
204
-
205
- context "with several methods at once" do
206
- before do
207
- class Test::Client < Evil::Client
208
- operation :example do |_settings|
209
- security do
210
- key_auth "foo", "bar", using: :query
211
- key_auth "baz", "qux"
212
- basic_auth "foo", "bar"
213
- end
214
- end
215
- end
216
- end
217
-
218
- it "combines definitions" do
219
- request = a_request(:get, "#{path}?foo=bar").with do |req|
220
- expect(req.headers).to include "Authorization" => "Basic Zm9vOmJhcg==",
221
- "Baz" => "qux"
222
- end
223
-
224
- subject
225
- expect(request).to have_been_made
226
- end
227
- end
228
- end