rspec-openapi 0.3.13 → 0.3.18

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e2d47641978a7e3644aefc735a5ff71495bd12ab22d3371ff386d5733226afea
4
- data.tar.gz: ccd481a8593efa2a9d0db0cc10a7bb751df1cefac913b44aa93cdc70e7309d0b
3
+ metadata.gz: cd7d2eb0e69e2e60405a7d71d10acd3b2edf2d4db0358297a900200a0a69012e
4
+ data.tar.gz: 577545384d404ba11382ab4425e0bd40abeeb3e58db922e82d923f0d6d6ae8e9
5
5
  SHA512:
6
- metadata.gz: '097a157b4b7c17a1bef1aeb949d41507e09aa72f43dba5158b4a50b0659e44470b59e29d4609d24f04f4936a43e867a4e85834c0cdaa6ddde1096d304d194530'
7
- data.tar.gz: eb1a0c743fb8b64edf56d5a67165ef77afc6c0b48317c0bdfcda7449b1322591fd1c0539b9c4c5992efbab26c6fb3928ec156bcfa137200dce4535b35e0d85b6
6
+ metadata.gz: 5f60ee2cf93946405e3e151786965b3a0f68e53ad147a6d7613f59f46f834efd9a641d0f878943af934879d2f5e27e8c8d4cd55dac5288d62a85dc2b77009ddb
7
+ data.tar.gz: 7dc56150dfb4a8a5b526d7ec626b4ebc9c0680878cd1f976213490a489a598dfe2a285f01029e5a17cdbbe0d8b492fe79a2e51148ac24df94d532c404b0231fd
@@ -0,0 +1 @@
1
+ github: k0kubun
data/CHANGELOG.md CHANGED
@@ -1,3 +1,30 @@
1
+ ## v0.3.18
2
+
3
+ * Support nested query parameters
4
+ [#29](https://github.com/k0kubun/rspec-openapi/pull/29)
5
+
6
+ ## v0.3.17
7
+
8
+ * Rescue NotImplementedError in the after suite hook as well
9
+ [#28](https://github.com/k0kubun/rspec-openapi/pull/28)
10
+
11
+ ## v0.3.16
12
+
13
+ * Use `media_type` instead of `content_type` for Rails 6.1
14
+ [#26](https://github.com/k0kubun/rspec-openapi/pull/26)
15
+ * Avoid crashing the after suite hook when it fails to build schema
16
+ [#27](https://github.com/k0kubun/rspec-openapi/pull/27)
17
+
18
+ ## v0.3.15
19
+
20
+ * Fix an error when Content-Disposition header is inline
21
+ [#24](https://github.com/k0kubun/rspec-openapi/pull/24)
22
+
23
+ ## v0.3.14
24
+
25
+ * Avoid an error when an application calls `request.body.read`
26
+ [#20](https://github.com/k0kubun/rspec-openapi/pull/20)
27
+
1
28
  ## v0.3.13
2
29
 
3
30
  * Avoid crashing when there's no request made in a spec
@@ -6,6 +6,7 @@ require 'rspec/openapi/schema_file'
6
6
  require 'rspec/openapi/schema_merger'
7
7
 
8
8
  records = []
9
+ records_errors = []
9
10
 
10
11
  RSpec.configuration.after(:each) do |example|
11
12
  if example.metadata[:type] == :request && example.metadata[:openapi] != false
@@ -19,7 +20,21 @@ RSpec.configuration.after(:suite) do
19
20
  RSpec::OpenAPI::SchemaFile.new(RSpec::OpenAPI.path).edit do |spec|
20
21
  RSpec::OpenAPI::SchemaMerger.reverse_merge!(spec, RSpec::OpenAPI::DefaultSchema.build(title))
21
22
  records.each do |record|
22
- RSpec::OpenAPI::SchemaMerger.reverse_merge!(spec, RSpec::OpenAPI::SchemaBuilder.build(record))
23
+ begin
24
+ RSpec::OpenAPI::SchemaMerger.reverse_merge!(spec, RSpec::OpenAPI::SchemaBuilder.build(record))
25
+ rescue StandardError, NotImplementedError => e # e.g. SchemaBuilder raises a NotImplementedError
26
+ # NOTE: Don't fail the build
27
+ records_errors << [e, record]
28
+ end
23
29
  end
24
30
  end
31
+ if records_errors.any?
32
+ error_message = <<~EOS
33
+ RSpec::OpenAPI got errors building #{records_errors.size} requests
34
+
35
+ #{records_errors.map {|e, record| "#{e.inspect}: #{record.inspect}" }.join("\n")}
36
+ EOS
37
+ colorizer = ::RSpec::Core::Formatters::ConsoleCodes
38
+ RSpec.configuration.reporter.message colorizer.wrap(error_message, :failure)
39
+ end
25
40
  end
@@ -11,5 +11,6 @@ RSpec::OpenAPI::Record = Struct.new(
11
11
  :status, # @param [Integer] - 200
12
12
  :response_body, # @param [Object] - {"status" => "ok"}
13
13
  :response_content_type, # @param [String] - "application/json"
14
+ :response_content_disposition, # @param [String] - "inline"
14
15
  keyword_init: true,
15
16
  )
@@ -8,6 +8,7 @@ class << RSpec::OpenAPI::RecordBuilder = Object.new
8
8
  def build(context, example:)
9
9
  if rack_test?(context)
10
10
  request = ActionDispatch::Request.new(context.last_request.env)
11
+ request.body.rewind if request.body.respond_to?(:rewind)
11
12
  response = ActionDispatch::TestResponse.new(*context.last_response.to_a)
12
13
  else
13
14
  request = context.request
@@ -39,13 +40,14 @@ class << RSpec::OpenAPI::RecordBuilder = Object.new
39
40
  path_params: raw_path_params(request),
40
41
  query_params: request.query_parameters,
41
42
  request_params: raw_request_params(request),
42
- request_content_type: request.content_type,
43
+ request_content_type: request.media_type,
43
44
  summary: summary,
44
45
  tags: tags,
45
46
  description: RSpec::OpenAPI.description_builder.call(example),
46
47
  status: response.status,
47
48
  response_body: response_body,
48
- response_content_type: response.content_type,
49
+ response_content_type: response.media_type,
50
+ response_content_disposition: response.header["Content-Disposition"],
49
51
  ).freeze
50
52
  end
51
53
 
@@ -7,10 +7,11 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
7
7
  }
8
8
 
9
9
  if record.response_body
10
+ disposition = normalize_content_disposition(record.response_content_disposition)
10
11
  response[:content] = {
11
12
  normalize_content_type(record.response_content_type) => {
12
- schema: build_property(record.response_body),
13
- example: (record.response_body if example_enabled?),
13
+ schema: build_property(record.response_body, disposition: disposition),
14
+ example: response_example(record, disposition: disposition),
14
15
  }.compact,
15
16
  }
16
17
  end
@@ -34,6 +35,12 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
34
35
 
35
36
  private
36
37
 
38
+ def response_example(record, disposition:)
39
+ return nil if !example_enabled? || disposition
40
+
41
+ record.response_body
42
+ end
43
+
37
44
  def example_enabled?
38
45
  RSpec::OpenAPI.enable_example
39
46
  end
@@ -43,7 +50,7 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
43
50
 
44
51
  record.path_params.each do |key, value|
45
52
  parameters << {
46
- name: key.to_s,
53
+ name: build_parameter_name(key, value),
47
54
  in: 'path',
48
55
  required: true,
49
56
  schema: build_property(try_cast(value)),
@@ -53,7 +60,7 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
53
60
 
54
61
  record.query_params.each do |key, value|
55
62
  parameters << {
56
- name: key.to_s,
63
+ name: build_parameter_name(key, value),
57
64
  in: 'query',
58
65
  schema: build_property(try_cast(value)),
59
66
  example: (try_cast(value) if example_enabled?),
@@ -64,6 +71,16 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
64
71
  parameters
65
72
  end
66
73
 
74
+ def build_parameter_name(key, value)
75
+ key = key.to_s
76
+ if value.is_a?(Hash) && (value_keys = value.keys).size == 1
77
+ value_key = value_keys.first
78
+ build_parameter_name("#{key}[#{value_key}]", value[value_key])
79
+ else
80
+ key
81
+ end
82
+ end
83
+
67
84
  def build_request_body(record)
68
85
  return nil if record.request_content_type.nil?
69
86
  return nil if record.request_params.empty?
@@ -78,8 +95,8 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
78
95
  }
79
96
  end
80
97
 
81
- def build_property(value)
82
- property = build_type(value)
98
+ def build_property(value, disposition: nil)
99
+ property = build_type(value, disposition)
83
100
 
84
101
  case value
85
102
  when Array
@@ -94,7 +111,9 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
94
111
  property
95
112
  end
96
113
 
97
- def build_type(value)
114
+ def build_type(value, disposition)
115
+ return { type: 'string', format: 'binary' } if disposition
116
+
98
117
  case value
99
118
  when String
100
119
  { type: 'string' }
@@ -143,4 +162,8 @@ class << RSpec::OpenAPI::SchemaBuilder = Object.new
143
162
  def normalize_content_type(content_type)
144
163
  content_type&.sub(/;.+\z/, '')
145
164
  end
165
+
166
+ def normalize_content_disposition(content_disposition)
167
+ content_disposition&.sub(/;.+\z/, '')
168
+ end
146
169
  end
@@ -30,6 +30,13 @@ class << RSpec::OpenAPI::SchemaMerger = Object.new
30
30
  deep_reverse_merge!(base[key], value)
31
31
  elsif !base.key?(key)
32
32
  base[key] = value
33
+ elsif base[key].is_a?(Array) && value.is_a?(Array)
34
+ if key == "parameters"
35
+ # merge arrays
36
+ base[key] |= value
37
+ end
38
+ else
39
+ # no-op
33
40
  end
34
41
  end
35
42
  base
@@ -1,5 +1,5 @@
1
1
  module RSpec
2
2
  module OpenAPI
3
- VERSION = '0.3.13'
3
+ VERSION = '0.3.18'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-openapi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.13
4
+ version: 0.3.18
5
5
  platform: ruby
6
6
  authors:
7
7
  - Takashi Kokubun
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-02-12 00:00:00.000000000 Z
11
+ date: 2021-06-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -45,6 +45,7 @@ executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
+ - ".github/FUNDING.yml"
48
49
  - ".github/workflows/test.yml"
49
50
  - ".gitignore"
50
51
  - ".rspec"
@@ -89,7 +90,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
89
90
  - !ruby/object:Gem::Version
90
91
  version: '0'
91
92
  requirements: []
92
- rubygems_version: 3.2.6
93
+ rubygems_version: 3.1.2
93
94
  signing_key:
94
95
  specification_version: 4
95
96
  summary: Generate OpenAPI schema from RSpec request specs