JapanRob
JapanRob

Reputation: 384

Rails 5 File POST file as body in Minitest

I have a small image file in my text/fixtures/filesfolder that I am trying to call an external API with. It is a JPG. I am trying to test it with this method in my controller test

 test 'post image to external API' do
    binding.pry
    image = fixture_file_upload('files/simple_image.jpg', 'image/jpg')
    post '/api/services/image_processor', params: {body: image}
    assert_response :success
  end

Unfortunately, if I do this the result is Invalid request parameters: invalid %-encoding, which makes sense because I'm posting a param and not a body.

How do I set my uploaded file to be the body of the request? I can post the file body with postman and it works excellently, but I'd like automate the process for testing.

Upvotes: 1

Views: 2434

Answers (2)

Mike Szyndel
Mike Szyndel

Reputation: 10592

The right way to do it is use following code in your controller

a) If you pass file to a method that expects a path (like CSV parser)

params[:file].path

b) or this if you need file contents

params[:file].read

And then in your test

file = fixture_file_upload('path/to/some/file.csv')
post '/api/endpoint',
     params: { file: file },
     headers: { 'content-type': 'multipart/form-data' }

This way in params you will find a properly working file upload

<ActionController::Parameters {"file"=>#<ActionDispatch::Http::UploadedFile:0x007ff3f1ea8e80 @tempfile= ...

Upvotes: 2

JapanRob
JapanRob

Reputation: 384

I used this:

image = fixture_file_upload('files/simple_file.jpg', 'image/jpg', :binary)
post '/api/services/image_processor', params: image.tempfile, headers: { 'CONTENT-TYPE': 'image/jpg' }
assert_response :success

Upvotes: -1

Related Questions