committee 5.0.0.beta1 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4257522fd7e79dceca7f4ee846f35d8eea30f70a4a2a9ab1f9e99a946eb992f6
4
- data.tar.gz: c71c15566465b608e72380c47ad3beceb9195d47949c234c1fbb0f99b0ebc22a
3
+ metadata.gz: d38440a7b31b31d429a47b744f397333489d09dbae1dbf16bcd74dd01124d68d
4
+ data.tar.gz: a7d1b5a22c1f415c6eb2bae32b6666df4558c3361f7685c50926499e2e74575e
5
5
  SHA512:
6
- metadata.gz: ca98156c131a991a05fc12f4bb149e2d740c6083befb91b96874ac27b2fdc923109e452f64d35f3e8bb0e92bd3c19575171013f8529ef95437bbd3b51335d1a4
7
- data.tar.gz: a623459fca01819e67403a3ba73b4e7cf3997d01c48b6c21f71f87ca51b9f6eddf3e3e413be25678d684042cb94b991a75c5432ea85cec07af7f07696accaa94
6
+ metadata.gz: 5314750901b395a42cdb9efe6c3a2992bb67a4d7561a0937422d48574f7705944a0b7317ccc5b10eda510734a8dac2375eaf27c1932be26ea1000662b14cf31d
7
+ data.tar.gz: 2ec012b81b43e319df14fbaefeb72b38bc2f065358084d479e927d68c58734e44c6b3d252436dc3fcc296dbfeb0c7798105fb52f3aca7325904673f7cf9647e4
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'digest'
4
+
3
5
  module Committee
4
6
  module Drivers
5
7
  # Gets a driver instance from the specified name. Raises ArgumentError for
@@ -36,13 +38,16 @@ module Committee
36
38
  # @param [String] schema_path
37
39
  # @return [Committee::Driver]
38
40
  def self.load_from_file(schema_path, parser_options: {})
39
- case File.extname(schema_path)
40
- when '.json'
41
- load_from_json(schema_path, parser_options: parser_options)
42
- when '.yaml', '.yml'
43
- load_from_yaml(schema_path, parser_options: parser_options)
44
- else
45
- raise "Committee only supports the following file extensions: '.json', '.yaml', '.yml'"
41
+ @__load_from_file_cache ||= {}
42
+ @__load_from_file_cache[cache_key(schema_path, parser_options)] ||= begin
43
+ case File.extname(schema_path)
44
+ when '.json'
45
+ load_from_json(schema_path, parser_options: parser_options)
46
+ when '.yaml', '.yml'
47
+ load_from_yaml(schema_path, parser_options: parser_options)
48
+ else
49
+ raise "Committee only supports the following file extensions: '.json', '.yaml', '.yml'"
50
+ end
46
51
  end
47
52
  end
48
53
 
@@ -74,6 +79,17 @@ module Committee
74
79
  # TODO: in the future, pass `opts` here and allow optionality in other drivers?
75
80
  driver.parse(hash)
76
81
  end
82
+
83
+ class << self
84
+ private
85
+
86
+ def cache_key(schema_path, parser_options)
87
+ [
88
+ File.exist?(schema_path) ? Digest::MD5.hexdigest(File.read(schema_path)) : nil,
89
+ parser_options.hash,
90
+ ].join('_')
91
+ end
92
+ end
77
93
  end
78
94
  end
79
95
 
@@ -48,9 +48,15 @@ module Committee
48
48
  private
49
49
 
50
50
  def response_media_type(response)
51
- response.content_type.to_s.split(";").first.to_s
51
+ if response.respond_to?(:media_type)
52
+ response.media_type.to_s
53
+ else
54
+ # for rack compatibility. In rack v 1.5.0, Rack::Response doesn't have media_type
55
+ response.content_type.to_s.split(";").first.to_s
56
+ end
52
57
  end
53
58
 
59
+
54
60
  def check_content_type!(response)
55
61
  if @link.media_type
