I have the following routes defined and the following UsersController defined and when I attempt to run spec test that attempts before { visit signup_path }, I get the following error:
ERROR
Failure/Error: before { visit signup_path}
ActionController::RoutingError:
uninitialized constant UserController
# ./spec/requests/user_pages_spec.rb:7:in `block (3 levels) in <top (required)>'
resources :users
routes.rb
resources :users
match '/signup', to: 'users#new'
match '/help', to: 'static_pages#help'
root :to => 'static_pages#help'
users_controller.rb
class UsersController < ApplicationController
def new
end
def show
#user = User.find(params[:id])
end
end
updated
**user_pages_spec.rb**
describe "UserPages" do
subject { page }
describe "Signup Page" do
before { visit signup_path}
it "Should have header Sign-up" do
should have_selector("h1", text: "Sign-up")
should have_selector("title", text: "Sign-up")
end
end
describe "profile page" do
let(:user) {FactoryGirl.create(:user)}
before { visit user_path(user) }
it { should have_selector("title", text: "#{user.name} Profile")}
it { should have_selector("h1", text: user.name)}
end
end
Here is my routes:
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
signup /signup(.:format) users#new
help /help(.:format) static_pages#help
root / static_pages#help
I can go to www.blah.com/signup without an issue. But the spec is looking for a singular UserController. I can also substitute "signup_path" for "/users/new" and the test will pass.
Also, wanted to add that originally I created the controller (only) using the rails generator using the singular version. But I backed it out after I discovered that by using the rails destroy controller script. Then issued the correct rails generator for the plural version. Like I said, its like the tests are screwed up, but the actual app.
Related
Trying to test my controller
static_pages_controller_spec.rb
require 'rails_helper'
RSpec.describe StatigPagesController, type: :controller do
it 'return home view' do
get '/'
expect(response).to render_template :home
end
it 'return about view' do
get :about
expect(response).to render_template :about
end
end
routes.rb
Rails.application.routes.draw do
devise_for :users
root 'static_pages#home'
get '/about', to: 'static_pages#about'
end
and i get errors
1) StatigPagesController return home view
Failure/Error: get '/'
ActionController::UrlGenerationError:
No route matches {:action=>"/", :controller=>"statig_pages"}
2) StatigPagesController return about view
Failure/Error: get :about
ActionController::UrlGenerationError:
No route matches {:action=>"about", :controller=>"statig_pages"}
I wrote routes, What i'm do wrong?
You have a typo in your static_pages_controller_spec.rb
RSpec.describe StatigPagesController
Try:
RSpec.describe StaticPagesController
The route in my system is:
user_show GET /user/show(.:format) user#show.
The controller code is:
def show
#user = User.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #user}
end
end
_spec.rb
describe 'GET #show' do
it 'should return success' do
get :show, id:#user.id
expect(response).to be_success
end
end
result is:
Failure/Error: expect(response).to be_success
expected success? to return true, got false
In the browser, when I type xxx/user/show, it get error.
ActiveRecord::RecordNotFound in UserController#show
But if I type xxx/user/show?id=31, it shows user with id=31!!
Thanks for #Alex Wayne, I add more information here: I check the routes.rb file:
get "user/show"
get "user/index"
get "user/delete"
get "user/edit"
post "user/update"
resource :users, :path => :user, :as => :user
I personal think my teammate should not write down "get user/show, get user/index...." based on Rails Routing. But I can't change their code. So,
anyone know how to test user/show?id=xxx ? Many thanks~!!!!
so I've been using Michael Hartl's tutorial for some time and I can say it's really useful but there's a problem and I gues it's not on the tutorial's part. So in chapter "9.2.2 Requiring the right user" ther's a test for checking that a user can access neither other user's edit page nor submit a direct PUT reauest.
describe "as wrong user" do
let(:user) { FactoryGirl.create(:user) }
let(:wrong_user) { FactoryGirl.create(:user, email: "wrong#example.com") }
before { sign_in user }
describe "visiting Users#edit page" do
before { visit edit_user_path(wrong_user) }
it { should_not have_selector('title', text: full_title('Edit user')) }
end
describe "submitting a PUT request to the Users#update action" do
before { put user_path(wrong_user) }
specify { response.should redirect_to(root_path) }
end
end
So long all seems right but the test fails:
1) Authentication authorization as wrong user submitting a PUT request to the Users#update action ←[31mFailure/Error:←[0m ←[31mspecify { response.should redirect_to(root_path }←[0m←[31mExpected response to be a redirect to <http://www.example.com/> but was a redirect to <http://www.example.com/signin>←[0m←[36m # ./spec/requests/authentication_pages_spec.rb:107:in `block (5 levels) in <top (required)>'←[0m
Here's the User controller:
class UsersController < ApplicationController
before_filter :signed_in_user, only: [:index, :edit, :update]
before_filter :correct_user, only: [:edit, :update]
def index
#users = User.all
end
def show
#user = User.find(params[:id])
end
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
sign_in #user
flash[:success] = "Welcome to the Sample App!"
redirect_to #user
else
render 'new'
end
end
def edit
end
def update
if #user.update_attributes(params[:user])
flash[:success] = "Profile updated"
sign_in #user
redirect_to #user
else
render 'edit'
end
end
private
def signed_in_user
unless signed_in?
puts "No user signed in"
store_location
redirect_to signin_path, notice: "Please sign in."
end
end
def correct_user
#user = User.find(params[:id])
puts "Incorrect user" unless current_user?(#user)
redirect_to(root_path) unless current_user?(#user)
end
end
So as you can see the problem is that when using RSpec put method, the test fails even before checking for the right user because it sees ther's no user signed in.
This is a small problem which can easily be omitted (incorrect user cannot make direct PUT request anyway) but it's a puzzle for me why doesn't it work correct and I can't get the answer for quite a time already.
It looks like the signed_in_user filter is redirecting back to the sign in page before the correct_user fires. That suggests that the user is not actually signed in correctly by the sign_in user call in the before block.
Have you defined sign_in in spec/support/utilities.rb?
include ApplicationHelper
def sign_in(user)
visit signin_path
fill_in "Email", with: user.email
fill_in "Password", with: user.password
click_button "Sign in"
# Sign in when not using Capybara as well.
cookies[:remember_token] = user.remember_token
end
I am using Devise 1.4.2, RSpec 2.6.0 and Rails 3.1.0.rc6. My routes.rb looks like this:
scope "(:locale)", :locale => /e(s|n)/ do
resources :demotivideos, :only => [:index, :show]
devise_for :users
namespace "admin" do
resources :demotivideos, :except => [:index, :show]
end
end
I am spec'ing that, when a not logged in user acces new, create or update, he should be redirected to new_user_session_path. For this, I am using the following code
context "when not logged in" do
before(:each) do
sign_out user
end
describe "GET new" do
it "should redirect to new user session" do
get :new
response.should redirect_to(new_user_session_path)
end
end
describe "POST create" do
it "should redirect to new user session" do
post :create, :demotivideo => valid_attributes
response.should redirect_to(new_user_session_path)
end
end
describe "PUT update" do
it "should redirect to new user session" do
put :update, :id => 1, :demotivideo => valid_attributes
response.should redirect_to(new_user_session_path)
end
end
end
All are failing because of the same reason: expected route includes the locale (by default en) but the actual redirect was to the same path without locale. My application controller was modified as told in Rails Guides:
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :set_locale
def default_url_options(options={})
logger.debug "default_url_options is passed options: #{options.inspect}\n"
{ :locale => I18n.locale }
end
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
end
end
What am I doing wrong?
Seems like though Rails Guides uses def default_url_options in Devise you need def self.default_url_options. Don't know the difference, though.
I have a fairly simple Rails 3 project where I've defined a custom route:
get 'factions/:name' => 'factions#show', :as => :factions
get 'factions' => 'factions#index'
... which when running rails s gives me the expected page (http://localhost:3000/factions/xyz is HTTP 200 with the app/views/factions/show.html.haml being displayed). However I've tried multiple different ways of expressing a spec that will work, below is my latest incarnation:
require 'spec_helper'
describe FactionsController do
render_views
describe "GET 'show'" do
before { get '/xyz' }
subject { controller }
it { should respond_with(:success) }
it { should render_template(:show) }
end
describe "GET 'index'" do
it "should be successful" do
get 'index'
response.should be_success
end
end
end
The GET 'index' spec passes without complaint but no matter what I do the GET 'show' specs cannot pass - even if they do succeed when I am browsing to them locally.
1) FactionsController GET 'show'
Failure/Error: before { get '/xyz' }
ActionController::RoutingError:
No route matches {:controller=>"factions", :action=>"/xyz"}
# ./spec/controllers/factions_controller_spec.rb:7:in `block (3 levels) in <top (required)>'
The action really should be show but my routes.rb configuration must be incorrect or something. What gives?
(Additional context: I am using bundle exec spork for speeding up my specs and I have restarted the spork server multiple times just to make sure I'm not completely insane.)
Change:
before { get '/xyz' }
To:
before { get :show, :name => 'xyz' }