3

I have a rails project that is running out of a subdirectory of the base url in production and I want it to act that way in dev so as to make dev and prod as close as possible. I have the routes file set up like so:

Foo::Application.routes.draw do
    def draw_routes
        root :to=>'foo#home'
        resources :cats, :only=>[:create] do
    end
    if Rails.env.production?
        scope :protocol=>'http://' do
            draw_routes
        end
    else
        scope :path=>"/foo", :protocol=>'http://' do
            draw_routes
        end
    end
end

My CatsController is like this:

class CatsController < ApplicationController
    def create
        @cat = Cat.new(:name=>"Bob")
        if @cat.save()
            redirect_to root
        end
    end
end

I want to test my Create Cat Method, so I set up an rspec test in spec/controllers/cats_controller_spec.rb:

require 'spec_helper'
describe CatsController do
    describe "calling create cat with good data" do
        it "should add a cat" do
            expect {post(:action=>:create)}.to change(Cat, :count).by(1)
        end
    end 
end

When I run my test, though, I get

Failure/Error: post :create
     ActionController::RoutingError:
       No route matches {:controller=>"cats", :action=>"create"}
     # ./spec/controllers/cats_controller_spec.rb:5:in `(root)'

Rake routes says my route is there! What is going on under the hood here, and why is this failing?

Rake Routes:
    cats POST   /foo/cats(.:format)            cats#create {:protocol=>"http://"}
Rokujolady
  • 939
  • 2
  • 8
  • 15
  • try `post '/foo/cats'` instead – ted Apr 09 '13 at 20:26
  • No dice: post 'foo/cats' yields ActionController::RoutingError: No route matches {:controller=>"cats", :action=>"foo/cats"} Thanks, though! – Rokujolady Apr 09 '13 at 20:32
  • If you go for `http://localhost:3000/foo/cats`, get up to the expected place? – ted Apr 09 '13 at 20:34
  • If I go there in the browser, yes. Also, if I have a form that posts the request, and I call it like <%=form_tag("/foo/cats",:method=>post)%>, it also goes to the right place. – Rokujolady Apr 09 '13 at 20:45
  • Hmmm. If I remove the :protocol it starts working so it has to do with that. – Rokujolady Apr 09 '13 at 21:18

2 Answers2

3

The problem is that the value of :protocol is a bit wonky.

The better way to fix this, I think, is to set the protocol in your scopes to http instead of http://. If you did need to test your controller with some funky protocol, though, you should be able to do:

post(:action => :create, :protocol => 'funky')

or whatever your protocol might be.

Owen S.
  • 7,665
  • 1
  • 28
  • 44
  • 1
    I have to add the caveat that yes, the correct protocol is 'http' without the slashes. However, I still had to explicitly specify it in the post function. Works now, though! – Rokujolady Apr 09 '13 at 21:53
0

For rspec 3, this below works for me.

post :action, protocol: 'https://'
Thaichor Seng
  • 105
  • 10