openapi_contracts 0.13.0 → 0.14.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: 2e3c770fbbdd4c6d8a18f69f9deaf65959ce70088232ad8291a5aa10bf4b6f0e
4
- data.tar.gz: 2248125b3e18a71d403f72b25eae01c2173628f0c58deaf7e004d501cb7f9b16
3
+ metadata.gz: 6a860586af31ca0bcf61a9301dba60df4466d367a495efbb306498eb71496f09
4
+ data.tar.gz: d74042e38633c207a4410ba6e961e68ed206f4b9d3a0d1fe0ea8d8aa1f4f4982
5
5
  SHA512:
6
- metadata.gz: 64d09afded34921b66bd12573998906882681cf68e62c277abb1f569afa3da93e856240877e9edffa1768c14d7a9766de0a9be57bf9f40a0b443c366187f8813
7
- data.tar.gz: 3b93196eaaf631d853d693a6082b19399b2db334190cd0bc7d8d27d80ddf67260556249f284c515fb6c0bf207d9d6599a916a2bfbccdbb4c40d6637ae08004fd
6
+ metadata.gz: 0bdddf66b9418f3374179566ebccfa5d7abad647708557ce5ec176afe620cbfcf79102743ffff6d293503278eeaccd8465e0a8627ff03b646b44c2c0aeb7e8f4
7
+ data.tar.gz: 9c0e8a0ba61f44bb8bde129524531a7a60918c9ff5fc23072c3d547a23a70ae45ef1e1a0983dc48b0ff2f57c8caf4e5998b5c80088d08aa645c99ccc0ed9acf6
data/README.md CHANGED
@@ -62,6 +62,12 @@ it { is_expected.to match_openapi_doc($doc, path: '/messages/{id}').with_http_st
62
62
  it { is_expected.to match_openapi_doc($doc, request_body: true).with_http_status(:created) }
63
63
  ```
64
64
 
65
+ * `parameters` can be set to `true` to validate request parameters against the parameter definitions
66
+
67
+ ```ruby
68
+ it { is_expected.to match_openapi_doc($doc, parameters: true) }
69
+ ```
70
+
65
71
  Both options can as well be used simultaneously.
66
72
 
67
73
  ### Without RSpec
@@ -14,33 +14,34 @@ module OpenapiContracts
14
14
  @in == 'path'
15
15
  end
16
16
 
17
+ def in_query?
18
+ @in == 'query'
19
+ end
20
+
17
21
  def matches?(value)
18
- case @spec.dig('schema', 'type')
19
- when 'integer'
20
- integer_parameter_matches?(value)
21
- when 'number'
22
- number_parameter_matches?(value)
23
- else
24
- schemer.valid?(value)
25
- end
22
+ errors = schemer.validate(convert_value(value))
23
+ # debug errors.to_a here
24
+ errors.none?
26
25
  end
27
26
 
28
- private
27
+ def required?
28
+ @required == true
29
+ end
29
30
 
30
- def schemer
31
- @schemer ||= Validators::SchemaValidation.validation_schemer(@spec.navigate('schema'))
31
+ def schema_for_validation
32
+ @spec.navigate('schema')
32
33
  end
33
34
 
34
- def integer_parameter_matches?(value)
35
- return false unless /^-?\d+$/.match?(value)
35
+ private
36
36
 
37
- schemer.valid?(value.to_i)
37
+ def convert_value(original)
38
+ OpenapiParameters::Converter.convert(original, schema_for_validation)
39
+ rescue StandardError
40
+ original
38
41
  end
39
42
 
40
- def number_parameter_matches?(value)
41
- return false unless /^-?(\d+\.)?\d+$/.match?(value)
42
-
43
- schemer.valid?(value.to_f)
43
+ def schemer
44
+ @schemer ||= Validators::SchemaValidation.validation_schemer(schema_for_validation)
44
45
  end
45
46
  end
46
47
  end
@@ -35,20 +35,20 @@ module OpenapiContracts
35
35
  end
36
36
 
37
37
  # Returns an Enumerator over all Operations
38
- def operations(&block) # rubocop:disable Naming/BlockForwarding
38
+ def operations(&block)
39
39
  return enum_for(:operations) unless block_given?
40
40
 
41
41
  paths.each do |path|
42
- path.operations.each(&block) # rubocop:disable Naming/BlockForwarding
42
+ path.operations.each(&block)
43
43
  end
44
44
  end
45
45
 
46
46
  # Returns an Enumerator over all Responses
47
- def responses(&block) # rubocop:disable Naming/BlockForwarding
47
+ def responses(&block)
48
48
  return enum_for(:responses) unless block_given?
49
49
 
50
50
  operations.each do |operation|
51
- operation.responses.each(&block) # rubocop:disable Naming/BlockForwarding
51
+ operation.responses.each(&block)
52
52
  end
53
53
  end
54
54
 
@@ -1,6 +1,9 @@
1
1
  module OpenapiContracts
2
2
  class Match
3
- DEFAULT_OPTIONS = {request_body: false}.freeze
3
+ DEFAULT_OPTIONS = {
4
+ parameters: false,
5
+ request_body: false
6
+ }.freeze
4
7
  MIN_REQUEST_ANCESTORS = %w(Rack::Request::Env Rack::Request::Helpers).freeze
5
8
  MIN_RESPONSE_ANCESTORS = %w(Rack::Response::Helpers).freeze
6
9
 
@@ -42,6 +45,7 @@ module OpenapiContracts
42
45
  )
43
46
  validators = Validators::ALL.dup
44
47
  validators.delete(Validators::HttpStatus) unless @options[:status]
48
+ validators.delete(Validators::Parameters) unless @options[:parameters]
45
49
  validators.delete(Validators::RequestBody) unless @options[:request_body]
46
50
  validators.reverse
47
51
  .reduce(->(err) { err }) { |s, m| m.new(s, env) }
@@ -30,7 +30,7 @@ module OpenapiContracts
30
30
  # file list consists of
31
31
  # - root file
32
32
  # - all files in components/
33
- # - all path files referenced by the root file
33
+ # - all path & webhook files referenced by the root file
34
34
  def build_file_list
35
35
  list = {@rootfile.relative_path_from(@cwd) => Doc::Pointer[]}
36
36
  Dir[File.expand_path('components/**/*.yaml', @cwd)].each do |file|
@@ -38,16 +38,21 @@ module OpenapiContracts
38
38
  pointer = Doc::Pointer.from_path pathname.sub_ext('')
39
39
  list.merge! pathname => pointer
40
40
  end
41
- YAML.safe_load_file(@rootfile).fetch('paths') { {} }.each_pair do |k, v|
42
- next unless v['$ref'] && !v['$ref'].start_with?('#')
41
+ rootdata = YAML.safe_load_file(@rootfile)
42
+ %w(paths webhooks).each do |name|
43
+ rootdata.fetch(name) { {} }.each_pair do |k, v|
44
+ next unless v['$ref'] && !v['$ref'].start_with?('#')
43
45
 
44
- list.merge! Pathname(v['$ref']).cleanpath => Doc::Pointer['paths', k]
46
+ list.merge! Pathname(v['$ref']).cleanpath => Doc::Pointer[name, k]
47
+ end
45
48
  end
46
49
  list
47
50
  end
48
51
 
49
52
  def file_to_data(pathname, pointer)
50
53
  YAML.safe_load_file(@cwd.join(pathname)).tap do |data|
54
+ break {} unless data.present?
55
+
51
56
  transform_objects!(data, pathname.parent, pointer)
52
57
  end
53
58
  end
@@ -0,0 +1,21 @@
1
+ module OpenapiContracts::Validators
2
+ # Validates the input parameters, eg path/url parameters
3
+ class Parameters < Base
4
+ include SchemaValidation
5
+
6
+ private
7
+
8
+ def validate
9
+ operation.parameters.select(&:in_query?).each do |parameter|
10
+ if request.GET.key?(parameter.name)
11
+ value = request.GET[parameter.name]
12
+ unless parameter.matches?(value)
13
+ @errors << "#{value.inspect} is not a valid value for the query parameter #{parameter.name.inspect}"
14
+ end
15
+ elsif parameter.required?
16
+ @errors << "Missing query parameter #{parameter.name.inspect}"
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -4,6 +4,7 @@ module OpenapiContracts
4
4
  autoload :Documented, 'openapi_contracts/validators/documented'
5
5
  autoload :Headers, 'openapi_contracts/validators/headers'
6
6
  autoload :HttpStatus, 'openapi_contracts/validators/http_status'
7
+ autoload :Parameters, 'openapi_contracts/validators/parameters'
7
8
  autoload :RequestBody, 'openapi_contracts/validators/request_body'
8
9
  autoload :ResponseBody, 'openapi_contracts/validators/response_body'
9
10
  autoload :SchemaValidation, 'openapi_contracts/validators/schema_validation'
@@ -12,6 +13,7 @@ module OpenapiContracts
12
13
  ALL = [
13
14
  Documented,
14
15
  HttpStatus,
16
+ Parameters,
15
17
  RequestBody,
16
18
  ResponseBody,
17
19
  Headers
@@ -7,6 +7,7 @@ require 'active_support/core_ext/string'
7
7
  require 'rubygems/version'
8
8
 
9
9
  require 'json_schemer'
10
+ require 'openapi_parameters'
10
11
  require 'rack'
11
12
  require 'yaml'
12
13
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openapi_contracts
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.0
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - mkon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-09 00:00:00.000000000 Z
11
+ date: 2024-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -50,6 +50,26 @@ dependencies:
50
50
  - - "<"
51
51
  - !ruby/object:Gem::Version
52
52
  version: '2.2'
53
+ - !ruby/object:Gem::Dependency
54
+ name: openapi_parameters
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 0.3.3
60
+ - - "<"
61
+ - !ruby/object:Gem::Version
62
+ version: '0.4'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: 0.3.3
70
+ - - "<"
71
+ - !ruby/object:Gem::Version
72
+ version: '0.4'
53
73
  - !ruby/object:Gem::Dependency
54
74
  name: rack
55
75
  requirement: !ruby/object:Gem::Requirement
@@ -84,42 +104,42 @@ dependencies:
84
104
  requirements:
85
105
  - - "~>"
86
106
  - !ruby/object:Gem::Version
87
- version: 3.12.0
107
+ version: 3.13.0
88
108
  type: :development
89
109
  prerelease: false
90
110
  version_requirements: !ruby/object:Gem::Requirement
91
111
  requirements:
92
112
  - - "~>"
93
113
  - !ruby/object:Gem::Version
94
- version: 3.12.0
114
+ version: 3.13.0
95
115
  - !ruby/object:Gem::Dependency
96
116
  name: rubocop
97
117
  requirement: !ruby/object:Gem::Requirement
98
118
  requirements:
99
119
  - - '='
100
120
  - !ruby/object:Gem::Version
101
- version: 1.59.0
121
+ version: 1.64.1
102
122
  type: :development
103
123
  prerelease: false
104
124
  version_requirements: !ruby/object:Gem::Requirement
105
125
  requirements:
106
126
  - - '='
107
127
  - !ruby/object:Gem::Version
108
- version: 1.59.0
128
+ version: 1.64.1
109
129
  - !ruby/object:Gem::Dependency
110
130
  name: rubocop-rspec
111
131
  requirement: !ruby/object:Gem::Requirement
112
132
  requirements:
113
133
  - - '='
114
134
  - !ruby/object:Gem::Version
115
- version: 2.25.0
135
+ version: 2.31.0
116
136
  type: :development
117
137
  prerelease: false
118
138
  version_requirements: !ruby/object:Gem::Requirement
119
139
  requirements:
120
140
  - - '='
121
141
  - !ruby/object:Gem::Version
122
- version: 2.25.0
142
+ version: 2.31.0
123
143
  - !ruby/object:Gem::Dependency
124
144
  name: simplecov
125
145
  requirement: !ruby/object:Gem::Requirement
@@ -170,6 +190,7 @@ files:
170
190
  - lib/openapi_contracts/validators/documented.rb
171
191
  - lib/openapi_contracts/validators/headers.rb
172
192
  - lib/openapi_contracts/validators/http_status.rb
193
+ - lib/openapi_contracts/validators/parameters.rb
173
194
  - lib/openapi_contracts/validators/request_body.rb
174
195
  - lib/openapi_contracts/validators/response_body.rb
175
196
  - lib/openapi_contracts/validators/schema_validation.rb
@@ -196,7 +217,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
196
217
  - !ruby/object:Gem::Version
197
218
  version: '0'
198
219
  requirements: []
199
- rubygems_version: 3.4.22
220
+ rubygems_version: 3.5.11
200
221
  signing_key:
201
222
  specification_version: 4
202
223
  summary: Openapi schemas as API contracts