Module: OpenApi::Rswag::Specs::ExampleGroupHelpers
- Defined in:
- lib/open_api/rswag/specs/example_group_helpers.rb
Instance Method Summary collapse
-
#description(value = nil) ⇒ Object
NOTE: ‘description’ requires special treatment because ExampleGroup already defines a method with that name.
-
#examples(example = nil) ⇒ Object
NOTE: Similar to ‘description’, ‘examples’ need to handle the case when being invoked with no params to avoid overriding ‘examples’ method of rspec-core ExampleGroup.
- #header(name, attributes) ⇒ Object
-
#merge_other_examples!(example_metadata) ⇒ Object
checks the examples in the parameters should be able to add $ref and externalValue examples.
- #parameter(attributes) ⇒ Object
- #path(template, metadata = {}, &block) ⇒ Object
-
#request_body(attributes) ⇒ Object
MUST HAVES need to run “‘npm install“` in rswag-ui dir to get assets to load not sure if its an asset issue or what but this should load => localhost:3000/api-docs/index.html TODO: fix examples in the main README.
- #request_body_json(schema:, required: true, description: nil, examples: nil) ⇒ Object
- #request_body_multipart(schema:, description: nil) ⇒ Object
- #request_body_text_plain(required: false, description: nil, examples: nil) ⇒ Object
-
#request_body_xml(schema:, required: false, description: nil, examples: nil) ⇒ Object
TODO: add examples to this like we can for json, might be large lift as many assumptions are made on content-type.
- #response(code, description, metadata = {}, &block) ⇒ Object
- #run_test!(&block) ⇒ Object
- #schema(value, content_type: 'application/json') ⇒ Object
Instance Method Details
#description(value = nil) ⇒ Object
NOTE: ‘description’ requires special treatment because ExampleGroup already defines a method with that name. Provide an override that supports the existing functionality while also setting the appropriate metadata if applicable
29 30 31 32 33 |
# File 'lib/open_api/rswag/specs/example_group_helpers.rb', line 29 def description(value = nil) return super() if value.nil? [:operation][:description] = value end |
#examples(example = nil) ⇒ Object
NOTE: Similar to ‘description’, ‘examples’ need to handle the case when being invoked with no params to avoid overriding ‘examples’ method of rspec-core ExampleGroup
177 178 179 180 181 |
# File 'lib/open_api/rswag/specs/example_group_helpers.rb', line 177 def examples(example = nil) return super() if example.nil? [:response][:examples] = example end |
#header(name, attributes) ⇒ Object
163 164 165 166 167 168 169 170 171 172 |
# File 'lib/open_api/rswag/specs/example_group_helpers.rb', line 163 def header(name, attributes) [:response][:headers] ||= {} if attributes[:type] && attributes[:schema].nil? attributes[:schema] = {type: attributes[:type]} attributes.delete(:type) end [:response][:headers][name] = attributes end |
#merge_other_examples!(example_metadata) ⇒ Object
checks the examples in the parameters should be able to add $ref and externalValue examples. This syntax would look something like this in the integration _spec.rb file
request_body_json schema: { ‘$ref’ => ‘#/components/schemas/blog’ },
examples: [:blog, {name: :external_blog,
externalValue: 'http://api.sample.org/myjson_example'},
{name: :another_example,
'$ref' => '#/components/examples/flexible_blog_example'}]
The first value :blog, points to a let param of the same name, and is used to make the request in the integration test (it is used to build the request payload)
The second item in the array shows how to add an externalValue for the examples in the requestBody section The third item shows how to add a $ref item that points to the components/examples section of the swagger spec.
NOTE: that the externalValue will produce valid example syntax in the swagger output, but swagger-ui will not show it yet
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
# File 'lib/open_api/rswag/specs/example_group_helpers.rb', line 199 def merge_other_examples!() # example.metadata[:operation][:requestBody][:content]['application/json'][:examples] content_node = [:operation][:requestBody][:content]['application/json'] return unless content_node external_example = [:operation]&.dig(:parameters)&.detect { |p| p[:in] == :body && p[:name].is_a?(Hash) && p[:name][:externalValue] } || {} ref_example = [:operation]&.dig(:parameters)&.detect { |p| p[:in] == :body && p[:name].is_a?(Hash) && p[:name]['$ref'] } || {} examples_node = content_node[:examples] ||= {} nodes_to_add = [] nodes_to_add << external_example unless external_example.empty? nodes_to_add << ref_example unless ref_example.empty? nodes_to_add.each do |node| json_request_examples = examples_node ||= {} other_name = node[:name][:name] other_key = node[:name][:externalValue] ? :externalValue : '$ref' if other_name json_request_examples.merge!(other_name => {other_key => node[:param_value]}) end end end |
#parameter(attributes) ⇒ Object
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/open_api/rswag/specs/example_group_helpers.rb', line 135 def parameter(attributes) if attributes[:in] && attributes[:in].to_sym == :path attributes[:required] = true end if attributes[:type] && attributes[:schema].nil? attributes[:schema] = {type: attributes[:type]} end if .key?(:operation) [:operation][:parameters] ||= [] [:operation][:parameters] << attributes else [:path_item][:parameters] ||= [] [:path_item][:parameters] << attributes end end |
#path(template, metadata = {}, &block) ⇒ Object
8 9 10 11 |
# File 'lib/open_api/rswag/specs/example_group_helpers.rb', line 8 def path(template, = {}, &block) [:path_item] = { template: template } describe(template, , &block) end |
#request_body(attributes) ⇒ Object
MUST HAVES need to run “‘npm install“` in rswag-ui dir to get assets to load not sure if its an asset issue or what but this should load => localhost:3000/api-docs/index.html TODO: fix examples in the main README
51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/open_api/rswag/specs/example_group_helpers.rb', line 51 def request_body(attributes) # can make this generic, and accept any incoming hash (like parameter method) attributes.compact! if [:operation][:requestBody].blank? [:operation][:requestBody] = attributes elsif [:operation][:requestBody] && [:operation][:requestBody][:content] # merge in content_hash = [:operation][:requestBody][:content] incoming_content_hash = attributes[:content] content_hash.merge!(incoming_content_hash) if incoming_content_hash end end |
#request_body_json(schema:, required: true, description: nil, examples: nil) ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/open_api/rswag/specs/example_group_helpers.rb', line 65 def request_body_json(schema:, required: true, description: nil, examples: nil) passed_examples = Array(examples) content_hash = { 'application/json' => { schema: schema, examples: examples }.compact! || {} } request_body(description: description, required: required, content: content_hash) if passed_examples.any? # the request_factory is going to have to resolve the different ways that the example can be given # it can contain a 'value' key which is a direct hash (easiest) # it can contain a 'external_value' key which makes an external call to load the json # it can contain a '$ref' key. Which points to #/components/examples/blog passed_examples.each do |passed_example| if passed_example.is_a?(Symbol) example_key_name = passed_example # TODO: write more tests around this adding to the parameter # if symbol try and use save_request_example param_attributes = { name: example_key_name, in: :body, required: required, param_value: example_key_name, schema: schema } parameter(param_attributes) elsif passed_example.is_a?(Hash) && passed_example[:externalValue] param_attributes = { name: passed_example, in: :body, required: required, param_value: passed_example[:externalValue], schema: schema } parameter(param_attributes) elsif passed_example.is_a?(Hash) && passed_example['$ref'] param_attributes = { name: passed_example, in: :body, required: required, param_value: passed_example['$ref'], schema: schema } parameter(param_attributes) end end end end |
#request_body_multipart(schema:, description: nil) ⇒ Object
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/open_api/rswag/specs/example_group_helpers.rb', line 104 def request_body_multipart(schema:, description: nil) content_hash = { 'multipart/form-data' => { schema: schema }} request_body(description: description, content: content_hash) schema.extend(Hashie::Extensions::DeepLocate) file_properties = schema.deep_locate ->(_k, v, _obj) { v == :binary } hash_locator = [] file_properties.each do |match| hash_match = schema.deep_locate ->(_k, v, _obj) { v == match } hash_locator.concat(hash_match) unless hash_match.empty? end property_hashes = hash_locator.flat_map do |locator| locator.select { |_k,v| file_properties.include?(v) } end existing_keys = [] property_hashes.each do |property_hash| property_hash.keys.each do |k| if existing_keys.include?(k) next else file_name = k existing_keys << k parameter name: file_name, in: :formData, type: :file, required: true end end end end |
#request_body_text_plain(required: false, description: nil, examples: nil) ⇒ Object
92 93 94 95 |
# File 'lib/open_api/rswag/specs/example_group_helpers.rb', line 92 def request_body_text_plain(required: false, description: nil, examples: nil) content_hash = { 'test/plain' => { schema: {type: :string}, examples: examples }.compact! || {} } request_body(description: description, required: required, content: content_hash) end |
#request_body_xml(schema:, required: false, description: nil, examples: nil) ⇒ Object
TODO: add examples to this like we can for json, might be large lift as many assumptions are made on content-type
98 99 100 101 102 |
# File 'lib/open_api/rswag/specs/example_group_helpers.rb', line 98 def request_body_xml(schema:,required: false, description: nil, examples: nil) passed_examples = Array(examples) content_hash = { 'application/xml' => { schema: schema, examples: examples }.compact! || {} } request_body(description: description, required: required, content: content_hash) end |
#response(code, description, metadata = {}, &block) ⇒ Object
153 154 155 156 |
# File 'lib/open_api/rswag/specs/example_group_helpers.rb', line 153 def response(code, description, = {}, &block) [:response] = { code: code, description: description } context(description, , &block) end |
#run_test!(&block) ⇒ Object
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 |
# File 'lib/open_api/rswag/specs/example_group_helpers.rb', line 222 def run_test!(&block) # NOTE: rspec 2.x support if RSPEC_VERSION < 3 before do submit_request(example.) end it "returns a #{[:response][:code]} response" do () block.call(response) if block_given? end else before do |example| submit_request(example.) # end it "returns a #{[:response][:code]} response" do |example| (example., &block) example.instance_exec(response, &block) if block_given? end after do |example| body_parameter = example.[:operation]&.dig(:parameters)&.detect { |p| p[:in] == :body && p[:required] } if body_parameter && respond_to?(body_parameter[:name]) && example.[:operation][:requestBody][:content]['application/json'] # save response examples by default if example.[:response][:examples].nil? || example.[:response][:examples].empty? example.[:response][:examples] = { 'application/json' => JSON.parse(response.body, symbolize_names: true) } unless response.body.to_s.empty? end # save request examples using the let(:param_name) { REQUEST_BODY_HASH } syntax in the test if response.code.to_s =~ /^2\d{2}$/ example.[:operation][:requestBody][:content]['application/json'] = { examples: {} } unless example.[:operation][:requestBody][:content]['application/json'][:examples] json_request_examples = example.[:operation][:requestBody][:content]['application/json'][:examples] json_request_examples[body_parameter[:name]] = { value: send(body_parameter[:name]) } example.[:operation][:requestBody][:content]['application/json'][:examples] = json_request_examples end end self.class.merge_other_examples!(example.) if example.[:operation][:requestBody] end end end |
#schema(value, content_type: 'application/json') ⇒ Object
158 159 160 161 |
# File 'lib/open_api/rswag/specs/example_group_helpers.rb', line 158 def schema(value, content_type: 'application/json') content_hash = {content_type => {schema: value}} [:response][:content] = content_hash end |