evil-client 0.3.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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