committee 3.1.0 → 3.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/bin/committee-stub +1 -0
  3. data/lib/committee.rb +12 -34
  4. data/lib/committee/bin/committee_stub.rb +6 -4
  5. data/lib/committee/drivers.rb +15 -67
  6. data/lib/committee/drivers/driver.rb +47 -0
  7. data/lib/committee/drivers/hyper_schema.rb +8 -171
  8. data/lib/committee/drivers/hyper_schema/driver.rb +105 -0
  9. data/lib/committee/drivers/hyper_schema/link.rb +68 -0
  10. data/lib/committee/drivers/hyper_schema/schema.rb +22 -0
  11. data/lib/committee/drivers/open_api_2.rb +9 -416
  12. data/lib/committee/drivers/open_api_2/driver.rb +253 -0
  13. data/lib/committee/drivers/open_api_2/header_schema_builder.rb +33 -0
  14. data/lib/committee/drivers/open_api_2/link.rb +36 -0
  15. data/lib/committee/drivers/open_api_2/parameter_schema_builder.rb +83 -0
  16. data/lib/committee/drivers/open_api_2/schema.rb +26 -0
  17. data/lib/committee/drivers/open_api_2/schema_builder.rb +33 -0
  18. data/lib/committee/drivers/open_api_3.rb +7 -75
  19. data/lib/committee/drivers/open_api_3/driver.rb +51 -0
  20. data/lib/committee/drivers/open_api_3/schema.rb +41 -0
  21. data/lib/committee/drivers/schema.rb +23 -0
  22. data/lib/committee/errors.rb +2 -0
  23. data/lib/committee/middleware.rb +11 -0
  24. data/lib/committee/middleware/base.rb +38 -34
  25. data/lib/committee/middleware/request_validation.rb +51 -30
  26. data/lib/committee/middleware/response_validation.rb +49 -26
  27. data/lib/committee/middleware/stub.rb +55 -51
  28. data/lib/committee/request_unpacker.rb +3 -1
  29. data/lib/committee/schema_validator.rb +23 -0
  30. data/lib/committee/schema_validator/hyper_schema.rb +85 -74
  31. data/lib/committee/schema_validator/hyper_schema/parameter_coercer.rb +60 -54
  32. data/lib/committee/schema_validator/hyper_schema/request_validator.rb +43 -37
  33. data/lib/committee/schema_validator/hyper_schema/response_generator.rb +86 -80
  34. data/lib/committee/schema_validator/hyper_schema/response_validator.rb +65 -59
  35. data/lib/committee/schema_validator/hyper_schema/router.rb +35 -29
  36. data/lib/committee/schema_validator/hyper_schema/string_params_coercer.rb +87 -81
  37. data/lib/committee/schema_validator/open_api_3.rb +71 -61
  38. data/lib/committee/schema_validator/open_api_3/operation_wrapper.rb +121 -115
  39. data/lib/committee/schema_validator/open_api_3/request_validator.rb +24 -18
  40. data/lib/committee/schema_validator/open_api_3/response_validator.rb +22 -16
  41. data/lib/committee/schema_validator/open_api_3/router.rb +30 -24
  42. data/lib/committee/schema_validator/option.rb +42 -38
  43. data/lib/committee/test/methods.rb +55 -51
  44. data/lib/committee/validation_error.rb +2 -0
  45. data/test/bin/committee_stub_test.rb +3 -1
  46. data/test/bin_test.rb +3 -1
  47. data/test/committee_test.rb +3 -1
  48. data/test/drivers/hyper_schema/driver_test.rb +49 -0
  49. data/test/drivers/{hyper_schema_test.rb → hyper_schema/link_test.rb} +2 -45
  50. data/test/drivers/open_api_2/driver_test.rb +156 -0
  51. data/test/drivers/open_api_2/header_schema_builder_test.rb +26 -0
  52. data/test/drivers/open_api_2/link_test.rb +52 -0
  53. data/test/drivers/open_api_2/parameter_schema_builder_test.rb +195 -0
  54. data/test/drivers/{open_api_3_test.rb → open_api_3/driver_test.rb} +5 -3
  55. data/test/drivers_test.rb +12 -10
  56. data/test/middleware/base_test.rb +3 -1
  57. data/test/middleware/request_validation_open_api_3_test.rb +4 -2
  58. data/test/middleware/request_validation_test.rb +46 -5
  59. data/test/middleware/response_validation_open_api_3_test.rb +3 -1
  60. data/test/middleware/response_validation_test.rb +39 -4
  61. data/test/middleware/stub_test.rb +3 -1
  62. data/test/request_unpacker_test.rb +2 -2
  63. data/test/schema_validator/hyper_schema/parameter_coercer_test.rb +2 -2
  64. data/test/schema_validator/hyper_schema/request_validator_test.rb +3 -1
  65. data/test/schema_validator/hyper_schema/response_generator_test.rb +3 -1
  66. data/test/schema_validator/hyper_schema/response_validator_test.rb +3 -1
  67. data/test/schema_validator/hyper_schema/router_test.rb +5 -3
  68. data/test/schema_validator/hyper_schema/string_params_coercer_test.rb +3 -1
  69. data/test/schema_validator/open_api_3/operation_wrapper_test.rb +3 -1
  70. data/test/schema_validator/open_api_3/request_validator_test.rb +11 -1
  71. data/test/schema_validator/open_api_3/response_validator_test.rb +3 -1
  72. data/test/test/methods_new_version_test.rb +3 -1
  73. data/test/test/methods_test.rb +4 -2
  74. data/test/test_helper.rb +16 -16
  75. data/test/validation_error_test.rb +3 -1
  76. metadata +52 -6
  77. data/lib/committee/schema_validator/schema_validator.rb +0 -15
  78. data/test/drivers/open_api_2_test.rb +0 -416
