testing all matched routes (*path) in rails in Rspec - ruby-on-rails

I have a rails application and I am trying to test the routes file.
How can one test this route in the routes.rb in rspec(minitest would be great as well):
'*unmatched_route', :to => 'application#raise_not_found!', :via => :all

According to Routing specs in RSpec you should be able to write something like this:
# in spec/routing/not_found.rb
describe 'not found' do
it 'routes to application#raise_not_found' do
expect(:get => "/an-unknown-route").to route_to(
:controller => "application",
:action => "raise_not_found!"
)
end
end

Related

Rspec: how to test Rails' url_for helper?

Using RSpec, how do I test url_for helper method to make sure to it goes to the correct controller and action with a particular format?
I had to do the following --
Add this to spec_helper.rb:
Rspec.configure do |config|
config.include Rails.application.routes.url_helpers # url_for
end
Then:
describe "Article routing" do
it "routes to #index.atom" do
get('/articles.atom').
should route_to('articles#index', format: 'atom')
url_for(:controller => 'articles', :format => :atom, :only_path => true).
should == '/articles/index.atom'
end
end
You can test that named routes are routed to the correct place. Routing specs live in spec/routing,so the following specs would be added to spec/routing/widget_routes_spec.rb
describe "routes to the widgets controller" do
it "routes a named route" do
expect(:get => new_widget_path).
to route_to(:controller => "widgets", :action => "new")
end
end
There are a lot of other options for testing routes described in the routing specs documentation.

Rspec Controller Test No Route Matches Error

Rspec is not recognising my controller routes. I am using Versionist gem to version my API and I am using a path version (so /v1/ to version my API as shown below.).
constraints :subdomain => "api" do
api_version(:module => "V1", :path => {:value => "v1"}, :defaults => {:format => :json}, :default => true) do
match '/orders' => 'orders#index', :via => :get
The route in rake routes is shown as:
GET /v1/orders(.:format) V1/orders#index {:subdomain=>"api", :format=>:json}
My controller is located in app/controller/v1/orders_controller.rb.
For the rspec test, I have a orders_controller_spec.rb, I have:
require 'spec_helper'
module V1
describe OrdersController do
describe "GET #index" do
it "throws an error on incorrect params" do
get :index
end
end
end
end
The error I get is:
1) V1::OrdersApiController GET #index throws an error on incorrect param
Failure/Error: get :index
ActionController::RoutingError:
No route matches {:controller=>"v1/orders"}
What is wrong here? How come no route matches v1/orders? In rake routes, I see the route right there as shown above: GET /v1/orders(.:format) V1/orders#index {:subdomain=>"api", :format=>:json}. It says GET /v1/orders. Where is the problem here?

Route errors in controller tests after upgrading rails and journey router

This is my route
match "/:type/:brand/:model/:plate" => "site/vehicles#show",
:constraints => {:plate => /[a-z]{3}\d{4}/}, :as => :vehicle
It passes the route tests
# the route test passess
it "routes to #show" do
{:get => '/carro/volksvagen/gol-2-0/abc1234'}.should route_to(
"site/vehicles#show",
:type => "carro",
:brand => "volksvagen",
:model => "gol-2-0",
:plate => "abc1234"
)
end
But after upgrading rails (3.2.0 => 3.2.8 ) which also updated journey (1.0.0 => 1.0.4), the following CONTROLLER test (which IMHO should not check for routes, which it apparently did not, back in rails 3.2.0) started failing.
describe "#show" do
it "should be success" do
get :show, :plate => #vehicle.plate
response.should be_success
end
end
It raises
Site::VehiclesController#show should be success
ActionController::RoutingError:
No route matches {:plate=>"ABC1672", :controller=>"site/vehicles",
:action=>"show"}
And even if I complete all the route vars
describe "#show" do
it "should be success" do
get :show, :plate => #vehicle.plate, :model => 'model',
:type => 'type', :brand => 'brand'
response.should be_success
end
end
I get:
# No route matches {:plate=>"ABC1586", :model=>"model", :type=>"type",
:brand=>"brand", :controller=>"site/vehicles", :action=>"show"}
The application still works, but I will not know when it stops, since my tests are failing.
Anyone solved/had similar issue?
I know 'not upgrading rails' could avoid getting this errors, as suggested in a similar question, but I don't think it is a solution.
Routing error when updating to Rails 3.2.6 or Rspec 2.11.0
Thank you in advance.
Edit:
vehicle /:type/:brand/:model/:plate(.:format) site/vehicles#show {:plate=>/[a-z]{3}\d{4}/}
I think your problem is in a mismatch between your regex and your test data. In your error message, I see:
No route matches {:plate=>"ABC1586", :model=>"model", :type=>"type",
:brand=>"brand", :controller=>"site/vehicles", :action=>"show"}
But the route has the following regex for plate:
:plate => /[a-z]{3}\d{4}/
That requires all lower-case letters; upper case letters won't match. So you need to either fix your test data, or fix the regex in your route.

