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
@@ -0,0 +1,66 @@
1
+ RSpec.describe Evil::Client::Resolver::Format, ".call" do
2
+ subject { described_class.call schema, settings }
3
+
4
+ let(:log) { StringIO.new }
5
+ let(:logger) { Logger.new log }
6
+ let(:settings) { double :my_settings, version: 77, logger: logger }
7
+
8
+ let(:root_schema) do
9
+ double :my_parent_schema,
10
+ definitions: { format: proc { :form } },
11
+ parent: nil
12
+ end
13
+
14
+ let(:schema) do
15
+ double :my_schema,
16
+ definitions: { format: proc { version > 2 ? :json : :form } },
17
+ parent: root_schema
18
+ end
19
+
20
+ it "resolves format from a schema" do
21
+ expect(subject).to eq :json
22
+ end
23
+
24
+ it "logs the result" do
25
+ subject
26
+
27
+ expect(log.string).to include described_class.name
28
+ expect(log.string).to include "my_schema"
29
+ expect(log.string).to include "my_settings"
30
+ expect(log.string).to include "json"
31
+ end
32
+
33
+ context "when logger level was set to INFO" do
34
+ before { logger.level = Logger::INFO }
35
+
36
+ it "skips logging" do
37
+ expect { subject }.not_to change { log.string }
38
+ end
39
+ end
40
+
41
+ context "when current schema not defines a format" do
42
+ before { schema.definitions.delete :format }
43
+
44
+ it "resolves format from a parent schema" do
45
+ expect(subject).to eq :form
46
+ end
47
+ end
48
+
49
+ context "when format not defined by any schema" do
50
+ before { schema.definitions.delete :format }
51
+ before { root_schema.definitions.delete :format }
52
+
53
+ it "resolves format to :json" do
54
+ expect(subject).to eq :json
55
+ end
56
+ end
57
+
58
+ context "when format resolves to inacceptable value" do
59
+ before { schema.definitions[:format] = proc { :foo } }
60
+
61
+ it "raises Evil::Client::DefinitionError" do
62
+ expect { subject }.to raise_error Evil::Client::DefinitionError,
63
+ /foo/
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,93 @@
1
+ RSpec.describe Evil::Client::Resolver::Headers, ".call" do
2
+ subject { described_class.call schema, settings }
3
+
4
+ let(:log) { StringIO.new }
5
+ let(:logger) { Logger.new log }
6
+
7
+ let(:settings) do
8
+ double :my_settings, name: "foo", value: "bar", logger: logger
9
+ end
10
+
11
+ let(:root_schema) do
12
+ double :my_parent_schema,
13
+ definitions: { headers: proc { { name: name.capitalize } } },
14
+ parent: nil
15
+ end
16
+
17
+ let(:schema) do
18
+ double :my_schema,
19
+ definitions: { headers: proc { { Value: value.upcase } } },
20
+ parent: root_schema
21
+ end
22
+
23
+ it "resolves headers from a schema" do
24
+ expect(subject).to eq "name" => "Foo", "Value" => "BAR"
25
+ end
26
+
27
+ it "logs the result" do
28
+ subject
29
+
30
+ expect(log.string).to include described_class.name
31
+ expect(log.string).to include "my_schema"
32
+ expect(log.string).to include "my_settings"
33
+ expect(log.string).to include "Foo"
34
+ end
35
+
36
+ context "when some header has empty value" do
37
+ before { schema.definitions[:headers] = proc { { Value: "" } } }
38
+
39
+ it "is ignored" do
40
+ expect(subject).to eq "name" => "Foo"
41
+ end
42
+ end
43
+
44
+ context "when header values are arrays" do
45
+ before { schema.definitions[:headers] = proc { { foo: [:bar] } } }
46
+
47
+ it "resolves header values to array of strings" do
48
+ expect(subject).to eq "foo" => ["bar"], "name" => "Foo"
49
+ end
50
+ end
51
+
52
+ context "when header values are nested arrays" do
53
+ before { schema.definitions[:headers] = proc { { foo: [[:bar]] } } }
54
+
55
+ it "resolves header values to array of strings" do
56
+ expect(subject).to eq "foo" => ["[:bar]"], "name" => "Foo"
57
+ end
58
+ end
59
+
60
+ context "when logger level was set to INFO" do
61
+ before { logger.level = Logger::INFO }
62
+
63
+ it "skips logging" do
64
+ expect { subject }.not_to change { log.string }
65
+ end
66
+ end
67
+
68
+ context "when current schema not defines headers" do
69
+ before { schema.definitions.delete :headers }
70
+
71
+ it "resolves headers from a parent schema only" do
72
+ expect(subject).to eq "name" => "Foo"
73
+ end
74
+ end
75
+
76
+ context "when headers not defined by any schema" do
77
+ before { schema.definitions.delete :headers }
78
+ before { root_schema.definitions.delete :headers }
79
+
80
+ it "resolves headers to empty hash" do
81
+ expect(subject).to eq({})
82
+ end
83
+ end
84
+
85
+ context "when headers resolves to inacceptable value" do
86
+ before { schema.definitions[:headers] = proc { :foo } }
87
+
88
+ it "raises Evil::Client::DefinitionError" do
89
+ expect { subject }.to raise_error Evil::Client::DefinitionError,
90
+ /foo/
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,67 @@
1
+ RSpec.describe Evil::Client::Resolver::HttpMethod, ".call" do
2
+ subject { described_class.call schema, settings }
3
+
4
+ let(:log) { StringIO.new }
5
+ let(:logger) { Logger.new log }
6
+ let(:settings) { double :my_settings, version: 77, logger: logger }
7
+
8
+ let(:root_schema) do
9
+ double :my_parent_schema,
10
+ definitions: { http_method: proc { :put } },
11
+ parent: nil
12
+ end
13
+
14
+ let(:schema) do
15
+ double :my_schema,
16
+ definitions: { http_method: proc { version > 2 ? :patch : :put } },
17
+ parent: root_schema
18
+ end
19
+
20
+ it "resolves http method from a schema" do
21
+ expect(subject).to eq "PATCH"
22
+ end
23
+
24
+ it "logs the result" do
25
+ subject
26
+
27
+ expect(log.string).to include described_class.name
28
+ expect(log.string).to include "my_schema"
29
+ expect(log.string).to include "my_settings"
30
+ expect(log.string).to include "PATCH"
31
+ end
32
+
33
+ context "when logger level was set to INFO" do
34
+ before { logger.level = Logger::INFO }
35
+
36
+ it "skips logging" do
37
+ expect { subject }.not_to change { log.string }
38
+ end
39
+ end
40
+
41
+ context "when current schema not defines a http method" do
42
+ before { schema.definitions.delete :http_method }
43
+
44
+ it "resolves http method from a parent schema" do
45
+ expect(subject).to eq "PUT"
46
+ end
47
+ end
48
+
49
+ context "when http method resolves to inacceptable value" do
50
+ before { schema.definitions[:http_method] = proc { :foo } }
51
+
52
+ it "raises Evil::Client::DefinitionError" do
53
+ expect { subject }.to raise_error Evil::Client::DefinitionError,
54
+ /FOO/
55
+ end
56
+ end
57
+
58
+ context "when http method not defined by any schema" do
59
+ before { schema.definitions.delete :http_method }
60
+ before { root_schema.definitions.delete :http_method }
61
+
62
+ it "raises Evil::Client::DefinitionError" do
63
+ expect { subject }.to raise_error Evil::Client::DefinitionError,
64
+ /http_method/
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,83 @@
1
+ RSpec.describe Evil::Client::Resolver::Middleware, ".call" do
2
+ subject { described_class.call schema, settings }
3
+
4
+ before do
5
+ class Test::Foo; end
6
+ class Test::Bar; end
7
+ class Test::Baz; end
8
+ end
9
+
10
+ let(:log) { StringIO.new }
11
+ let(:logger) { Logger.new log }
12
+
13
+ let(:settings) do
14
+ double :my_settings, name: "Andy", gender: "man", logger: logger
15
+ end
16
+
17
+ let(:root_schema) do
18
+ double :my_parent_schema,
19
+ definitions: { middleware: proc { [Test::Foo, Test::Bar] } },
20
+ parent: nil
21
+ end
22
+
23
+ let(:schema) do
24
+ double :my_schema,
25
+ definitions: { middleware: proc { Test::Baz } },
26
+ parent: root_schema
27
+ end
28
+
29
+ it "resolves middleware from a schema in a reverse order" do
30
+ expect(subject).to eq [Test::Baz, Test::Bar, Test::Foo]
31
+ end
32
+
33
+ it "logs the result" do
34
+ subject
35
+
36
+ expect(log.string).to include described_class.name
37
+ expect(log.string).to include "my_schema"
38
+ expect(log.string).to include "my_settings"
39
+ expect(log.string).to include "[Test::Baz, Test::Bar, Test::Foo]"
40
+ end
41
+
42
+ context "when logger level was set to INFO" do
43
+ before { logger.level = Logger::INFO }
44
+
45
+ it "skips logging" do
46
+ expect { subject }.not_to change { log.string }
47
+ end
48
+ end
49
+
50
+ context "when current schema not defines a middleware" do
51
+ before { schema.definitions.delete :middleware }
52
+
53
+ it "resolves middleware from a parent schema in a reverse order" do
54
+ expect(subject).to eq [Test::Bar, Test::Foo]
55
+ end
56
+ end
57
+
58
+ context "when root middleware definitions was reloaded by nil" do
59
+ before { schema.definitions[:middleware] = proc {} }
60
+
61
+ it "resolves middleware to empty list" do
62
+ expect(subject).to eq []
63
+ end
64
+ end
65
+
66
+ context "when middleware not defined by any schema" do
67
+ before { schema.definitions.delete :middleware }
68
+ before { root_schema.definitions.delete :middleware }
69
+
70
+ it "resolves middleware to empty list" do
71
+ expect(subject).to eq []
72
+ end
73
+ end
74
+
75
+ context "when middleware defintion has wrong format" do
76
+ before { schema.definitions[:middleware] = proc { 1323 } }
77
+
78
+ it "raises Evil::Client::DefinitionError" do
79
+ expect { subject }.to raise_error Evil::Client::DefinitionError,
80
+ /1323/
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,85 @@
1
+ RSpec.describe Evil::Client::Resolver::Query, ".call" do
2
+ subject { described_class.call schema, settings }
3
+
4
+ let(:log) { StringIO.new }
5
+ let(:logger) { Logger.new log }
6
+
7
+ let(:settings) do
8
+ double :my_settings, name: "Andy", gender: "man", logger: logger
9
+ end
10
+
11
+ let(:root_schema) do
12
+ double :my_parent_schema,
13
+ definitions: { query: proc { { user: { name: name } } } },
14
+ parent: nil
15
+ end
16
+
17
+ let(:schema) do
18
+ double :my_schema,
19
+ definitions: { query: proc { { user: { gender: gender } } } },
20
+ parent: root_schema
21
+ end
22
+
23
+ it "resolves query from a schema" do
24
+ expect(subject).to eq "user" => { "name" => "Andy", "gender" => "man" }
25
+ end
26
+
27
+ it "logs the result" do
28
+ subject
29
+
30
+ expect(log.string).to include described_class.name
31
+ expect(log.string).to include "my_schema"
32
+ expect(log.string).to include "my_settings"
33
+ expect(log.string).to include "Andy"
34
+ end
35
+
36
+ context "when logger level was set to INFO" do
37
+ before { logger.level = Logger::INFO }
38
+
39
+ it "skips logging" do
40
+ expect { subject }.not_to change { log.string }
41
+ end
42
+ end
43
+
44
+ context "when current schema not defines a query" do
45
+ before { schema.definitions.delete :query }
46
+
47
+ it "resolves query from a parent schema" do
48
+ expect(subject).to eq "user" => { name: "Andy" }
49
+ end
50
+ end
51
+
52
+ context "when current schema definitions incompatible to root" do
53
+ before { schema.definitions[:query] = proc { { user: [gender: :man] } } }
54
+
55
+ it "resolves query from a current schema only" do
56
+ expect(subject).to eq "user" => [{ gender: :man }]
57
+ end
58
+ end
59
+
60
+ context "when root query definitions was reloaded by nil" do
61
+ before { schema.definitions[:query] = proc {} }
62
+
63
+ it "resolves query to empty hash" do
64
+ expect(subject).to eq({})
65
+ end
66
+ end
67
+
68
+ context "when query not defined by any schema" do
69
+ before { schema.definitions.delete :query }
70
+ before { root_schema.definitions.delete :query }
71
+
72
+ it "resolves query to empty hash" do
73
+ expect(subject).to eq({})
74
+ end
75
+ end
76
+
77
+ context "when query defintion returns neither hash nor nil" do
78
+ before { schema.definitions[:query] = proc { 1323 } }
79
+
80
+ it "raises Evil::Client::DefinitionError" do
81
+ expect { subject }.to raise_error Evil::Client::DefinitionError,
82
+ /1323/
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,121 @@
1
+ RSpec.describe Evil::Client::Resolver::Request, ".call" do
2
+ subject { described_class.call schema, settings }
3
+
4
+ let(:log) { StringIO.new }
5
+ let(:logger) { Logger.new log }
6
+
7
+ let(:root_schema) do
8
+ double :my_parent_schema,
9
+ definitions: {
10
+ body: proc { %W[v#{version}] },
11
+ format: proc { :form },
12
+ headers: proc { { "Foo" => "BAR" } },
13
+ http_method: proc { :get },
14
+ query: proc { { version: version } },
15
+ security: proc { token_auth token },
16
+ path: proc { "https://myhost.com/api/v#{version}" }
17
+ },
18
+ parent: nil
19
+ end
20
+
21
+ let(:schema) do
22
+ double :my_schema,
23
+ to_s: "MySchema.users.fetch",
24
+ definitions: {
25
+ body: proc { { version: "v#{version}" } },
26
+ format: proc { :json if version > 76 },
27
+ headers: proc { { "Baz" => "QUX" } },
28
+ http_method: proc { :post if version > 75 },
29
+ query: proc { { verbose: true } },
30
+ security: proc { token_auth token, prefix: "Bearer" },
31
+ path: proc { "users/#{id}" }
32
+ },
33
+ parent: root_schema
34
+ end
35
+
36
+ let(:opts) { { version: 77, token: "eoiqopr==", id: 43 } }
37
+ let(:settings) { double :my_settings, options: opts, logger: logger, **opts }
38
+
39
+ let(:environment) do
40
+ {
41
+ "REQUEST_METHOD" => "POST",
42
+ "SCRIPT_NAME" => "",
43
+ "PATH_INFO" => "/api/v77/users/43",
44
+ "QUERY_STRING" => "version=77&verbose=true",
45
+ "SERVER_NAME" => "myhost.com",
46
+ "SERVER_PORT" => 443,
47
+ "HTTP_Variables" => {
48
+ "Foo" => "BAR",
49
+ "Baz" => "QUX",
50
+ "Authorization" => "Bearer eoiqopr==",
51
+ "Content-Type" => "application/json"
52
+ },
53
+ "rack.version" => Rack::VERSION,
54
+ "rack.input" => '{"version":"v77"}',
55
+ "rack.url_scheme" => "https",
56
+ "rack.multithread" => false,
57
+ "rack.multiprocess" => false,
58
+ "rack.run_once" => false,
59
+ "rack.hijack?" => false,
60
+ "rack.logger" => logger
61
+ }
62
+ end
63
+
64
+ context "with default :json format" do
65
+ it "resolves request schema for settings to rack-compatible env" do
66
+ expect(subject).to eq environment
67
+ end
68
+ end
69
+
70
+ context "with :yaml format" do
71
+ before do
72
+ schema.definitions[:format] = -> { :yaml }
73
+ environment["rack.input"] = "---\n:version: v77\n"
74
+ environment["HTTP_Variables"]["Content-Type"] = "application/yaml"
75
+ end
76
+
77
+ it "resolves request schema for settings to rack-compatible env" do
78
+ expect(subject).to eq environment
79
+ end
80
+ end
81
+
82
+ context "with :text format" do
83
+ before do
84
+ schema.definitions[:format] = -> { :text }
85
+ environment["rack.input"] = '{:version=>"v77"}'
86
+ environment["HTTP_Variables"]["Content-Type"] = "text/plain"
87
+ end
88
+
89
+ it "resolves request schema for settings to rack-compatible env" do
90
+ expect(subject).to eq environment
91
+ end
92
+ end
93
+
94
+ context "with :form format" do
95
+ before do
96
+ schema.definitions[:format] = -> { :form }
97
+ environment["rack.input"] = "version=v77"
98
+ environment["HTTP_Variables"]["Content-Type"] = \
99
+ "application/x-www-form-urlencoded"
100
+ end
101
+
102
+ it "resolves request schema for settings to rack-compatible env" do
103
+ expect(subject).to eq environment
104
+ end
105
+ end
106
+
107
+ context "with :multipart format" do
108
+ before { schema.definitions[:format] = -> { :multipart } }
109
+
110
+ it "resolves request schema for settings to rack-compatible env" do
111
+ expect(subject["HTTP_Variables"]["Content-Type"])
112
+ .to match %r{multipart/form-data; boundary=\w{20}}
113
+
114
+ expect(subject["rack.input"])
115
+ .to include 'Content-Disposition: form-data; name="Part1"'
116
+
117
+ expect(subject["rack.input"])
118
+ .to include "version=v77"
119
+ end
120
+ end
121
+ end