@@ -1,27 +1,33 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Committee
2
- class SchemaValidator::OpenAPI3::RequestValidator
3
- # @param [SchemaValidator::OpenAPI3::OperationWrapper] operation_object
4
- # @param [Committee::SchemaValidator::Option] validator_option
5
- def initialize(operation_object, validator_option:)
6
- @operation_object = operation_object
7
- @validator_option = validator_option
8
- end
4
+ module SchemaValidator
5
+ class OpenAPI3
6
+ class RequestValidator
7
+ # @param [SchemaValidator::OpenAPI3::OperationWrapper] operation_object
8
+ # @param [Committee::SchemaValidator::Option] validator_option
9
+ def initialize(operation_object, validator_option:)
10
+ @operation_object = operation_object
11
+ @validator_option = validator_option
12
+ end
9
13
 
10
- def call(request, params, headers)
11
- content_type = ::Committee::SchemaValidator.request_media_type(request)
12
- check_content_type(request, content_type) if @validator_option.check_content_type
14
+ def call(request, params, headers)
15
+ content_type = ::Committee::SchemaValidator.request_media_type(request)
16
+ check_content_type(request, content_type) if @validator_option.check_content_type
13
17
 
14
- @operation_object.validate_request_params(params, headers, @validator_option)
15
- end
18
+ @operation_object.validate_request_params(params, headers, @validator_option)
19
+ end
16
20
 
17
- private
21
+ private
18
22
 
19
- def check_content_type(request, content_type)
20
- # support post, put, patch only
21
- return true unless request.post? || request.put? || request.patch?
22
- return true if @operation_object.valid_request_content_type?(content_type)
23
+ def check_content_type(request, content_type)
24
+ # support post, put, patch only
25
+ return true unless request.post? || request.put? || request.patch?
26
+ return true if @operation_object.valid_request_content_type?(content_type)
23
27
 
24
- raise Committee::InvalidRequest, %{"Content-Type" request header must be set to "#{@operation_object}".}
28
+ raise Committee::InvalidRequest, %{"Content-Type" request header must be set to "#{@operation_object}".}
29
+ end
30
+ end
25
31
  end
