Rails: how to test and access custom routing - ruby-on-rails

so far in routes.rb
match 'campaigns_mobile_application', to: 'campaigns#update_mobile_store_application', via: [:post, :get]
in spec_helper.rb
config.include Rails.application.routes.url_helpers
in controller_spec.rb
get campaigns_mobile_application_path format: :json # and here I have error
ok, I have error:
ActionController::RoutingError No route matches {:controller=>"campaigns", :action=>"/api/campaigns_mobile_application.json"}
change routes.rb now:
resources :campaigns do
match 'mobile_application', to: 'campaigns#update_mobile_store_application', via: [:post, :get]
end
and also spec:
get campaign_mobile_application_path campaign_id: #campaign.id, format: :json
and again I catch error:
ActionController::RoutingError:
No route matches {:controller=>"campaigns", :action=>"/api/campaigns/6775/mobile_application.json"}
How to fix this?
UPD:
I try different magic with on: :member, on: :collection, as: :name and other stuff.
Seems that I completely doesn't understand routing.
routes.rb
resources :campaigns do
match :mobile_applications, to: 'campaigns#update_mobile_store_applications',
via: [:post, :get], on: :member, as: :mobile_applications
end
**rake routes **
mobile_applications_campaign POST|GET /api/campaigns/:id/mobile_applications(.:format) campaigns#update_mobile_store_applications
controller.rb
def update_mobile_store_applications
render: json: { }, status: :ok
end
spec.rb
get mobile_applications_campaign_path campaign_id: #campaign.id, format: :json
generate error:
Failure/Error: get mobile_applications_campaign_path campaign_id: #campaign.id, format: :json
ActionController::RoutingError:
No route matches {:action=>"update_mobile_store_applications", :controller=>"campaigns", :campaign_id=>8059, :format=>:json}
change request to this one (rename parameter):
get mobile_applications_campaign_path id: #campaign.id, format: :json
still generate error: ( different error )
Failure/Error: get mobile_applications_campaign_path id: #campaign.id, format: :json
ActionController::RoutingError:
No route matches {:controller=>"campaigns", :action=>"/api/campaigns/8108/mobile_applications.json"}
UPD2
This code works well on app but not in testing.
UPD3
This code works well on testing too now! Yeah!
get :update_mobile_store_applications, id: #campaign.id, format: :json

get :mobile_applications_campaign_path, id: #campaign.id, format: :json
The format was incorrect look here: https://github.com/everydayrails/rails-4-1-rspec-3-0/blob/master/spec/controllers/contacts_controller_spec.rb
This code is part of a Everyday Rails Testing book, a very good book for learn testing with rspec on Rails

Related

Rails Api test UrlGenerationError

