1

I have the following test for the create method on my controller

  before :each do
    request.env["HTTP_ACCEPT"] = 'application/json'
    request.env["CONTENT_TYPE"] = "application/json"

  end

  test "should post create" do
    params = {
      trip_id: 1,
      schedule: {
        price: 12.50,
        max_size: 1,
        time: "11:00 am",
        wdays: [0,1]
      }
    }

    post :create, params
    assert_response :success
  end

When this hits my create method, params[:schedule][:wdays] is changed from [0,1] to ["0", "1"]

This causes my test to fail because the wdays has to be a int array. I thought about doing a .to_i in my validation but that would allow ["hello", "world"] to become [0,0].

Oddly enough, this curl command, which I thought would be doing the same thing, works just fine

curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"trip_id":1, "schedule":{"price":12.50,"max_size":1,"wdays":[0,1],"time":"11:00 am"}}' http://localhost:3000/trips/1/schedules

How can I get my test to leave the array as an int array like in the curl?

If I can't get this functionality to work as is in the tests, should I change my validation to allow a string of arrays? If I do that, how should I prevent strings like "hello" from being valid?

This is my current validation:

  def valid_wdays
    if !wdays.is_a?(Array) || wdays.detect { |d| !(0..6).include?(d) }
      errors.add(:wdays, "should be an array of ints represeting days of the week")
    end
  end
7
  • 1
    You should remember that HTTP params only support strings Commented Nov 12, 2013 at 16:39
  • then why does the curl work? Commented Nov 12, 2013 at 16:47
  • This works in cURL because cURL uses the rails stack to process the request. Your controller test bypasses the full rails stack and basically calls .to_param on everything. github.com/rails/rails/blob/… You will have better luck with an integration test, because it actually uses ActionDispatch. Commented Nov 12, 2013 at 17:41
  • so does that mean I can't test this route here? Commented Nov 12, 2013 at 17:52
  • @bsiddiqui You can do anything, anywhere. Try adding this class to your test, and using this in your params: wdays: [IntParam.new(0),IntParam.new(1)] - class IntParam; def initialize int; @int = int; end; def to_param; @int; end; end Commented Nov 12, 2013 at 20:10

1 Answer 1

1

You need to specify that the request not only accepts JSON (-H "Accept: application/json" in curl, request.env["HTTP_ACCEPT"] = 'application/json' in the test), but sends data as JSON (-H "Content-type: application/json" in curl, nothing in the test).

Try something like

post :create, params.to_json, format: :json

or

post :create, params.to_json, {'CONTENT_TYPE' => 'application/json'}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.