26
32
  end
27
33
  end
@@ -1,24 +1,30 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Committee
2
- class SchemaValidator::OpenAPI3::ResponseValidator
3
- attr_reader :validate_success_only
4
+ module SchemaValidator
5
+ class OpenAPI3
6
+ class ResponseValidator
7
+ attr_reader :validate_success_only
4
8
 
5
- # @param [Committee::SchemaValidator::Options] validator_option
6
- # @param [Committee::SchemaValidator::OpenAPI3::OperationWrapper] operation_wrapper
7
- def initialize(operation_wrapper, validator_option)
8
- @operation_wrapper = operation_wrapper
9
- @validate_success_only = validator_option.validate_success_only
10
- @check_header = validator_option.check_header
11
- end
9
+ # @param [Committee::SchemaValidator::Options] validator_option
10
+ # @param [Committee::SchemaValidator::OpenAPI3::OperationWrapper] operation_wrapper
11
+ def initialize(operation_wrapper, validator_option)
12
+ @operation_wrapper = operation_wrapper
13
+ @validate_success_only = validator_option.validate_success_only
14
+ @check_header = validator_option.check_header
15
+ end
12
16
 
13
- def call(status, headers, response_data, strict)
14
- return unless Committee::Middleware::ResponseValidation.validate?(status, validate_success_only)
17
+ def call(status, headers, response_data, strict)
18
+ return unless Committee::Middleware::ResponseValidation.validate?(status, validate_success_only)
15
19
 
16
- #content_type = headers['Content-Type'].to_s.split(";").first.to_s
17
- operation_wrapper.validate_response_params(status, headers, response_data, strict, check_header)
18
- end
20
+ #content_type = headers['Content-Type'].to_s.split(";").first.to_s
21
+ operation_wrapper.validate_response_params(status, headers, response_data, strict, check_header)
22
+ end
19
23
 
20
- private
24
+ private
21
25
 
22
- attr_reader :operation_wrapper, :check_header
26
+ attr_reader :operation_wrapper, :check_header
27
+ end
28
+ end
23
29
  end
24
30
  end
@@ -1,37 +1,43 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Committee
2
- class SchemaValidator::OpenAPI3::Router
3
- # @param [Committee::SchemaValidator::Option] validator_option
4
- def initialize(schema, validator_option)
5
- @schema = schema
6
- @prefix_regexp = ::Committee::SchemaValidator.build_prefix_regexp(validator_option.prefix)
7
- @validator_option = validator_option
8
- end
4
+ module SchemaValidator
5
+ class OpenAPI3
6
+ class Router
7
+ # @param [Committee::SchemaValidator::Option] validator_option
8
+ def initialize(schema, validator_option)
9
+ @schema = schema
10
+ @prefix_regexp = ::Committee::SchemaValidator.build_prefix_regexp(validator_option.prefix)
11
+ @validator_option = validator_option
12
+ end
9
13
 
10
- def includes_request?(request)
11
- return true unless @prefix_regexp
14
+ def includes_request?(request)
15
+ return true unless @prefix_regexp
12
16
 
13
- prefix_request?(request)
14
- end
17
+ prefix_request?(request)
18
+ end
15
19
 
16
- def build_schema_validator(request)
17
- Committee::SchemaValidator::OpenAPI3.new(self, request, @validator_option)
18
- end
20
+ def build_schema_validator(request)
21
+ Committee::SchemaValidator::OpenAPI3.new(self, request, @validator_option)
22
+ end
19
23
 
20
- def operation_object(request)
21
- path = request.path
22
- path = path.gsub(@prefix_regexp, '') if prefix_request?(request)
24
+ def operation_object(request)
25
+ path = request.path
26
+ path = path.gsub(@prefix_regexp, '') if prefix_request?(request)
23
27
 
24
- request_method = request.request_method.downcase
28
+ request_method = request.request_method.downcase
25
29
 
