2

I am using rails 5.2.3 and testing using rspec-rails (3.8.2), when I send request to rails like this

  let(:params) do
    {
      down_payment: 10_000,
      asking_price: 100_000,
      payment_schedule: 'weekly',
      amortization_period: 5
    }
  end
  it 'works' do
    get :calculate, params: params, format: :json
    expect(response.status).to eq 200
  end

I also tried

  it 'works' do
    get :calculate, params: params, as: :json
    expect(response.status).to eq 200
  end

in rails all integers get converted to string like this

<ActionController::Parameters {"amortization_period"=>"5", "asking_price"=>"100000", "down_payment"=>"10000", "payment_schedule"=>"weekly", "format"=>"json", "controller"=>"payment_amount", "action"=>"calculate", "payment_amount"=>{}} permitted: false>

But if I use curl to send a request I can see integer not being converted to string.

curl -X GET -H "Content-Type: application/json"  -d ‘{"asking_price": 100000 ,"payment_schedule": "monthly", "down_payment": 10000, "amortization_period": 5  }' http://localhost:3000/payment-amount

Thanks for any help!

icn
  • 17,126
  • 39
  • 105
  • 141
  • How are you sending them with curl that they are not being converted to string? I cannot reproduce this. – max pleaner May 16 '19 at 06:58
  • @maxpleaner Please see my updates. I have added `curl` command – icn May 16 '19 at 07:28
  • Because curl works like it is supposed to - follows the JSON standard - not what the rails-team thinks everyone "should be doing," and never mind most of the machines we interact with API-wise don't adhere to their religion. – JosephK Aug 19 '19 at 08:39
  • Note - same problem using rack-test on backend - the post method takes your json and adds backslashed-strings. If you use to: :json, it doesn't send the backslashes, but still converts your non-string values to strings, so no POSTs with integers being sent can ever be tested. – JosephK Aug 19 '19 at 08:41
  • Found a solution - posted to answer another question here: https://stackoverflow.com/a/57566937/2326613 – JosephK Aug 20 '19 at 05:01

3 Answers3

4

JSON payloads can contain five value types: string, number, integer, boolean and null.

HTTP query strings are, by contrast, only strings.

By default, request specs use the encoding specified in the HTTP spec - i.e. all parameters are strings. This is why you see the parameters get converted.

If your production system is sending JSON, you need to tell the test to do so too - e.g. by adding as: :json as you did above.

Tom Lord
  • 27,404
  • 4
  • 50
  • 77
  • 1
    Thanks, why I added `as: :json` it is still converting params to string? – icn May 16 '19 at 14:50
  • Cannot reproduce. When I add `as_json`, I get integers. Maybe you're using some extra library (that you haven't mentioned) which changes the behaviour. – Tom Lord May 16 '19 at 16:11
1

Just add as: :json format to your requests

post(graphql_path, params: params, as: :json)
itsnikolay
  • 17,415
  • 4
  • 65
  • 64
0

After a lot of tries, I found the solution to this issue. If you pass the params converted with to_json and pass 'CONTENT_TYPE' => 'application/json' as env, integers will be passed to the controller.

let(:params) do
  {
    down_payment: 10_000,
    asking_price: 100_000,
    payment_schedule: 'weekly',
    amortization_period: 5
  }
end

it 'works' do
  post '/', params.to_json, 'CONTENT_TYPE' => 'application/json'
end

This will work as expected.

Ayer
  • 120
  • 2
  • 6