0
votes

I have two specs, a request spec and a controller spec. I want clients to omit the root json node from their post data, and the request spec proves that this works. In fact, Rails seems to be creating this root node when it isn't present, which is why the controller implementation below works. The controller spec, however, fails when this root node isn't specified. The stack trace indicates a routing error when this node is missing. I'm looking for an explanation as to why this is happening so that I can either fix my controller spec, or live in peace understanding why they must be different.

Rails: 3.2.18

Rspec: 2.14.7

The trace:

1) Api::V2::ExamplesController has a status of 201
   Failure/Error: post :create, post_data, subdomain: 'api'
   ActionController::RoutingError:
     No route matches {:param1=>"foo", :param2=>"bar", :controller=>"api/v2/exampless", :action=>"create"}
   # ./spec/controllers/api/v2/examples_controller_spec.rb:2:in `block (2 levels) in <top (required)>'

The (passing) request spec:

describe 'Webhook' do
  it 'has a status of 201' do
    host! 'api.example.com'
    post_data = { param1: 'foo', param2: 'bar' }
    post '/v2/examples', post_data, json_request_headers
    expect(response.status).to eq(201)
  end
end

def json_request_headers
  {
    'Accept' => 'application/json',
    'Content-Type' => 'application/json'
  }
end

The (failing) controller spec:

describe Api::V2::ExamplesController do
  it 'has a status of 201' do
    request.env['HTTP_ACCEPT'] = 'application/json'
    request.env['HTTP_CONTENT_TYPE'] = 'application/json'
    post_data = { param1: 'foo', param2: 'bar' }
    post :create, post_data, subdomain: 'api'
    expect(response.status).to eq(201)
  end
end

This test succeeds when line 6 reads post :create, example: post_data, subdomain: 'api'

The controller:

module Api::V2
  class ExamplesController
    skip_before_filter :verify_authenticity_token

    def create
      Example.create!(params[:example])
      head :created
    end
  end
end

The routes:

namespace :api, defaults: { format: 'json' }, subdomain: 'api', path: '/' do
  namespace :v2 do
    resources :examples, only: :create
  end
end
1

1 Answers

0
votes

You need to add format: 'json' to the post :create params in your controller spec:

post_data = { format: 'json', param1: 'foo', param2: 'bar' }
post :create, post_data, subdomain: 'api'