26
- @schema.operation_object(path, request_method)
27
- end
30
+ @schema.operation_object(path, request_method)
31
+ end
28
32
 
29
- private
33
+ private
30
34
 
31
- def prefix_request?(request)
32
- return false unless @prefix_regexp
35
+ def prefix_request?(request)
36
+ return false unless @prefix_regexp
33
37
 
34
- request.path =~ @prefix_regexp
38
+ request.path =~ @prefix_regexp
39
+ end
40
+ end
35
41
  end
36
42
  end
37
43
  end
@@ -1,45 +1,49 @@
1
- class Committee::SchemaValidator
2
- class Option
3
- # Boolean Options
4
- attr_reader :allow_form_params,
5
- :allow_get_body,
6
- :allow_query_params,
7
- :check_content_type,
8
- :check_header,
9
- :coerce_date_times,
10
- :coerce_form_params,
11
- :coerce_path_params,
12
- :coerce_query_params,
13
- :coerce_recursive,
14
- :optimistic_json,
15
- :validate_success_only
1
+ # frozen_string_literal: true
16
2
 
17
- # Non-boolean options:
18
- attr_reader :headers_key,
19
- :params_key,
20
- :prefix
3
+ module Committee
4
+ module SchemaValidator
5
+ class Option
6
+ # Boolean Options
7
+ attr_reader :allow_form_params,
8
+ :allow_get_body,
9
+ :allow_query_params,
10
+ :check_content_type,
11
+ :check_header,
12
+ :coerce_date_times,
13
+ :coerce_form_params,
14
+ :coerce_path_params,
15
+ :coerce_query_params,
16
+ :coerce_recursive,
17
+ :optimistic_json,
18
+ :validate_success_only
21
19
 
22
- def initialize(options, schema, schema_type)
23
- # Non-boolean options
24
- @headers_key = options[:headers_key] || "committee.headers"
25
- @params_key = options[:params_key] || "committee.params"
26
- @prefix = options[:prefix]
20
+ # Non-boolean options:
21
+ attr_reader :headers_key,
22
+ :params_key,
23
+ :prefix
27
24
 
28
- # Boolean options and have a common value by default
29
- @allow_form_params = options.fetch(:allow_form_params, true)
30
- @allow_query_params = options.fetch(:allow_query_params, true)
31
- @check_content_type = options.fetch(:check_content_type, true)
32
- @check_header = options.fetch(:check_header, true)
33
- @coerce_recursive = options.fetch(:coerce_recursive, true)
34
- @optimistic_json = options.fetch(:optimistic_json, false)
25
+ def initialize(options, schema, schema_type)
26
+ # Non-boolean options
27
+ @headers_key = options[:headers_key] || "committee.headers"
28
+ @params_key = options[:params_key] || "committee.params"
29
+ @prefix = options[:prefix]
35
30
 
36
- # Boolean options and have a different value by default
37
- @allow_get_body = options.fetch(:allow_get_body, schema.driver.default_allow_get_body)
38
- @coerce_date_times = options.fetch(:coerce_date_times, schema.driver.default_coerce_date_times)
39
- @coerce_form_params = options.fetch(:coerce_form_params, schema.driver.default_coerce_form_params)
40
- @coerce_path_params = options.fetch(:coerce_path_params, schema.driver.default_path_params)
41
- @coerce_query_params = options.fetch(:coerce_query_params, schema.driver.default_query_params)
42
- @validate_success_only = options.fetch(:validate_success_only, schema.driver.default_validate_success_only)
31
+ # Boolean options and have a common value by default
32
+ @allow_form_params = options.fetch(:allow_form_params, true)
33
+ @allow_query_params = options.fetch(:allow_query_params, true)
34
+ @check_content_type = options.fetch(:check_content_type, true)
35
+ @check_header = options.fetch(:check_header, true)
36
+ @coerce_recursive = options.fetch(:coerce_recursive, true)
37
+ @optimistic_json = options.fetch(:optimistic_json, false)
38
+
39
+ # Boolean options and have a different value by default
40
+ @allow_get_body = options.fetch(:allow_get_body, schema.driver.default_allow_get_body)
41
+ @coerce_date_times = options.fetch(:coerce_date_times, schema.driver.default_coerce_date_times)
42
+ @coerce_form_params = options.fetch(:coerce_form_params, schema.driver.default_coerce_form_params)
43
+ @coerce_path_params = options.fetch(:coerce_path_params, schema.driver.default_path_params)
44
+ @coerce_query_params = options.fetch(:coerce_query_params, schema.driver.default_query_params)
45
+ @validate_success_only = options.fetch(:validate_success_only, schema.driver.default_validate_success_only)
46
+ end
43
47
  end