I am building an API and, upon writing the tests, I run into a strange UrlGenerator Error.
I have an API on version one and this is my Users controller.
class Api::V1::UsersController < ApplicationController
respond_to :json
def show
respond_with User.find(params[:id])
end
end
Here is the spec for that users controller
require 'rails_helper'
RSpec.describe Api::V1::UsersController, type: :controller do
before(:each) { request.headers['Accept'] = "application/vnd.marketplace.v1" }
describe "GET #show" do
before(:each) do
#user = FactoryBot.create :user
get :show, format: :json
end
it "returns the information about a reporter on a hash" do
user_response = JSON.parse(response.body, symbolize_names: true)
expect(user_response[:email]).to eql #user.email
end
it { should respond_with 200 }
end
end
When I run this spec I get the following error message: `Failure/Error: get :show, format: :json
ActionController::UrlGenerationError:
No route matches {:action=>"show", :controller=>"api/v1/users", :format=>:json}`
I have only one route for my API:
api_user GET /users/:id(.:format) api/v1/users#show {:subdomain=>"api", :format=>:json}
Does anybody know why I would be getting this error? It seems to me that, based on the route returned from the api routes list, this should be working. My routes.rb file is listed below:
namespace :api, defaults: { format: :json }, constraints: { subdomain: 'api' }, path: '/' do
scope module: :v1, constraints: ApiConstraints.new(version: 1, default: true) do
resources :users, :only => [:show]
end
end
The problem is that the show route that you have defined requires an :id parameter, but the call for get :show from the test does not send it.
From Rspec, you can send the id with something like:
get :show, params: { id: #user.id }, format: :json

"No route matches" error in rspec, but route shows up in rake routes

Here is my route from routes.rb:
resources :books, :except => [:new, :edit] do
post "pull" => "books#update", :data => { "pull" => true }
rake routes shows things as expected
pull_api_v1_book POST /api/v1/books/:id/pull(.:format)
api/v1/books#update {:format=>:json, :data=>{"pull"=>true}}
Running a dev server, the route works as expected:
curl -X POST http://localhost:3000/api/v1/books/3/pull?auth_token=1234567890
My spec in in books_controller_spec.rb:
describe "pull api" do
it "should not fail" do
post :pull, params: { :id => 12 }
end
end
But the output of the spec:
Failure/Error: post :pull, params: { :id => 12 }
ActionController::UrlGenerationError:
No route matches {:action=>"pull", :controller=>"api/v1/books", :id=>12}
Why can't rspec find the route?
Controller tests in rails don't actually invoke the routing, it's only syntactic sugar for calling the controller action. Your spec should call:
post :update, params: { :id => 12 }
If you actually want to test the route you should use a request spec.

ActionController::UrlGenerationError: error No routes matches

I get the below error ActionController::UrlGenerationError.
ActionController::UrlGenerationError:
No route matches {:action=>"/accounts/100", :controller=>"accounts"}
Below is my code which throws this error.
it "can find an account" do
Account.should_receive(:find, with: {id: 2055, authorization: #auth}
get "/accounts/100", nil, {"AUTH_TOKEN" => #auth}
hashed_response = {
"#type" => "test",
"createdAt" => "2014-07-24T15:26:49",
"description" => "Something about test",
"disabled" => false
}
expect(response.status).to eq 200
expect(response.body).to eq(hashed_response.to_json);
end
I did a google on this and came to know that there is no routes defined for this. Below is my config/routes.rb file
Rails.application.routes.draw do
resources :accounts do
resources :holders
end
end
I presume this error is coming from a controller spec? If so, you simply use a symbol representing the action you want to call, not the URL itself.
eg. this is a show action, so you would use:
get :show, id: 100

Rails 4 Upgrade - ActionController::UrlGenerationError - No route matches

I am trying to port my application from Rails 3.2.x to Rails 4.0.4. All the gems have been made compatible and I am in the phase of fixing failing tests.
I have this weird test failure.
My routes.rb
resources :my_reports, only: [:index] do
collection do
get "/report/:filename", to: :show, prefix: "pri/excl/rep", as: :show
end
end
My spec which has been passing in Rails 3.2.x and now failing after update to 4.0.4
describe MyReportsController do
describe "#show" do
def make_request
get :show, prefix: 'some/place', filename: 'foo', format: 'doc'
end
it "makes a simple request" do
make_request
end
end
end
I am getting the following error
Failure/Error: get :show, prefix: 'some/place', filename: 'foo', format: 'doc'
ActionController::UrlGenerationError:
No route matches {:action=>"show", :controller=>"my_reports",
:filename=>"foo", :format=>"doc", :prefix=>"some/place"}
I am stuck at this point, hints are welcome. I am using rspec and rspec-rails versions 2.14.1.
Passing a dummy :id in the test fixed the issue for me although I would not like it, tests pass.
get :show, id: "", prefix: 'some/place', filename: 'foo', format: 'doc'
Refer to state of rails releases here.
You're describing the show method but your route is only available for the index one. Maybe it's a beginning of solution.

Routing Test Fails with Matched Route

I have this line of code in my routes
namespace :api, defaults: {format: 'json'} do
namespace :v1 do
match '/auth/:provider/callback', to: 'sign_in#authenticate'
end
end
And my test as
require 'spec_helper'
describe "Routing" do
it "should route to sign_in#authenticate" do
expect(post: 'api/v1/auth/:provider/callback').to route_to({ controller: 'api/v1/sign_in', action: 'authenticate', format: 'json' })
end
end
However, no matter what I do I keep getting the error
No route matches "/api/v1/auth/:provider/callback"
What am I missing here in order to make this test pass?
I believe the error you're getting is because match defaults to a GET request, but you are testing a POST request in your spec. You should be able to fix the issue by changing the route to:
match '/auth/:provider/callback', to: 'sign_in#authenticate', via: :post
My personal preference is to use the post method instead of match, it just reads better to me:
post '/auth/:provider/callback' => 'sign_in#authenticate'

Resources