I'm using rswag to test a rather common RubyOnRails JSON Api application, but I can't figure out a rather common case where I upload a file to an endpoint.
The endpoint expects the usual data
attribute in the request body with a file
attribute containing the binary, and I cannot make rswag to generate a request with the correct parameters.
path '/documents' do
post 'Creates a document' do
tags 'Documents'
consumes 'multipart/form-data'
produces 'application/vnd.api+json'
parameter name: 'data',
description: 'Whatever',
attributes: {
schema: {
type: :object,
properties: {
file: { type: :binary },
},
},
}
response '201', 'success' do
let(:data) do
{
attributes: {
file: Rack::Test::UploadedFile.new($REALARGS),
},
}
end
schema "$ref": '#/definitions/post_document_responses/201'
run_test! do |_example|
# ACTUAL TEST
end
end
end
end
There are some other simpler parameters (Authorization for example) that are correctly generated, I'm then sure rswag
is hooked correctly.
The request I'm seeing has no parameters, I can remove the data
parameter and nothing changes. I've tried a million combinations, always the same result and I don't know what's going on.
The params
the controller expects is data[attributes][file]
.
Can anyone help me?
The parameter
block needs to specify where it will be inserted. There's an example spec where I found a reference to :formData
, which it turns out must be set (i.e. you can't use :body
, it just sends an empty request).
After a bit of jiggery-pokery I managed to get your example working with the nested attribute in the form data:
path '/documents' do
post 'Creates a document' do
tags 'Documents'
consumes 'multipart/form-data'
produces 'application/vnd.api+json'
parameter name: 'data[attributes][file]',
description: 'Whatever',
in: :formData,
attributes: {
schema: {
type: :object,
properties: {
file: { type: :binary },
},
},
}
response '201', 'success' do
let(:"data[attributes][file]") { Rack::Test::UploadedFile.new(Rails.root.join("spec/requests/api/v1/documents_post_spec.rb")) }
end
schema "$ref": '#/definitions/post_document_responses/201'
run_test! do |_example|
# ACTUAL TEST
end
end
end
end