Search code examples
ruby-on-railsminitest

Minitest to process a JSON string in a turbo stream


A successful action logged:

Processing by CartsController#update_receipt_number as TURBO_STREAM
  Parameters: {"code_json_data"=>"{\"code_data\":\"69aabaa2f610860c827f27fb386d4\",\"id\":6}", "id"=>"6"}

when tested as follows

post update_receipt_number_cart_url(carts(:thirty_one), format: :turbo_stream), params: { code_json_data: 
  { code_data: '69aabaa2f610860c827f27fb386d4', id: carts(:thirty_one).id } 
}, as: :json 

attempted both with and without , as: :json as per API documentation with identical results

does not process the data as defined in the test:

TypeError: no implicit conversion of ActionController::Parameters into String
    app/controllers/carts_controller.rb:192:in `update_receipt_number'

where the controller line states result = JSON.parse(params[:code_json_data])

How should this test be cast to provide a proper JSON parameter hash


Solution

  • The problem here is that you're passing the format parameter in the query string:

    update_receipt_number_cart_url(carts(:thirty_one), format: :turbo_stream)
    

    This overrides the headers which specify the type of both the request and the desired response. as: :json won't work either as it specifies both.

    If you're sending JSON to the server you and want the response in the form of a turbo stream you should send the correct headers:

    post update_receipt_number_cart_url(carts(:thirty_one)), 
      params: { code_json_data: 
        { code_data: '69aabaa2f610860c827f27fb386d4', id: carts(:thirty_one).id } 
      }, 
      headers: {
        content_type: 'application/json',      # what i'm sending in the request body
        accept: 'text/vnd.turbo-stream.html'   # please give me this back 
      }
    

    where the controller line states result = JSON.parse(params[:code_json_data])

    Don't do that. If you send the correct headers (which you should) you should not need to ever manually parse JSON. Rack has got you covered.