Why is it that this request spec works as it should:
require "spec_helper"
describe "POST on a GET route" do
it "should not allow this" do
post "/applicants/new"
assert_response :missing
end
end
But in this controller spec, GET, POST, PUT, and DELETE all work the same when they should not:
require 'spec_helper'
describe ApplicantsController do
it "should not allow this" do
post :new
should respond_with :missing # but it responds with 200
end
end
UPDATE: Added ApplicantsController code and route definition:
class ApplicantsController < InheritedResources::Base
respond_to :html
actions :index, :new, :create
def new
if current_user
redirect_to resume_application_path and return
end
@applicant = Applicant.new
@applicant.applications.build
@applicant.build_user_detail
new!
end
end
Routes:
resources :applicants
UPDATE: After much researching and digging into the API, I believe this is by design as the Controller specs inherit from ActionController::TestCase while the Request specs inherit from ActionDispatch::IntegrationTest. In the case of Controller specs, the HTTP verbs become merely descriptive.
Could someone confirm that this is by design? Or should I file a bug report?
Thank you!
This seems surprising, but it makes sense when you look at it from the perspective of testing the controller actions in isolation. Normally, controller actions don't need to know about HTTP request methods. Specifying a route without a method illustrates this:
match 'sample' => 'applicants#index'
Now GET /sample
and POST /sample
will both route to the index action. Unless you code for it, the controller will not know the difference between a GET and a POST request. Controller specs do not test whether request method/action combinations are routable, since that is the responsibility of the routing engine.
You can verify which routes work and which don't with routing specs:
it "recognizes and generates #new" do
{ :get => "/applicants/new" }.should route_to(:controller => "applicants",
:action => "new")
end
it "does not recognize POST /applicants/new" do
{ :post => "/applicants/new" }.should_not be_routable
end