Route works in browser, fails in Rspec

This question has probably been asked a dozen times on Stack Overflow (e.g. (1), (2), (3), (4), (5)) but every time the answer seems to be different and none of them have helped me. I'm working on a Rails Engine and I'm finding that Rspec2 gets route errors, but I can reach the routes in the browser. Here's the situation:
In the engine's routes.rb:
resources :mw_interactives, :controller => 'mw_interactives', :constraints => { :id => /\d+/ }, :except => :show
# This is so we can build the InteractiveItem at the same time as the Interactive
resources :pages, :controller => 'interactive_pages', :constraints => { :id => /\d+/ }, :only => [:show] do
resources :mw_interactives, :controller => 'mw_interactives', :constraints => { :id => /\d+/ }, :except => :show
end
Excerpted output of rake routes:
new_mw_interactive GET /mw_interactives/new(.:format) lightweight/mw_interactives#new {:id=>/\d+/}
...
new_page_mw_interactive GET /pages/:page_id/mw_interactives/new(.:format) lightweight/mw_interactives#new {:id=>/\d+/, :page_id=>/\d+/}
And my test, from one of the controller specs (describe Lightweight::MwInteractivesController do):
it 'shows a form for a new interactive' do
get :new
end
...which gets this result:
Failure/Error: get :new
ActionController::RoutingError:
No route matches {:controller=>"lightweight/mw_interactives", :action=>"new"}
...and yet when I go to that route in the browser, it works exactly as intended.
What am I missing here?
ETA: To clarify a point Andreas raises: this is a Rails Engine, so rspec runs in a dummy application which includes the engine's routes in a namespace:
mount Lightweight::Engine => "/lightweight"
...so the routes shown in rake routes are prefaced with /lightweight/. That's why the route shown in the Rspec error doesn't seem to match what's in rake routes. But it does make the debugging an extra step wonkier.
ETA2: Answering Ryan Clark's comment, this is the action I'm testing:
module Lightweight
class MwInteractivesController < ApplicationController
def new
create
end
...and that's it.
I found a workaround for this. Right at the top of the spec, I added this code:
render_views
before do
# work around bug in routing testing
#routes = Lightweight::Engine.routes
end
...and now the spec runs without the routing error. But I don't know why this works, so if someone can post an answer which explains it, I'll accept that.
I think the might be something wrong higher up in you specs
how did the "lightweight" get into this line :controller=>"lightweight/mw_interactives"
the route says
new_mw_interactive GET /mw_interactives/new(.:format)
not
new_mw_interactive GET /lightweight/mw_interactives/new(.:format)
add a file spec/routing/root_routing_spec.rb
require "spec_helper"
describe "routes for Widgets" do
it "routes /widgets to the widgets controller" do
{ :get => "/" }.should route_to(:controller => "home", :action => "index")
end
end
then add a file spec/controllers/home_controller_spec.rb
require 'spec_helper'
describe HomeController do
context "GET index" do
before(:each) do
get :index
end
it {should respond_with :success }
it {should render_template(:index) }
end
end

Rspec and non-RestFul routes

I am doing homework but I have problem with non-RestFul routes.
My spec is:
require 'spec_helper'
describe MoviesController do
describe 'searching TMDb' do
before :each do
#fake_results = [mock('Movie'), mock('Movie')]
end
it 'should call the model method that performs TMDb search' do
Movie.should_receive(:find_in_tmdb).with('Star Wars').
and_return(#fake_results)
get :search_similar_movies, { :search_terms => 'Star Wars' }
end
end
end
In config/routes.rb I have:
resources :movies
'movies/search_similar_movies/:search_terms'
But when I run autotest it gives me error that begins with:
/usr/local/lib/ruby/gems/1.9.1/gems/actionpack-3.1.0/lib/action_dispatch/routing/mapper.rb:181:in `default_controller_and_action': missing :action (ArgumentError)
It's obvious that something is wrong is config/routes.rb. How to solve this?
Your route should be something like
resources :movies do
get 'search_similar_movies', :on => :collection
end
or
match 'movies/search_similar_movies/:search_terms' => 'movies#search_similar_movies', :via => :get

Resources