44
48
  end
45
49
  end
@@ -1,69 +1,73 @@
1
- module Committee::Test
2
- module Methods
3
- def assert_schema_conform
4
- assert_request_schema_confirm unless old_behavior
5
- assert_response_schema_confirm
6
- end
1
+ # frozen_string_literal: true
7
2
 
8
- def assert_request_schema_confirm
9
- unless schema_validator.link_exist?
10
- request = "`#{request_object.request_method} #{request_object.path_info}` undefined in schema."
11
- raise Committee::InvalidRequest.new(request)
3
+ module Committee
4
+ module Test
5
+ module Methods
6
+ def assert_schema_conform
7
+ assert_request_schema_confirm unless old_behavior
8
+ assert_response_schema_confirm
12
9
  end
13
10
 
14
- schema_validator.request_validate(request_object)
15
- end
11
+ def assert_request_schema_confirm
12
+ unless schema_validator.link_exist?
13
+ request = "`#{request_object.request_method} #{request_object.path_info}` undefined in schema."
14
+ raise Committee::InvalidRequest.new(request)
15
+ end
16
16
 
17
- def assert_response_schema_confirm
18
- unless schema_validator.link_exist?
19
- response = "`#{request_object.request_method} #{request_object.path_info}` undefined in schema."
20
- raise Committee::InvalidResponse.new(response)
17
+ schema_validator.request_validate(request_object)
21
18
  end
22
19
 
23
- status, headers, body = response_data
24
- schema_validator.response_validate(status, headers, [body], true) if validate_response?(status)
25
- end
20
+ def assert_response_schema_confirm
21
+ unless schema_validator.link_exist?
22
+ response = "`#{request_object.request_method} #{request_object.path_info}` undefined in schema."
23
+ raise Committee::InvalidResponse.new(response)
24
+ end
26
25
 
27
- def committee_options
28
- raise "please set options"
29
- end
26
+ status, headers, body = response_data
27
+ schema_validator.response_validate(status, headers, [body], true) if validate_response?(status)
28
+ end
30
29
 
31
- def request_object
32
- raise "please set object like 'last_request'"
33
- end
30
+ def committee_options
31
+ raise "please set options"
32
+ end
34
33
 
35
- def response_data
36
- raise "please set response data like 'last_response.status, last_response.headers, last_response.body'"
37
- end
34
+ def request_object
35
+ raise "please set object like 'last_request'"
36
+ end
38
37
 
39
- def validate_response?(status)
40
- Committee::Middleware::ResponseValidation.validate?(status, committee_options.fetch(:validate_success_only, false))
41
- end
38
+ def response_data
39
+ raise "please set response data like 'last_response.status, last_response.headers, last_response.body'"
40
+ end
42
41
 
43
- def schema
44
- @schema ||= Committee::Middleware::Base.get_schema(committee_options)
45
- end
42
+ def validate_response?(status)
43
+ Committee::Middleware::ResponseValidation.validate?(status, committee_options.fetch(:validate_success_only, false))
44
+ end
46
45
 
47
- def router
48
- @router ||= schema.build_router(committee_options)
49
- end
46
+ def schema
47
+ @schema ||= Committee::Middleware::Base.get_schema(committee_options)
48
+ end
50
49
 
