diff --git a/lib/rspec/openapi/schema_builder.rb b/lib/rspec/openapi/schema_builder.rb index 92999075..641c27b4 100644 --- a/lib/rspec/openapi/schema_builder.rb +++ b/lib/rspec/openapi/schema_builder.rb @@ -199,7 +199,14 @@ def adjust_params(value) adjust_params(v) when Array result = v.map do |item| - item.is_a?(ActionDispatch::Http::UploadedFile) ? item.original_filename : item + case item + when ActionDispatch::Http::UploadedFile + item.original_filename + when Hash + adjust_params(item) + else + item + end end value[key] = result end diff --git a/spec/integration_tests/rails_test.rb b/spec/integration_tests/rails_test.rb index 64d97a6a..65109cd1 100644 --- a/spec/integration_tests/rails_test.rb +++ b/spec/integration_tests/rails_test.rb @@ -161,6 +161,15 @@ class ImageTest < ActionDispatch::IntegrationTest post '/images/upload_multiple', params: { images: [image, image] } assert_response 200 end + + test 'returns a image payload with upload multiple nested' do + png = 'iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAAAAADhZOFXAAAADklEQVQIW2P4DwUMlDEA98A/wTjP + QBoAAAAASUVORK5CYII='.unpack1('m') + File.binwrite('test.png', png) + image = Rack::Test::UploadedFile.new('test.png', 'image/png') + post '/images/upload_multiple_nested', params: { images: [{ image: image }, { image: image }] } + assert_response 200 + end end class ExtraRoutesTest < ActionDispatch::IntegrationTest diff --git a/spec/rails/app/controllers/images_controller.rb b/spec/rails/app/controllers/images_controller.rb index bcb49eb7..b2aab36e 100644 --- a/spec/rails/app/controllers/images_controller.rb +++ b/spec/rails/app/controllers/images_controller.rb @@ -25,6 +25,10 @@ def upload_multiple send_image end + def upload_multiple_nested + send_image + end + private def send_image diff --git a/spec/rails/config/routes.rb b/spec/rails/config/routes.rb index a0737865..4acd108b 100644 --- a/spec/rails/config/routes.rb +++ b/spec/rails/config/routes.rb @@ -8,6 +8,7 @@ post 'upload' post 'upload_nested' post 'upload_multiple' + post 'upload_multiple_nested' end end resources :users, only: [:show, :create] do diff --git a/spec/rails/doc/openapi.json b/spec/rails/doc/openapi.json index 0353c573..e6518ace 100644 --- a/spec/rails/doc/openapi.json +++ b/spec/rails/doc/openapi.json @@ -786,9 +786,9 @@ } } }, - "/images/upload_multiple": { + "/images/upload_nested": { "post": { - "summary": "upload_multiple", + "summary": "upload_nested", "tags": [ "Image" ], @@ -798,30 +798,81 @@ "schema": { "type": "object", "properties": { - "images": { - "type": "array", - "items": { - "type": "string", - "format": "binary" - } + "nested_image": { + "type": "object", + "properties": { + "image": { + "type": "string", + "format": "binary" + }, + "caption": { + "type": "string" + } + }, + "required": [ + "image", + "caption" + ] } }, "required": [ - "images" + "nested_image" ] }, "example": { - "images": [ - "test.png", - "test.png" + "nested_image": { + "image": "test.png", + "caption": "Some caption" + } + } + } + } + }, + "responses": { + "200": { + "description": "returns a image payload with upload nested", + "content": { + "image/png": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + } + } + } + }, + "/images/upload": { + "post": { + "summary": "upload", + "tags": [ + "Image" + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "image": { + "type": "string", + "format": "binary" + } + }, + "required": [ + "image" ] + }, + "example": { + "image": "test.png" } } } }, "responses": { "200": { - "description": "returns a image payload with upload multiple", + "description": "returns a image payload with upload", "content": { "image/png": { "schema": { @@ -834,9 +885,9 @@ } } }, - "/images/upload_nested": { + "/images/upload_multiple_nested": { "post": { - "summary": "upload_nested", + "summary": "upload_multiple_nested", "tags": [ "Image" ], @@ -846,39 +897,42 @@ "schema": { "type": "object", "properties": { - "nested_image": { - "type": "object", - "properties": { - "image": { - "type": "string", - "format": "binary" + "images": { + "type": "array", + "items": { + "type": "object", + "properties": { + "image": { + "type": "string", + "format": "binary" + } }, - "caption": { - "type": "string" - } - }, - "required": [ - "image", - "caption" - ] + "required": [ + "image" + ] + } } }, "required": [ - "nested_image" + "images" ] }, "example": { - "nested_image": { - "image": "test.png", - "caption": "Some caption" - } + "images": [ + { + "image": "test.png" + }, + { + "image": "test.png" + } + ] } } } }, "responses": { "200": { - "description": "returns a image payload with upload nested", + "description": "returns a image payload with upload multiple nested", "content": { "image/png": { "schema": { @@ -891,9 +945,9 @@ } } }, - "/images/upload": { + "/images/upload_multiple": { "post": { - "summary": "upload", + "summary": "upload_multiple", "tags": [ "Image" ], @@ -903,24 +957,30 @@ "schema": { "type": "object", "properties": { - "image": { - "type": "string", - "format": "binary" + "images": { + "type": "array", + "items": { + "type": "string", + "format": "binary" + } } }, "required": [ - "image" + "images" ] }, "example": { - "image": "test.png" + "images": [ + "test.png", + "test.png" + ] } } } }, "responses": { "200": { - "description": "returns a image payload with upload", + "description": "returns a image payload with upload multiple", "content": { "image/png": { "schema": { diff --git a/spec/rails/doc/openapi.yaml b/spec/rails/doc/openapi.yaml index c9def75f..7e7eb55d 100644 --- a/spec/rails/doc/openapi.yaml +++ b/spec/rails/doc/openapi.yaml @@ -526,36 +526,6 @@ paths: example: - name: file.png tags: [] - "/images/upload_multiple": - post: - summary: upload_multiple - tags: - - Image - requestBody: - content: - multipart/form-data: - schema: - type: object - properties: - images: - type: array - items: - type: string - format: binary - required: - - images - example: - images: - - test.png - - test.png - responses: - '200': - description: returns a image payload with upload multiple - content: - image/png: - schema: - type: string - format: binary "/images/upload": post: summary: upload @@ -618,3 +588,68 @@ paths: schema: type: string format: binary + "/images/upload_multiple_nested": + post: + summary: upload_multiple_nested + tags: + - Image + requestBody: + content: + multipart/form-data: + schema: + type: object + properties: + images: + type: array + items: + type: object + properties: + image: + type: string + format: binary + required: + - image + required: + - images + example: + images: + - image: test.png + - image: test.png + responses: + '200': + description: returns a image payload with upload multiple nested + content: + image/png: + schema: + type: string + format: binary + "/images/upload_multiple": + post: + summary: upload_multiple + tags: + - Image + requestBody: + content: + multipart/form-data: + schema: + type: object + properties: + images: + type: array + items: + type: string + format: binary + required: + - images + example: + images: + - test.png + - test.png + responses: + '200': + description: returns a image payload with upload multiple + content: + image/png: + schema: + type: string + format: binary diff --git a/spec/requests/rails_spec.rb b/spec/requests/rails_spec.rb index 186174a1..d5febe6c 100644 --- a/spec/requests/rails_spec.rb +++ b/spec/requests/rails_spec.rb @@ -164,6 +164,20 @@ expect(response.status).to eq(200) end end + + describe '#upload_multiple_nested' do + before do + png = 'iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAAAAADhZOFXAAAADklEQVQIW2P4DwUMlDEA98A/wTjP + QBoAAAAASUVORK5CYII='.unpack1('m') + File.binwrite('test.png', png) + end + let(:image) { Rack::Test::UploadedFile.new('test.png', 'image/png') } + + it 'returns a image payload with upload multiple nested' do + post '/images/upload_multiple_nested', params: { images: [{ image: image }, { image: image }] } + expect(response.status).to eq(200) + end + end end RSpec.describe 'Extra routes', type: :request do