ruby-on-railsrubyhttphttp-status-code-406actiondispatch

Rails responds with status code 406


I have been working on a test for my function inside Ruby on Rails. However, the test (which expects a status code of :success) fails after receiving a status code 406. Here's the exact failure log:

Failure: Expected response to be a <:success>, but was <406>.
test_should_post_comment_through_token_successfully(CommentControllerTest)
test/functional/comment_controller_test.rb:271:in `block in <class:CommentControllerTest>'

I read a little about the 406 response, and found out that it stands of "Not Acceptable". so I tried setting the Accept, Content-Type, Accept-Language and Accept-Charset headers but I have had no luck.

Here's the code for my test:

test 'should post comment through token successfully' do
  @params = {
    id: 1,
    body: "Test Comment",
    username: "Bob"
  }

  @headers = {
    "Accept" => "application/json",
    "Accept-Language" => "en-US",
    "Accept-Charset" => "utf-8",
    "Content-Type" => "application/json",
    "Token" => "abcdefg12345"
  }

  get :create_by_token, @params, @headers
  assert_response :success
end

The create_by_token function inside the controller:

def create_by_token
  @node = Node.find params[:id]
  @user = User.find_by_username params[:username]
  @body = params[:body]
  @token = request.headers['Token']
  p request.headers["Accept"]
  p request.headers["Content-Type"]
  p request.headers["Token"]

  if @user && @user.token == @token
    begin
      @comment = create_comment(@node, @user, @body)
      msg = {
        status: :created,
        message: "Created"
      }
      respond_to do |format|
        format.xml { render xml: msg.to_xml }
        format.json { render json: msg.to_json }
      end
    rescue CommentError
      msg = {
        status: :bad_request,
        message: "Bad Request"
      }
      respond_to do |format|
        format.xml { render xml: msg.to_xml }
        format.json { render json: msg.to_json }
      end
    end
  else
    msg = {
      status: :unauthorized,
      message: "Unauthorized"
    }
    respond_to do |format|
      format.xml { render xml: msg.to_xml }
      format.json { render json: msg.to_json }
    end
  end
end

My route:

post '/bot/comment.:format', to: 'comment#create_by_token'

Am I missing something crucial? How do I go about solving this issue?

I would be happy to provide any other information you would need.


Solution

  • Oh, stupid me. I realized that among all the params I was passing, the format was also being passed inside the URL. However, as in the test I was not mentioning a URL which I could pass in the format as the suffix (.xml or .json), I would have to mention the format inside the params explicitly. Here's the updated test code:

    test 'should post comment through token successfully' do
      @params = {
        id: 1,
        body: "Test Comment",
        username: "Bob",
        format: 'json'
      }
    
      @headers = {
        "token" => "abcdefg12345"
      }
    
      post :create_by_token, @params, @headers
      assert_response :success
    end
    

    Kudos @Sowmiya for leading me to this conclusion. Your answer was not exactly the solution I needed, but it provoked me to think.