openapi_first
openapi_first copied to clipboard
Binary response gets converted to an array and throws a response validation error
I've stumbled on this error:
My API responds with an binary stream (file attachment). In my openapi.yml the response is described like this:
...
content:
"*/*":
schema:
type: string
format: binary
...
Running my tests I have response validation enabled via the middleware:
if Rails.env.test?
use OpenapiFirst::Middlewares::ResponseValidation,
spec: Rails.root.join("public", "api", "v1", "openapi.yml"),
raise_error: true
end
Now I have the problem that in the gem the private method read_body in openapi_first/middlewares/response_validation.rb is defined like this:
def read_body(body)
return body.to_ary if body.respond_to?(:to_ary)
result = []
body.each { |part| result << part }
result
end
The body is parsed into an ActionDispatch::Response::RackBody This class responds to to_ary (though the original reponse was a binary stream string)
Now I get the validation error because it is not expecting an array but a string.
Am I missing something?
Cheers Bijan
Hi. ~Can you try https://github.com/ahx/openapi_first/pull/282 to see if that fixes the problem?~ I just released 2.0.4, which should fix this. Thanks for the report.
Hey, thx for your effort. I'll be able to check tomorrow. Will of course let you know :)
I've been on a rather long break... Sorry to come back to this just now. I upgraded and am still hitting this error:
Api::V1::ImapProvidersControllerTest#test_should_show_attachment:
RuntimeError: Neutered Exception OpenapiFirst::ResponseInvalidError: Response body is invalid: value at root is not a string
test/controllers/api/v1/attachments_controller_test.rb:19:in `block in <class:ImapProvidersControllerTest>'
Am I missing something obvious? 🤔
For context:
This is my test
test "should show attachment" do
get api_v1_provider_message_attachment_url(@provider, @message_with_attachment_id, @attachment_id),
headers: auth_header(@api_key),
as: :json
assert_response :success
end
And this is the openapi.yml spec part:
/api/v1/providers/{provider_id}/messages/{message_id}/attachments/{attachment_id}:
get:
summary: Fetch an attached file
tags:
- Messages
description: |-
Fetch an attached file from a Message.
This endpoint will return the file as a binary stream.
You will use the download links in the Message response
to determine which file to download.
operationId: messages_attachments_show
security:
- bearerAuth: []
parameters:
- $ref: "#/components/parameters/provider_id"
- $ref: "#/components/parameters/message_id"
- $ref: "#/components/parameters/attachment_id"
- $ref: "#/components/parameters/mailbox"
responses:
"200":
description: successful
headers:
Content-Disposition:
schema:
type: string
description: Content-Disposition Header Detail
Content-Transfer-Encoding:
schema:
type: string
description: Content-Transfer-Encoding Header Detail
content:
"*/*":
schema:
type: string
format: binary
"400":
description: bad_request
content:
application/vnd.api+json:
schema:
$ref: "#/components/schemas/jsonApiErrors"
"401":
description: unauthorized
"403":
description: forbidden
"404":
description: not_found
content:
application/vnd.api+json:
schema:
$ref: "#/components/schemas/jsonApiErrors"
"422":
description: unprocessable entity
content:
application/vnd.api+json:
schema:
$ref: "#/components/schemas/jsonApiErrors"
Hi. Thanks for taking a look at this again. I think I should try to reproduce this in a real Rails app. I have started to put something together based on based on the train-travel API project. I will try to add a second API description to the example Rails app to reproduce this issue. I will probably try to do that at the end of this week.
What does "Neutered Exception" even mean?
Well... Basically that it doesn't crash and instead gets somehow handled 👯 :D Let me know if I can be of help debugging.
Well, two weeks have passed and I did not get to work on this. Sorry. If you have time to compile an example app with a failing rspec request test, that would be very helpful.
Alright. I think I got it fixed in 2.1.1 via https://github.com/ahx/openapi_first/pull/289.
Yes it's fixed indeed :) Well done!!!