Rspec format Post parameters to String values
Asked Answered
S

5

8

When I send an object json all fields inside are changed to string, breaking my validation in the controller and i get the following error.

Api::V1::BillsController POST #create when logged in 
     Failure/Error: post :create, { bill: bill_attributes }
     Apipie::ParamInvalid:
       Invalid parameter 'value' value "41.64794235693306": Must be Float
     # ./app/controllers/concerns/exception_aspects.rb:4:in exception_wrapper
     # ./spec/controllers/api/v1/bills_controller_spec.rb:135:in block (4 levels) in <top (required)>

My test I try indicate request.headers['Content-Type'] = 'application/json'

let(:bill_attributes) { FactoryGirl.attributes_for :bill }

before(:each) do
   request.headers['Content-Type'] = 'application/json'
   post :create, { bill: bill_attributes }
end

it "when is valid description" do
    expect(json_response[:description]).to eq(bill_attributes[:description])
end

My factory is

FactoryGirl.define do
 factory :bill do
  description { FFaker::Lorem.phrase }
  value { (rand() * 100).to_f }
 end
end

My controller validations are

api :POST, "/bills", "Add a new bill to an event"
description "Add a new bill"
param :bill, Hash, :required => true, :action_aware => true do
    param :description, String, "Bill description"
    param :bill_photo, Hash, :required => false do
        param :base64image, String, "Base 64 image file"
    end
    param :value, Float, "Amount of the bill"
end

I try to change validation :value from Float to :number but the problem continues

I am using rails 4.2.3 and rspec 3.3.0

Segmentation answered 19/11, 2015 at 15:24 Comment(4)
I thought all parameters were submitted as strings. How will a float be submitted to the api?Tallman
@Swards I try to send an object json { bill: { description: 'this is description', value:52.54 } }Segmentation
If you look at the params hash in the controller, all the params will be strings. You can test if the format of the string would be a valid floatTallman
If your json-consumer is expecting a non-string value, the controller-action will fail, and testing is not possible.Guenna
S
3

I added format json to post request and It worked like charm

before(:each) do
   post :create, { bill: bill_attributes, format: :json }
end
Segmentation answered 24/11, 2015 at 17:13 Comment(1)
This doesn't work anymore. RajeshT has the right answer.Excruciate
H
23
post :create, params: {}, as: :json

This is what works in Rails 5.0.3 and rspec-rails 3.6.0

Rails controller specs now inherit from ActionDispatch::IntegrationTest instead of ActionController::TestCase. But RSpec controller specs still use ActionController::TestCase which is deprecated. Relevant Rails commit here

Hellbent answered 22/6, 2017 at 15:43 Comment(1)
But "as: :json" with "post" converts my integers to strings.Guenna
S
3

I added format json to post request and It worked like charm

before(:each) do
   post :create, { bill: bill_attributes, format: :json }
end
Segmentation answered 24/11, 2015 at 17:13 Comment(1)
This doesn't work anymore. RajeshT has the right answer.Excruciate
C
1

None of above works for me.(rails 5.1.7, rspec 3.6)
The simple way you can give it a try is stub ActionController::Parameters In my case, in controller I always use permit for strong parameters.

def product_parameters
  _params = params.permit :name, :price

  # validate for price is integer
  raise BadRequest, code: 'blah_code' unless _params[:price].is_a?(Integer)
end

and then in Rspec I stub ActionController::Parameters like below

allow_any_instance_of(ActionController::Parameters).to receive(:permit).and_return(ActionController::Parameters.new(name: 'product name', price: 3000).permit(:name, :price)

just like that, and Rspec test checking Integer will work

NOTE: This can also apply with send boolean, float in params too.

Comprise answered 11/10, 2019 at 2:22 Comment(0)
D
0

For Rails 4 We can try this

post 'orders.json', JSON.dump(order: {boolean: true, integer: 123}), "CONTENT_TYPE" => "application/json"
Dumdum answered 14/12, 2018 at 4:51 Comment(0)
A
0

In my case using rails 4.2, rspec 3.5 and ruby 2.3

post '/api/webhooks/v1/subscriptions', { abc: 134 }.to_json, headers

the to_json part is the most important here and the headers have:

let(:headers) do
  {
    'Authorization' => 'Basic my-token',
    'Content-Type' => 'application/json'
  }
end
Arber answered 13/11, 2020 at 21:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.