56
62
  unless Rack::Mime.match?(response_media_type(response), @link.media_type)
@@ -52,6 +52,10 @@ module Committee
52
52
  ret
53
53
  end
54
54
 
55
+ def optional_body?
56
+ !request_operation.operation_object&.request_body&.required
57
+ end
58
+
55
59
  def valid_request_content_type?(content_type)
56
60
  if (request_body = request_operation.operation_object&.request_body)
57
61
  !request_body.select_media_type(content_type).nil?
@@ -24,6 +24,7 @@ module Committee
24
24
  # support post, put, patch only
25
25
  return true unless request.post? || request.put? || request.patch?
26
26
  return true if @operation_object.valid_request_content_type?(content_type)
27
+ return true if @operation_object.optional_body? && empty_request?(request)
27
28
 
28
29
  message = if valid_content_types.size > 1
29
30
  types = valid_content_types.map {|x| %{"#{x}"} }.join(', ')
@@ -37,6 +38,14 @@ module Committee
37
38
  def valid_content_types
38
39
  @operation_object&.request_content_types
39
40
  end
41
+
42
+ def empty_request?(request)
43
+ return true if !request.body
44
+
45
+ data = request.body.read
46
+ request.body.rewind
47
+ data.empty?
48
+ end
40
49
  end
41
50
  end
42
51
  end
@@ -4,7 +4,7 @@ module Committee
4
4
  module SchemaValidator
5
5
  class << self
6
6
  def request_media_type(request)
7
- request.content_type.to_s.split(";").first.to_s
7
+ request.media_type.to_s
8
8
  end
9
9
 
10
10
  # @param [String] prefix
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Committee
4
- VERSION = '5.0.0.beta1'.freeze
4
+ VERSION = '5.1.0'.freeze
5
5
  end
data/test/drivers_test.rb CHANGED
@@ -67,6 +67,35 @@ describe Committee::Drivers do
67
67
  end
68
68
  assert_equal "Committee only supports the following file extensions: '.json', '.yaml', '.yml'", e.message
69
69
  end
70
+
71
+ describe 'cache behavior' do
72
+ describe 'when loading the same file' do
73
+ it 'returns the same object when the options are identical' do
74
+ assert_equal(
75
+ Committee::Drivers.load_from_file(open_api_3_schema_path, parser_options:{strict_reference_validation: true}).object_id,
76
+ Committee::Drivers.load_from_file(open_api_3_schema_path, parser_options:{strict_reference_validation: true}).object_id,
77
+ )
78
+ end
79
+
80
+ it 'returns different objects if the options are different' do
81
+ refute_equal(
82
+ Committee::Drivers.load_from_file(open_api_3_schema_path, parser_options:{strict_reference_validation: true}).object_id,
83
+ Committee::Drivers.load_from_file(open_api_3_schema_path, parser_options:{strict_reference_validation: false}).object_id,
84
+ )
85
+ end
86
+
87
+ it 'returns different objects if the file contents have changed' do
88
+ object_id = Committee::Drivers.load_from_file(open_api_3_schema_path, parser_options:{strict_reference_validation: true}).object_id
89
+ original_file_contents = File.read(open_api_3_schema_path)
90
+ File.write(open_api_3_schema_path, original_file_contents + "\n")
91
+ refute_equal(
92
+ Committee::Drivers.load_from_file(open_api_3_schema_path, parser_options:{strict_reference_validation: true}).object_id,
93
+ object_id,
94
+ )
95
+ File.write(open_api_3_schema_path, original_file_contents)
96
+ end
97
+ end
98
+ end
70
99
  end
71
100
 
72
101
  describe 'load_from_json(schema_path)' do
@@ -71,6 +71,13 @@ describe Committee::SchemaValidator::OpenAPI3::RequestValidator do
71
71
  assert_equal 200, last_response.status
72
72
  end
73
73
 