51
- def schema_validator
52
- @schema_validator ||= router.build_schema_validator(request_object)
53
- end
50
+ def router
51
+ @router ||= schema.build_router(committee_options)
52
+ end
53
+
54
+ def schema_validator
55
+ @schema_validator ||= router.build_schema_validator(request_object)
56
+ end
54
57
 
55
- def old_behavior
56
- old_assert_behavior = committee_options.fetch(:old_assert_behavior, nil)
57
- if old_assert_behavior.nil?
58
- warn <<-MSG
59
- [DEPRECATION] now assert_schema_confirm check response schema only.
60
- but we will change check request and response in future major version.
61
- so if you want to conform response only, please use assert_response_schema_confirm,
62
- or you can suppress this message and keep old behavior by setting old_assert_behavior=true.
63
- MSG
64
- old_assert_behavior = true
58
+ def old_behavior
59
+ old_assert_behavior = committee_options.fetch(:old_assert_behavior, nil)
60
+ if old_assert_behavior.nil?
61
+ warn <<-MSG
62
+ [DEPRECATION] now assert_schema_conform check response schema only.
63
+ but we will change check request and response in future major version.
64
+ so if you want to conform response only, please use assert_response_schema_confirm,
65
+ or you can suppress this message and keep old behavior by setting old_assert_behavior=true.
66
+ MSG
67
+ old_assert_behavior = true
68
+ end
69
+ old_assert_behavior
65
70
  end
66
- old_assert_behavior
67
71
  end
68
72
  end
69
73
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Committee
2
4
  class ValidationError
3
5
  attr_reader :id, :message, :status
@@ -1,4 +1,6 @@
1
- require_relative "../test_helper"
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
2
4
 
3
5
  describe Committee::Bin::CommitteeStub do
4
6
  before do
data/test/bin_test.rb CHANGED
@@ -1,4 +1,6 @@
1
- require_relative "test_helper"
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
2
4
 
3
5
  #
4
6
  # The purpose of this sets of tests is just to include our Ruby executables
@@ -1,4 +1,6 @@
1
- require_relative "test_helper"
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
2
4
 
3
5
  describe Committee do
4
6
  it "debugs based off env" do
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ describe Committee::Drivers::HyperSchema::Driver do
6
+ before do
7
+ @driver = Committee::Drivers::HyperSchema::Driver.new
8
+ end
9
+
10
+ it "has a name" do
11
+ assert_equal :hyper_schema, @driver.name
12
+ end
13
+
14
+ it "has a schema class" do
15
+ assert_equal Committee::Drivers::HyperSchema::Schema, @driver.schema_class
16
+ end
17
+
18
+ it "parses a hyper-schema and builds routes" do
19
+ schema = @driver.parse(hyper_schema_data)
20
+ assert_kind_of Committee::Drivers::HyperSchema::Schema, schema
21
+ assert_equal @driver, schema.driver
22
+
23
+ assert_kind_of Hash, schema.routes
24
+ refute schema.routes.empty?
25
+ assert(schema.routes.keys.all? { |m|
26
+ ["DELETE", "GET", "PATCH", "POST", "PUT"].include?(m)
27
+ })
28
+
29
+ schema.routes.each do |(_, method_routes)|
30
+ method_routes.each do |regex, link|
31
+ assert_kind_of Regexp, regex
32
+ assert_kind_of Committee::Drivers::HyperSchema::Link, link
33
+ end
34
+ end
35
+ end
36
+
37
+ it "defaults to not coercing form parameters" do
38
+ assert_equal false, @driver.default_coerce_form_params
39
+ end
40
+
41
+ it "defaults to no path parameters" do
42
+ assert_equal false, @driver.default_path_params
43
+ end
44
+
45
+ it "defaults to no query parameters" do
46
+ assert_equal false, @driver.default_query_params
47
+ end
48
+ end
49
+