Rails Tutorial 3 chapter 7.1.3 rspec failing tests - ruby-on-rails

I have spend a few hours going over the book and the code from the github page, and I cannot seem to find my answer. I am in chapter 7.1.3 and trying to get the following tests to pass. When I view the pages everything is working properly as far as I can tell.
user_pages_spec.rb
require 'spec_helper'
describe "User pages" do
subject { page }
describe "signup page" do
before { visit signup_path }
it { should have_selector('h1', text: 'Sign Up') } (10)
it { should have_selector('title', text: full_title('Sign Up')) } (11)
end
describe "profile page" do
let(:user) { FactoryGirl.create(:user) }
before { visit user_path(user) }
it { should have_selector('h1', text: 'user.name') } (18)
it { should have_selector('title', text: 'user.name') } (19)
end
end
I have been through all of the files that I can think of checking what could go wrong.
app/views/users/new.html.erb
<% provide(:title, 'Sign Up') %>
<h1>Sign Up</h1>
<p>Find me in app/views/users/new.html.erb</p>
**app/views/users/show.html.erb
<% provide(:title, #user.name) %>
<h1><%= #user.name %></h1>
app/controller/users_controller.rb
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
end
def new
end
end
config/routes.rb
SampleApp::Application.routes.draw do
resources :users
match '/contact', :to => 'pages#contact'
match '/about', :to => 'pages#about'
match '/help', :to => 'pages#help'
match '/signup', :to => 'users#new'
root :to => 'pages#home'
I think I have attached all of the relevant code, please let me know if adding anything else will help. The following are the actual errors that I am getting. If you can please point out where I have thrown a wrench in the works I would be very appreciative.
rspec ./spec/requests/user_pages_spec.rb:10 # User pages signup page
rspec ./spec/requests/user_pages_spec.rb:11 # User pages signup page
rspec ./spec/requests/user_pages_spec.rb:18 # User pages profile page
rspec ./spec/requests/user_pages_spec.rb:19 # User pages profile page
Thanks for your help and time!

Remove the quotation marks in line 18 and 19. That should pass your tests.
Like this:
describe "profile page" do
let(:user) { FactoryGirl.create(:user) }
before { visit user_path(user) }
it { should have_selector('h1', text: user.name) }
it { should have_selector('title', text: user.name) }
end
Also look for your routes.rb. In the rails tutorial it is well
match '/help', to: 'static_pages#help'
match '/about', to: 'static_pages#about'
match '/contact', to: 'static_pages#contact'
unless you have create the static pages views with the name pages. Then forget my routes.rb

Related

ActionController::UrlGenerationError: No route matches {:action=>"/users/762146111"

I've been following the Michael Hartl tutorial for learning rails and have been doing pretty well thus far, but I'm stumped on this issue which I've encountered repeatedly. I'm not skilled enough to know if there is a configuration problem in my environment or something else, but this makes NO sense to me.
In ANY of the controller tests I attempt to run, I can never get my helper URL methods to work. As an example:
test "should redirect home when not an admin" do
log_in_as(#other_user)
assert_no_difference 'User.count' do
delete user_path(#user)
end
assert redirect_to root_url
end
Generates the following error:
ERROR["test_should_redirect_home_when_not_an_admin", UsersControllerTest, 0.9899668790167198]
test_should_redirect_home_when_not_an_admin#UsersControllerTest (0.99s)
ActionController::UrlGenerationError: ActionController::UrlGenerationError: No route matches {:action=>"/users/762146111", :controller=>"users"}
test/controllers/users_controller_test.rb:60:in `block (2 levels) in <class:UsersControllerTest>'
test/controllers/users_controller_test.rb:59:in `block in <class:UsersControllerTest>'
Even simple tests like
test "should redirect index when not logged in" do
get users_path
assert_redirected_to login_url
end
Produce the same error:
ERROR["test_should_redirect_index_when_not_logged_in", UsersControllerTest, 1.5291320629185066]
test_should_redirect_index_when_not_logged_in#UsersControllerTest (1.53s)
ActionController::UrlGenerationError: ActionController::UrlGenerationError: No route matches {:action=>"/users", :controller=>"users"}
test/controllers/users_controller_test.rb:34:in `block in <class:UsersControllerTest>'
Everything I've googled about this issue hasn't helped, because for some reason I cannot determine the user_path method (or any other similar method) somehow thinks the action I'm trying to take in my controller is the path!
I've verified that my routes file is configured correctly.
Rails.application.routes.draw do
root 'static_pages#home'
get '/help' => 'static_pages#help'
get '/about' => 'static_pages#about'
get '/contact' => 'static_pages#contact'
get '/signup' => 'users#new'
post '/signup' => 'users#create'
get '/login' => 'sessions#new'
post '/login' => 'sessions#create'
delete '/logout' => 'sessions#destroy'
get 'sessions/new'
resources :users
end
I've checked that running "rails routes" has the correct routes. I've even checked in rails console that "app.user_path(1)" spits out a valid path.
At this point I'm just beyond stumped as to why these helper methods don't seem to be helping... I also don't know what they're actually called so my googling has been fairly fruitless.
To get around this issue in the tutorial, I've been using syntax like
patch :edit, { id: #user }, params: { user: { name: #user.name,
email: #user.email }}
Or
test "should redirect index when not logged in" do
get :index
assert_redirected_to login_url
end
Which seems to work.
Also here is one of my test files if that's helpful:
require 'test_helper'
class UsersControllerTest < ActionController::TestCase
def setup
#user = users(:michael)
#other_user = users(:archer)
end
test "should get new" do
get :new
assert_response :success
end
test "should redirect edit when user not logged in" do
get :edit, params: { id: #user }
assert_not flash.empty?
assert_redirected_to login_url
end
test "should redirect update when user not logged in" do
patch :edit, { id: #user }, params: { user: { name: #user.name,
email: #user.email }}
assert_not flash.empty?
assert_redirected_to login_url
end
test "should redirect index when not logged in" do
# get users_path
get :index
assert_redirected_to login_url
end
test "should redirect destroy when not logged in" do
assert_no_difference 'User.count' do
delete user_path(#user)
end
assert redirect_to login_url
end
test "should redirect home when not an admin" do
log_in_as(#other_user)
assert_no_difference 'User.count' do
delete user_path(#user)
end
assert redirect_to root_url
end
end
Please let me know what other files I can post to be helpful.
I had the same issue and I fixed it by changing the file 'users_controller_test.rb' file replacing:
class UsersControllerTest < ActionController::TestCase
for
class UsersControllerTest < ActionDispatch::IntegrationTest
But first, in your case, check that you have in your Gemfile the line:
gem 'rails', '5.0.1'
as the tutorial shows.
I can also see that you have the following test:
test 'should get new' do
get :new
assert_response :success
end
When you make the correction you'll have to change the above test to:
test 'should get new' do
get new_user_path
assert_response :success
end
After that, run your tests and you should have them all passed.
Hope it helps

RSpec returning 'undefined local variable or method `signin_path''

When I run RSpec I am getting 4 errors all stating:
undefined local variable or method `signin_path' for #<RSpec::Core::ExampleGroup::Nested_1::Nested_1:0x4203fa8>
But I am running other tests that use this helper and path with no problem, it is only in the relationship controller tests that do not work with it.
relationship_controller_spec.rb
require 'spec_helper'
describe RelationshipsController do
let(:user) { FactoryGirl.create(:user) }
let(:other_user) { FactoryGirl.create(:user) }
before { sign_in user }
describe "creating a relationship with Ajax" do
it "should increment the Relationship count" do
expect do
xhr :post, :create, relationship: { followed_id: other_user.id }
end.to change(Relationship, :count).by(1)
end
it "should respond with success" do
xhr :post, :create, relationship: { followed_id: other_user.id }
response.should be_success
end
end
describe "destroying a relationship with Ajax" do
before { user.follow!(other_user) }
let(:relationship) { user.relationships.find_by_followed_id(other_user) }
it "should decrement the Relationship count" do
expect do
xhr :delete, :destroy, id: relationship.id
end.to change(Relationship, :count).by(-1)
end
it "should respond with success" do
xhr :delete, :destroy, id: relationship.id
response.should be_success
end
end
end
Utilities.rb:
def sign_in(user)
visit signin_path
fill_in 'Email', with: user.email.upcase
fill_in 'Password', with: user.password
click_button 'Sign In'
cookies[:remember_token] = user.remember_token
end
routes.rb:
resources :users do
member do
get :following, :followers
end
end
resources :sessions, only: [:create, :destroy, :new]
resources :microposts, only: [:create, :destroy]
resources :relationships, only: [:create, :destroy]
# Application Root
root to: 'static_pages#home'
# Static Pages
match '/help', to: 'static_pages#help'
match '/about', to: 'static_pages#about'
match '/contact', to: 'static_pages#contact'
# Users
match '/signup', to: 'users#new'
match '/signin', to: 'sessions#new'
match '/signout', to: 'sessions#destroy', via: :delete
Controller specs cannot interact with pages in the same way that feature specs do, so your sign_in utility will not work for them.
If your controller specs rely on a signed-in user, you will need to stub your current_user method. If you use Devise, here's a helpful page from their wiki: https://github.com/plataformatec/devise/wiki/How-To:-Stub-authentication-in-controller-specs

Hartl Chapter 5 issue

Going through Hartl's Rails tutorial and on Chapter 5.4.2 I am not able to get a certain test to pass.
Here is the error:
1) UserPages GET /user_pages works! (now write some real specs)
Failure/Error: get user_pages_index_path
NameError:
undefined local variable or method `user_pages_index_path' for #<RSpec::Core::ExampleGroup::Nested_1::Nested_1:0x007f9106e2cce8>
# ./spec/requests/user_pages_spec.rb:7:in `block (3 levels) in <top (required)>'
Here is the test in user_pages_spec.rb:
require 'spec_helper'
describe "UserPages" do
describe "GET /user_pages" do
it "works! (now write some real specs)" do
# Run the generator again with the
# --webrat flag if you want to use webrat methods/matchers
get user_pages_index_path
response.status.should be(200)
end
end
end
Here is the routes file:
get "users/new"
root 'static_pages#home'
match '/signup', to: 'users#new', via: 'get'
match '/help', to: 'static_pages#help', via: 'get'
match '/about', to: 'static_pages#about', via: 'get'
match '/contact', to: 'static_pages#contact', via: 'get'
match 'static_pages/home', to: 'static_pages#home', via: 'get'
Any input is appreciated
Sorry about the formatting. In the very beginning of that section is a spec file: spec/requests/user_pages_spec.rb
require 'spec_helper'
describe "User pages" do
subject { page }
describe "signup page" do
before { visit signup_path }
it { should have_content('Sign up') }
it { should have_title(full_title('Sign up')) }
end
end
and I am getting the following error:
Failure/Error: get user_pages_index_path
NameError: undefined local variable or method `user_pages_index_path' for #
Here is the rake routes output:
Prefix Verb URI Pattern Controller#Action
users_new GET /users/new(.:format) users#new
root GET / static_pages#home
signup GET /signup(.:format) users#new
help GET /help(.:format) static_pages#help
about GET /about(.:format) static_pages#about
contact GET /contact(.:format) static_pages#contact
static_pages_home GET /static_pages/home(.:format) static_pages#home
Just remove the contents at "user_pages_spec.rb"
cause there is no such method called user_pages_index_path
so, here is what it should be
user_pages_spec.rb
require 'spec_helper'
describe "User pages" do
subject { page }
describe "signup page" do
before { visit signup_path }
it { should have_content('Sign up') }
it { should have_title(full_title('Sign up')) }
end
end
Also, At /config/routes.rb file
SampleApp::Application.routes.draw do
get "users/new"
root 'static_pages#home'
match '/signup', to: 'users#new', via: 'get'
match '/help', to: 'static_pages#help', via: 'get'
match '/about', to: 'static_pages#about', via: 'get'
match '/contact', to: 'static_pages#contact', via: 'get'
.
.
.
end
I was having same issue and I just commented out the "user_pages_spec.rb" file. When I did that I passed all the tests. Is this the correct answer, I don't know but as I stated it allows for the tests to pass.

Hartl's Tutorial Section 5.3.2: Rails Routes

I've been following along in the tutorial exactly as it has been written. So far everything has gone without a hitch, until this section.
I was supposed to change the "GET" statements in the config/routes.rb file to the following:
SampleApp::Application.routes.draw do
root to: 'static_pages#home'
match '/help', to: 'static_pages#help'
match '/about', to: 'static_pages#about'
match '/contact', to: 'static_pages#contact'
This was supposed to make the tests pass. They do not pass. They continue to fail with the following error as one of the 9 similar errors:
Failure/Error: visit about_path
NameError:
undefined local variable or method 'about_path' ....
I have no idea how to get this to pass so that I can move on. What did I miss? What did Hartl miss? Other people who have asked this question never got an answer that made any sense or even worked when tried.
Before anyone asks:
All versions of Rails, Ruby and other installed components are the exact same versions used in the tutorial as it is written today 2012-10-05. Everything matches the tutorial perfectly.
UPDATE: Here is the current static_pages_spec.rb file
require 'spec_helper'
describe "Static pages" do
describe "Home page" do
it "should have the h1 'Sample App'" do
visit root_path
page.should have_selector('h1', text: 'Sample App')
end
it "should have the base title" do
visit root_path
page.should have_selector('title',
text: "Ruby on Rails Tutorial Sample App")
end
it "should not have a custom page title" do
visit root_path
page.should_not have_selector('title', text: '| Home')
end
end
describe "Help page" do
it "should have the h1 'Help'" do
visit help_path
page.should have_selector('h1', text: 'Help')
end
it "should have the title 'Help'" do
visit help_path
page.should have_selector('title',
text: "Ruby on Rails Tutorial Sample App | Help")
end
end
describe "About page" do
it "should have the h1 'About'" do
visit about_path
page.should have_selector('h1', text: 'About Us')
end
it "should have the title 'About Us'" do
visit about_path
page.should have_selector('title',
text: "Ruby on Rails Tutorial Sample App | About Us")
end
end
describe "Contact page" do
it "should have the h1 'Contact'" do
visit contact_path
page.should have_selector('h1', text: 'Contact')
end
it "should have the title 'Contact'" do
visit contact_path
page.should have_selector('title',
text: "Ruby on Rails Tutorial Sample App | Contact")
end
end
end
Rake Routes results:
root / static_pages#home
help /help(.:format) static_pages#help
about /about(.:format) static_pages#about
contact /contact(.:format) static_pages#contact
Try changing in your routes.rb your line to:
match '/about', to: 'static_pages#about', as: 'about'
and also you should reload Spork in order to changes apply.
You can also add:
load "#{Rails.root}/config/routes.rb"
into your Spork.each_run block in order to reload routes each time you run Spork.
Reloading spork worked for me.
Hi try to add this on your spec.
describe "Static pages" do
include Rails.application.routes.url_helpers
.......
I think you should type in the browser
http://localhost:3000/
instead of http://localhost:3000/static_pages/home to get the home page for example.
I think the problem is not the code but rather how to access the page. In the sections prior to 5.3.2 in the tutorial, you needed to visit localhost:3000/static_pages/home to access the homepage. After you follow instructions in 5.3.2, you only need to type http://localhost:3000/.
I just encountered this error, and had some help fixing this. I had mistakenly added the signin_path and signup_path on the layouts/_header.html.erb and static_pages/home.html.erb, respectively. This had EVERY page confused as to what the signin_path was.
The other issue I had made an error on was the root path. If you run 'rm public/index.html' from your sample app directory, 'root 'static_pages#home' in routes.rb, should work. The problem is that things in the public directory override any other part of your app as you customize it. Hope this helps you like it helped me :)
Named routes are not available in specs by default. Add the following code to the spec_helper.rb file:
RSpec.configure do |config|
config.include Rails.application.routes.url_helpers
end

Rails 3 Tutorial Section 7.3.1 Routing Error

I get the following error when running rspec spec/controllers/users_controller_spec.rb in section 7.3.1 of Michael Hartl's Rails Tutorial:
Failure/Error: get :show, :id => #user
ActionController::RoutingError:
No route matches {:id=>#<User id: 1, #rest is data from the factories.rb file....
Here's my code for the users_controller_spec.rb file:
require 'spec_helper'
require 'factories'
describe UsersController do
render_views
describe "GET 'show'" do
before(:each) do
#user = Factory(:user)
end
it "should be successful" do
get :show, :id => #user
response.should be_success
end
it "should find the right user" do
get :show, :id => #user
assigns(:user).should == #user
end
end
describe "GET 'new'" do
it "should be successful" do
get 'new'
response.should be_success
end
it "should have the right title" do
get 'new'
response.should have_selector("title", :content => "Sign up")
end
end
end
Here is my factories.rb code:
Factory.define :user do |user|
user.name "Michael Hartl"
user.email "mhartl#example.com"
user.password "foobar"
user.password_confirmation "foobar"
end
I inserted these lines in Spec_Helper in regards to 'factory_girl':
require 'factory_girl'
Factory.find_definitions
Any idea what's causing the routing error?
Here is my routes.rb code:
SampleApp::Application.routes.draw do
get "users/new"
match '/signup', :to => 'users#new'
match '/contact', :to => 'pages#contact'
match '/about', :to => 'pages#about'
match '/help', :to => 'pages#help'
root :to => 'pages#home'
The author's note regarding using - get :show, :id => #user instead of using - get :show, :id => #user.id:
" Second, note that the value of the hash key :id, instead of being the user’s id attribute #user.id, is the user object itself:
get :show, :id => #user
We could use the code:
get :show, :id => #user.id
to accomplish the same thing, but in this context Rails automatically converts the user object to the corresponding id. It does this by calling the to_param method on the #user variable.
You are missing a route to the show action for users. You can add something like this to the routes.rb file.
match "/users/:id" => "users#show"
If you want the normal CRUD actions, you can get rid of your users/new route and instead of the match line above, just declare them all with a single line:
resources :users
I believe your code is telling Rails that the id is the user, which of course doesn't make sense. That's creating a path like /users/#user, for which no route exists. As you probably know, you want a path like /users/1.
So I think you code should look like
get :show, :id => #user.id
or possibly
get :show, #user

Resources