74
+ it "skips content_type check with an empty body" do
75
+ @app = new_rack_app(check_content_type: true, schema: open_api_3_schema)
76
+ header "Content-Type", "application/x-www-form-urlencoded"
77
+ patch "/validate_empty_optional_body"
78
+ assert_equal 200, last_response.status
79
+ end
80
+
74
81
  it "does not mix up parameters and requestBody" do
75
82
  @app = new_rack_app(check_content_type: true, schema: open_api_3_schema)
76
83
  params = {
@@ -81,10 +88,17 @@ describe Committee::SchemaValidator::OpenAPI3::RequestValidator do
81
88
  assert_equal 200, last_response.status
82
89
  end
83
90
 
91
+ it "error because content_type check with body" do
92
+ @app = new_rack_app(check_content_type: true, schema: open_api_3_schema)
93
+ header "Content-Type", "application/x-www-form-urlencoded"
94
+ patch "/validate_empty_optional_body", "{}"
95
+ assert_equal 400, last_response.status
96
+ end
97
+
84
98
  def new_rack_app(options = {})
85
99
  # TODO: delete when 5.0.0 released because default value changed
86
100
  options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
87
-
101
+
88
102
  Rack::Builder.new {
89
103
  use Committee::Middleware::RequestValidation, options
90
104
  run lambda { |_|
data/test/test_helper.rb CHANGED
@@ -11,8 +11,10 @@ SimpleCov.start do
11
11
  add_filter "/test/"
12
12
 
13
13
  # This library has a pretty modest number of lines, so let's try to stick
14
- # to a 100% coverage target for a while and see what happens.
15
- minimum_coverage 100
14
+ # to a 99% coverage target for a while and see what happens.
15
+ # We can't use 100% because old rack version doesn't support media_type and it's not testable :(
16
+ # https://github.com/interagent/committee/pull/360/files#diff-ce1125b6594690a88a70dbe2869f7fcfa2962c2bca80751f3720888920e2dfabR54
17
+ minimum_coverage 99
16
18
  end
17
19
 
18
20
  require "minitest"
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: committee
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.0.beta1
4
+ version: 5.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandur
8
8
  - geemus (Wesley Beary)
9
9
  - ota42y
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-01-25 00:00:00.000000000 Z
13
+ date: 2024-01-16 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: json_schema
@@ -52,14 +52,14 @@ dependencies:
52
52
  requirements:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
- version: '1.0'
55
+ version: '2.0'
56
56
  type: :runtime
57
57
  prerelease: false
58
58
  version_requirements: !ruby/object:Gem::Requirement
59
59
  requirements:
60
60
  - - "~>"
61
61
  - !ruby/object:Gem::Version
62
- version: '1.0'
62
+ version: '2.0'
63
63
  - !ruby/object:Gem::Dependency
64
64
  name: minitest
65
65
  requirement: !ruby/object:Gem::Requirement
@@ -214,7 +214,7 @@ dependencies:
214
214
  - - ">="
215
215
  - !ruby/object:Gem::Version
216
216
  version: '0'
217
- description:
217
+ description:
218
218
  email:
219
219
  - brandur@mutelight.org
220
220
  - geemus+github@gmail.com
@@ -306,7 +306,7 @@ homepage: https://github.com/interagent/committee
306
306
  licenses:
307
307
  - MIT
308
308
  metadata: {}
309
- post_install_message:
309
+ post_install_message:
310
310
  rdoc_options: []
311
311
  require_paths:
312
312
  - lib
@@ -317,12 +317,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
317
317
  version: 2.6.0
318
318
  required_rubygems_version: !ruby/object:Gem::Requirement
319
319
  requirements:
320
- - - ">"
320
+ - - ">="
321
321
  - !ruby/object:Gem::Version
322
- version: 1.3.1
322
+ version: '0'
323
323
  requirements: []
324
- rubygems_version: 3.2.3
325
- signing_key:
324
+ rubygems_version: 3.4.20
325
+ signing_key:
326
326
  specification_version: 4
327
327
  summary: A collection of Rack middleware to support JSON Schema.
328
328
  test_files: []