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,41 +0,0 @@
1
- RSpec.describe "operation with documentation" do
2
- # see Test::Client definition in `/spec/support/test_client.rb`
3
- before do
4
- class Test::Client < Evil::Client
5
- operation do |settings|
6
- documentation "https://docs.example.com/v#{settings.version}/index.html"
7
- http_method :get
8
- path { "data" }
9
- end
10
-
11
- operation :clear_data
12
- operation :find_data do |settings|
13
- documentation "https://docs.example.com/v#{settings.version}/findData"
14
- end
15
- end
16
-
17
- stub_request(:any, //)
18
- end
19
-
20
- let(:client) { Test::Client.new("foo", version: 3, user: "bar") }
21
-
22
- it "displays default documentation in exception messages" do
23
- begin
24
- client.operations[:clear_data].call
25
- rescue => error
26
- expect(error.message).to include "https://docs.example.com/v3/index.html"
27
- else
28
- raise
29
- end
30
- end
31
-
32
- it "reloads default value with operation-specific one" do
33
- begin
34
- client.operations[:find_data].call
35
- rescue => error
36
- expect(error.message).to include "https://docs.example.com/v3/findData"
37
- else
38
- raise
39
- end
40
- end
41
- end
@@ -1,40 +0,0 @@
1
- RSpec.describe "operation with files" do
2
- # see Test::Client definition in `/spec/support/test_client.rb`
3
- before do
4
- class Test::Client < Evil::Client
5
- operation :example do
6
- http_method :get
7
- path { "users" }
8
- response :success, 200
9
-
10
- files do |file:, **|
11
- add file, type: "text/xml", charset: "utf-16", filename: "foo.xml"
12
- end
13
- end
14
- end
15
-
16
- stub_request(:get, //)
17
- end
18
-
19
- let(:path) { "https://foo.example.com/api/v3/users" }
20
- let(:client) { Test::Client.new "foo", user: "bar", version: 3, token: "baz" }
21
-
22
- subject { client.operations[:example].call file: "Hi!" }
23
-
24
- it "builds a multipart body" do
25
- request = a_request(:get, path).with do |req|
26
- expect(req.body).to include "Content-Disposition: form-data;" \
27
- ' name="AttachedFile1"; filename="foo.xml"'
28
-
29
- expect(req.body).to include "Content-Type: text/xml; charset=utf-16"
30
-
31
- expect(req.body).to include "Hi!"
32
-
33
- expect(req.headers["Content-Type"]).to include "multipart/form-data"
34
- end
35
-
36
- subject
37
-
38
- expect(request).to have_been_made
39
- end
40
- end
@@ -1,158 +0,0 @@
1
- RSpec.describe "operation with form body" 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
- end
15
-
16
- stub_request(:get, //)
17
- end
18
-
19
- let(:path) { "https://foo.example.com/api/v3/users" }
20
- let(:client) { Test::Client.new "foo", user: "bar", version: 3, token: "baz" }
21
- let(:operation) { client.operations[:example] }
22
-
23
- context "without operation-specific definition" do
24
- before do
25
- class Test::Client < Evil::Client
26
- operation do
27
- http_method :get
28
- path { "users" }
29
- response :success, 200
30
-
31
- body format: "form" do
32
- attribute :foo
33
- end
34
- end
35
-
36
- operation :example do
37
- end
38
- end
39
- end
40
-
41
- it "uses the default one" do
42
- request = a_request(:get, path).with do |req|
43
- expect(req.body).to eq "foo[][bar][]=BAZ"
44
- expect(req.headers)
45
- .to include "Content-Type" => "application/x-www-form-urlencoded"
46
- end
47
-
48
- operation.call foo: [{ bar: [:BAZ] }], baz: :QUX
49
-
50
- expect(request).to have_been_made
51
- end
52
- end
53
-
54
- context "with operation-specific definition" do
55
- before do
56
- class Test::Client < Evil::Client
57
- operation do
58
- http_method :get
59
- path { "users" }
60
- response :success, 200
61
-
62
- body format: "form" do
63
- attribute :foo
64
- end
65
- end
66
-
67
- operation :example do
68
- body format: "form" do
69
- attribute :baz
70
- end
71
- end
72
- end
73
- end
74
-
75
- it "uses the specific one" do
76
- request = a_request(:get, path).with body: "baz=QUX"
77
-
78
- operation.call foo: [{ bar: [:BAZ] }], baz: :QUX
79
-
80
- expect(request).to have_been_made
81
- end
82
- end
83
-
84
- context "when appended with files" do
85
- before do
86
- class Test::Client < Evil::Client
87
- operation :example do
88
- body format: "form" do
89
- attribute :baz
90
- end
91
-
92
- files do
93
- end
94
- end
95
- end
96
- end
97
-
98
- it "skips body definition" do
99
- request = a_request(:get, path).with do |req|
100
- expect(req.body).to be_nil
101
- end
102
-
103
- operation.call foo: [{ bar: [:BAZ] }], baz: :QUX
104
-
105
- expect(request).to have_been_made
106
- end
107
- end
108
-
109
- context "with a model" do
110
- before do
111
- class Test::Client < Evil::Client
112
- operation :example do
113
- body format: "form", model: Test::User do
114
- attribute :foo
115
- end
116
- end
117
- end
118
- end
119
-
120
- it "extends the model" do
121
- request = a_request(:get, path).with body: "name=Andy&foo=BAR"
122
-
123
- operation.call foo: :BAR, name: "Andy"
124
-
125
- expect(request).to have_been_made
126
- end
127
- end
128
-
129
- context "with a model" do
130
- before do
131
- class Test::Client < Evil::Client
132
- operation :example do
133
- body format: "form" do
134
- attribute :foo, type: Dry::Types["strict.string"]
135
- attribute :bar, default: proc { 1 }
136
- attribute :baz, optional: true
137
- end
138
- end
139
- end
140
- end
141
-
142
- it "requires mandatory arguments" do
143
- expect { operation.call bar: 2, baz: 3 }.to raise_error(ArgumentError)
144
- end
145
-
146
- it "applies type restrictions" do
147
- expect { operation.call foo: :FOO }.to raise_error(TypeError)
148
- end
149
-
150
- it "uses default values and skips undefined optional attributes" do
151
- request = a_request(:get, path).with body: "foo=BAR&bar=1"
152
-
153
- operation.call foo: "BAR"
154
-
155
- expect(request).to have_been_made
156
- end
157
- end
158
- end
@@ -1,99 +0,0 @@
1
- RSpec.describe "operation with headers" 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
-
9
- headers do
10
- attribute :foo
11
- attribute :bar, type: Dry::Types["strict.string"]
12
- attribute :baz, optional: true
13
- end
14
-
15
- response :success, 200
16
- end
17
-
18
- operation :clear_data do
19
- end
20
-
21
- operation :get_data do
22
- headers
23
- end
24
-
25
- operation :find_data do |settings|
26
- headers do
27
- attribute :foo if settings.version < 2
28
- attribute :bar, type: Dry::Types["coercible.int"]
29
- end
30
- end
31
- end
32
-
33
- stub_request(:any, //)
34
- end
35
-
36
- let(:path) { "https://foo.example.com/api/v3/data" }
37
- let(:client) { Test::Client.new("foo", version: 3, user: "bar") }
38
-
39
- it "uses default value" do
40
- client.operations[:clear_data].call foo: "FOO", bar: "BAR", baz: "BAZ"
41
-
42
- request = a_request(:get, path) do |req|
43
- expect(req.headers).to include "Foo" => "FOO",
44
- "Bar" => "BAR",
45
- "Baz" => "BAZ"
46
- end
47
-
48
- expect(request).to have_been_made
49
- end
50
-
51
- it "ingnores unknown attributes" do
52
- client.operations[:clear_data]
53
- .call foo: "FOO", bar: "BAR", baz: "BAZ", qux: "QUX"
54
-
55
- request = a_request(:get, path).with do |req|
56
- expect(req.headers.keys).not_to include "Qux"
57
- end
58
-
59
- expect(request).to have_been_made
60
- end
61
-
62
- it "requires mandatory headers" do
63
- expect { client.operations[:clear_data].call bar: "BAR", baz: "BAZ" }
64
- .to raise_error(ArgumentError)
65
- end
66
-
67
- it "applies type constraints" do
68
- expect { client.operations[:clear_data].call foo: "FOO", bar: :BAR }
69
- .to raise_error(TypeError)
70
- end
71
-
72
- it "skips optional headers" do
73
- client.operations[:clear_data].call foo: "FOO", bar: "BAR"
74
-
75
- request = a_request(:get, path).with do |req|
76
- expect(req.headers.keys).not_to include "Baz"
77
- end
78
-
79
- expect(request).to have_been_made
80
- end
81
-
82
- it "can undefine default headers" do
83
- client.operations[:get_data].call
84
-
85
- expect(a_request(:get, path)).to have_been_made
86
- end
87
-
88
- it "can reload default headers for a specific operation" do
89
- client.operations[:find_data].call foo: "FOO", bar: "01", baz: "BAZ"
90
-
91
- request = a_request(:get, path).with do |req|
92
- expect(req.headers).to include "Bar" => "1"
93
- expect(req.headers.keys).not_to include "Foo"
94
- expect(req.headers.keys).not_to include "Baz"
95
- end
96
-
97
- expect(request).to have_been_made
98
- end
99
- end
@@ -1,45 +0,0 @@
1
- RSpec.describe "operation with http_method" do
2
- # see Test::Client definition in `/spec/support/test_client.rb`
3
- before do
4
- class Test::Client < Evil::Client
5
- operation do |settings|
6
- http_method settings.version > 1 ? :post : :get
7
- path { "data" }
8
- response :success, 200
9
- end
10
-
11
- operation :clear_data do
12
- http_method :delete
13
- end
14
-
15
- operation :find_data
16
-
17
- operation :reset_data do |settings|
18
- http_method settings.version > 2 ? :patch : :put
19
- end
20
- end
21
-
22
- stub_request(:any, //)
23
- end
24
-
25
- let(:path) { "https://foo.example.com/api/v3/data" }
26
- let(:client) { Test::Client.new("foo", version: 3, user: "bar") }
27
-
28
- it "uses default value" do
29
- client.operations[:find_data].call
30
-
31
- expect(a_request(:post, path)).to have_been_made
32
- end
33
-
34
- it "reloads default value with operation-specific one" do
35
- client.operations[:clear_data].call
36
-
37
- expect(a_request(:delete, path)).to have_been_made
38
- end
39
-
40
- it "is customizeable by settings" do
41
- client.operations[:reset_data].call
42
-
43
- expect(a_request(:patch, path)).to have_been_made
44
- end
45
- end
@@ -1,156 +0,0 @@
1
- RSpec.describe "operation with json body" 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
- end
15
-
16
- stub_request(:get, //)
17
- end
18
-
19
- let(:path) { "https://foo.example.com/api/v3/users" }
20
- let(:client) { Test::Client.new "foo", user: "bar", version: 3, token: "baz" }
21
- let(:operation) { client.operations[:example] }
22
-
23
- context "without operation-specific definition" do
24
- before do
25
- class Test::Client < Evil::Client
26
- operation do
27
- http_method :get
28
- path { "users" }
29
- response :success, 200
30
-
31
- body do
32
- attribute :foo
33
- end
34
- end
35
-
36
- operation :example
37
- end
38
- end
39
-
40
- it "uses the default one" do
41
- request = a_request(:get, path).with do |req|
42
- expect(req.body).to eq '{"foo":[{"bar":["BAZ"]}]}'
43
- expect(req.headers).to include "Content-Type" => "application/json"
44
- end
45
-
46
- operation.call foo: [{ bar: [:BAZ] }], baz: :QUX
47
-
48
- expect(request).to have_been_made
49
- end
50
- end
51
-
52
- context "with operation-specific definition" do
53
- before do
54
- class Test::Client < Evil::Client
55
- operation do
56
- http_method :get
57
- path { "users" }
58
- response :success, 200
59
-
60
- body do
61
- attribute :foo
62
- end
63
- end
64
-
65
- operation :example do
66
- body do
67
- attribute :baz
68
- end
69
- end
70
- end
71
- end
72
-
73
- it "uses the specific one" do
74
- request = a_request(:get, path).with body: '{"baz":"QUX"}'
75
-
76
- operation.call foo: [{ bar: [:BAZ] }], baz: :QUX
77
-
78
- expect(request).to have_been_made
79
- end
80
- end
81
-
82
- context "when appended with files" do
83
- before do
84
- class Test::Client < Evil::Client
85
- operation :example do
86
- body do
87
- attribute :baz
88
- end
89
-
90
- files do
91
- end
92
- end
93
- end
94
- end
95
-
96
- it "skips body definition" do
97
- request = a_request(:get, path).with do |req|
98
- expect(req.body).to be_nil
99
- end
100
-
101
- operation.call foo: [{ bar: [:BAZ] }], baz: :QUX
102
-
103
- expect(request).to have_been_made
104
- end
105
- end
106
-
107
- context "with a model" do
108
- before do
109
- class Test::Client < Evil::Client
110
- operation :example do
111
- body model: Test::User do
112
- attribute :foo
113
- end
114
- end
115
- end
116
- end
117
-
118
- it "extends the model" do
119
- request = a_request(:get, path).with body: '{"name":"Andy","foo":"BAR"}'
120
-
121
- operation.call foo: :BAR, name: "Andy"
122
-
123
- expect(request).to have_been_made
124
- end
125
- end
126
-
127
- context "with a model" do
128
- before do
129
- class Test::Client < Evil::Client
130
- operation :example do
131
- body do
132
- attribute :foo, type: Dry::Types["strict.string"]
133
- attribute :bar, default: proc { 1 }
134
- attribute :baz, optional: true
135
- end
136
- end
137
- end
138
- end
139
-
140
- it "requires mandatory arguments" do
141
- expect { operation.call bar: 2, baz: 3 }.to raise_error(ArgumentError)
142
- end
143
-
144
- it "applies type restrictions" do
145
- expect { operation.call foo: :FOO }.to raise_error(TypeError)
146
- end
147
-
148
- it "uses default values and skips undefined optional attributes" do
149
- request = a_request(:get, path).with body: '{"foo":"BAR","bar":1}'
150
-
151
- operation.call foo: "BAR"
152
-
153
- expect(request).to have_been_made
154
- end
155
- end
156
- end