Failure/Error with Ruby on Rails Tutorial Chapter 9 - ruby-on-rails

Can anyone who has done this exercises help me out?
It's my first time using this programming language and not much to this, but I need to finish well until chapter 10 that is a final evaluation.
1) User pages edit with valid information
Failure/Error: describe "page" do
NoMethodError:
undefined method `describe' for #<RSpec::Core::ExampleGroup::Nested_5::Nested_5::Nested_1:0xc283f8c>
# ./spec/requests/user_pages_spec.rb:87:in `block (3 levels) in <top (required)>'
2) User pages edit with valid information
Failure/Error: describe "page" do
NoMethodError:
undefined method `describe' for #<RSpec::Core::ExampleGroup::Nested_5::Nested_5::Nested_1:0xb67b1cc>
# ./spec/requests/user_pages_spec.rb:87:in `block (3 levels) in <top (required)>'
3) User pages edit with valid information
Failure/Error: describe "page" do
NoMethodError:
undefined method `describe' for #<RSpec::Core::ExampleGroup::Nested_5::Nested_5::Nested_1:0xc224244>
# ./spec/requests/user_pages_spec.rb:87:in `block (3 levels) in <top (required)>'
4) User pages edit with valid information
Failure/Error: describe "page" do
NoMethodError:
undefined method `describe' for #<RSpec::Core::ExampleGroup::Nested_5::Nested_5::Nested_1:0xc562690>
# ./spec/requests/user_pages_spec.rb:87:in `block (3 levels) in <top (required)>'
5) User pages edit with valid information
Failure/Error: describe "page" do
NoMethodError:
undefined method `describe' for #<RSpec::Core::ExampleGroup::Nested_5::Nested_5::Nested_1:0xc0559a4>
# ./spec/requests/user_pages_spec.rb:87:in `block (3 levels) in <top (required)>'
6) User pages index
Failure/Error: visit users_path
ActionView::Template::Error:
undefined method `each' for nil:NilClass
# ./app/views/users/index.html.erb:5:in `_app_views_users_index_html_erb__615083638_97671840'
# ./spec/requests/user_pages_spec.rb:12:in `block (3 levels) in <top (required)>'
7) User pages index
Failure/Error: visit users_path
ActionView::Template::Error:
undefined method `each' for nil:NilClass
# ./app/views/users/index.html.erb:5:in `_app_views_users_index_html_erb__615083638_97671840'
# ./spec/requests/user_pages_spec.rb:12:in `block (3 levels) in <top (required)>'
8) User pages index should list each user
Failure/Error: visit users_path
ActionView::Template::Error:
undefined method `each' for nil:NilClass
# ./app/views/users/index.html.erb:5:in `_app_views_users_index_html_erb__615083638_97671840'
# ./spec/requests/user_pages_spec.rb:12:in `block (3 levels) in <top (required)>'
9) Authentication authorization after signing in should render the desired protected page
Failure/Error: expect(page).to have_title('Edit user')
expected #has_title?("Edit user") to return true, got false
# ./spec/requests/authentication_pages_spec.rb:84:in `block (4 levels) in <top (required)>'
Finished in 2.25 seconds
72 examples, 9 failures
Failed examples:
rspec ./spec/requests/user_pages_spec.rb:114 # User pages edit with valid information
rspec ./spec/requests/user_pages_spec.rb:115 # User pages edit with valid information
rspec ./spec/requests/user_pages_spec.rb:112 # User pages edit with valid information
rspec ./spec/requests/user_pages_spec.rb:113 # User pages edit with valid information
rspec ./spec/requests/user_pages_spec.rb:111 # User pages edit with valid information
rspec ./spec/requests/user_pages_spec.rb:15 # User pages index
rspec ./spec/requests/user_pages_spec.rb:16 # User pages index
rspec ./spec/requests/user_pages_spec.rb:18 # User pages index should list each user
rspec ./spec/requests/authentication_pages_spec.rb:83 # Authentication authorization after signing in should render the desired protected page
Edit
Here is my code:
require 'spec_helper'
describe "User pages" do
subject { page }
describe "index" do
before do
sign_in FactoryGirl.create(:user)
FactoryGirl.create(:user, name: "Bob", email: "bob#example.com")
FactoryGirl.create(:user, name: "Ben", email: "ben#example.com")
visit users_path
end
it { should have_title('All users') }
it { should have_content('All users') }
it "should list each user" do
User.all.each do |user|
expect(page).to have_selector('li', text: user.name)
end
end
end
describe "profile page" do
let(:user) { FactoryGirl.create(:user) }
before { visit user_path(user) }
it { should have_content(user.name) }
it { should have_title(user.name) }
end
describe "signup page" do
before { visit signup_path }
it { should have_content('Sign up') }
it { should have_title(full_title('Sign up')) }
end
describe "signup" do
before { visit signup_path }
let(:submit) { "Create my account" }
describe "with invalid information" do
it "should not create a user" do
expect { click_button submit }.not_to change(User, :count)
end
describe "after submission" do
before { click_button submit }
it { should have_title('Sign up') }
it { should have_content('error') }
end
end
describe "with valid information" do
before do
fill_in "Name", with: "Example User"
fill_in "Email", with: "user#example.com"
fill_in "Password", with: "foobar"
fill_in "Confirmation", with: "foobar"
end
it "should create a user" do
expect { click_button submit }.to change(User, :count).by(1)
end
describe "after saving the user" do
before { click_button submit }
let(:user) { User.find_by(email: 'user#example.com') }
it { should have_link('Sign out') }
it { should have_title(user.name) }
it { should have_selector('div.alert.alert-success', text: 'Welcome') }
end
end
end
describe "edit" do
let(:user) { FactoryGirl.create(:user) }
before do
sign_in user
visit edit_user_path(user)
describe "page" do
it { should have_content("Update your profile") }
it { should have_title("Edit user") }
it { should have_link('change', href: 'http://gravatar.com/emails') }
end
describe "with invalid information" do
before { click_button "Save changes" }
it { should have_content('error') }
end
end
describe "with valid information" do
let(:new_name) { "New Name" }
let(:new_email) { "new#example.com" }
before do
fill_in "Name", with: new_name
fill_in "Email", with: new_email
fill_in "Password", with: user.password
fill_in "Confirm Password", with: user.password
click_button "Save changes"
end
it { should have_title(new_name) }
it { should have_selector('div.alert.alert-success') }
it { should have_link('Sign out', href: signout_path) }
specify { expect(user.reload.name).to eq new_name }
specify { expect(user.reload.email).to eq new_email }
end
end
end

If your code is formatted like this:
describe "edit" do
let(:user) { FactoryGirl.create(:user) }
before do
sign_in user
visit edit_user_path(user)
describe "page" do
it { should have_content("Update your profile") }
it { should have_title("Edit user") }
it { should have_link('change', href: 'http://gravatar.com/emails') }
end
I can see that it is probably broken without reading any of your code.
Are all your code blocks properly closed? Does not look so!

In addition to the unclosed blocks that phoet pointed out, which are causing your "undefined method describe" errors, you're getting errors in /app/views/users/index.html.erb line 5. The error is undefined method `each' for nil:NilClass which means there's a variable on that line that you're doing variable.each with, but you're either not setting that variable or when you're setting it, it's getting set to nil.
In general, the way for you to successfully get through this is to read the error messages and try to fix what they're complaining about. If you search for each error message individually, you'll find stack overflow questions about the specific issue that will help you.

Related

Michael Hart's Ruby on Rails Tutorial - Chapter 8 Failing Tests

I am currently working on Chapter 8 of Michael Hartl's Ruby on Rails tutorial. I encountered a problem with my tests failing and tried to solve this myself, but I realize it's useless, so I have to ask here. Here is the error message I'm getting.
Failures:
1) Authentication signin with invalid information after visiting another page
Failure/Error: it { should_not have_selector('div.alert.alert-error') }
expected #has_selector?("div.alert.alert-error") to return false, got true
# ./spec/requests/authentication_pages_spec.rb:18:in `block (5 levels) in <top (required)>'
2) Authentication signin with valid information
Failure/Error: click_button "Sign in"
NoMethodError:
undefined method `sign_in' for #<SessionsController:0x007f8dbc9d5868>
# ./app/controllers/sessions_controller.rb:8:in `create'
# ./spec/requests/authentication_pages_spec.rb:27:in `block (4 levels) in <top (required)>'
3) Authentication signin with valid information
Failure/Error: click_button "Sign in"
NoMethodError:
undefined method `sign_in' for #<SessionsController:0x007f8dbfdf53a0>
# ./app/controllers/sessions_controller.rb:8:in `create'
# ./spec/requests/authentication_pages_spec.rb:27:in `block (4 levels) in <top (required)>'
4) Authentication signin with valid information
Failure/Error: click_button "Sign in"
NoMethodError:
undefined method `sign_in' for #<SessionsController:0x007f8dbfcf5ea0>
# ./app/controllers/sessions_controller.rb:8:in `create'
# ./spec/requests/authentication_pages_spec.rb:27:in `block (4 levels) in <top (required)>'
5) Authentication signin with valid information
Failure/Error: click_button "Sign in"
NoMethodError:
undefined method `sign_in' for #<SessionsController:0x007f8dbfc0ccc8>
# ./app/controllers/sessions_controller.rb:8:in `create'
# ./spec/requests/authentication_pages_spec.rb:27:in `block (4 levels) in <top (required)>'
6) User pages signup with valid information should create a user
Failure/Error: fill_in "Confirmation", with: "foobar"
Capybara::ElementNotFound:
Unable to find field "Confirmation"
# ./spec/requests/user_pages_spec.rb:24:in `block (4 levels) in <top (required)>'
Finished in 0.60967 seconds
41 examples, 6 failures
Failed examples:
rspec ./spec/requests/authentication_pages_spec.rb:18 # Authentication signin with invalid information after visiting another page
rspec ./spec/requests/authentication_pages_spec.rb:30 # Authentication signin with valid information
rspec ./spec/requests/authentication_pages_spec.rb:32 # Authentication signin with valid information
rspec ./spec/requests/authentication_pages_spec.rb:31 # Authentication signin with valid information
rspec ./spec/requests/authentication_pages_spec.rb:33 # Authentication signin with valid information
rspec ./spec/requests/user_pages_spec.rb:27 # User pages signup with valid information should create a user
Randomized with seed 17229
Here is my authentication pages spec file
require 'spec_helper'
describe "Authentication" do
subject { page }
describe "signin" do
before { visit signin_path }
describe "with invalid information" do
before { click_button "Sign in" }
it { should have_title('Sign in') }
it { should have_selector('div.alert.alert-error') }
describe "after visiting another page" do
before { click_link "Home" }
it { should_not have_selector('div.alert.alert-error') }
end
end
describe "with valid information" do
let(:user) { FactoryGirl.create(:user) }
before do
fill_in "Email", with: user.email.upcase
fill_in "Password", with: user.password
click_button "Sign in"
end
it { should have_title(user.name) }
it { should have_link('Profile', href: user_path(user)) }
it { should have_link('Sign out', href: signout_path) }
it { should_not have_link('Sign in', href: signin_path) }
end
end
end
Here is my sessions_controller.rb file
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
sign_in user
redirect_to user
else
# Create an error message and re-render the signin form
flash.now[:error] = 'Invalid email/password combination'
render 'new'
end
end
def destroy
end
end
The main failure I'm trying to solve, that should be green is 1. I passed the flash.now hash to indicate that I want the flash to disappear after a second request, but rspec says no.
I'm stumped as to what the problem is. Any help would be greatly appreciated
RSpec tells you that method sign_in does not exists. If you look at the chapter 8.2.2 you will find a helper with this method.
#app/helpers/sessions_helper.rb
module SessionsHelper
def sign_in(user)
remember_token = User.new_remember_token
cookies.permanent[:remember_token] = remember_token
user.update_attribute(:remember_token, User.digest(remember_token))
self.current_user = user
end
end

RoR. Chapter 8, Section 8.2.4 - Undefined method for Signin

I'm working on RoR tutorial, Chapter 8. I am trying to complete section 8.2.4 - Changing the layout links and ran $ bundle exec rspec spec/ and I got the following error:
Failures:
1) Authentication signin with valid information
Failure/Error: click_button "Sign in"
NoMethodError:
undefined method `sign_in' for #<SessionsController:0x007fef66b85fd0>
# ./app/controllers/sessions_controller.rb:9:in `create'
# (eval):2:in `click_button'
# ./spec/requests/authentication_pages_spec.rb:35:in `block (4 levels) in <top (required)>'
2) Authentication signin with valid information
Failure/Error: click_button "Sign in"
NoMethodError:
undefined method `sign_in' for #<SessionsController:0x007fef66b33eb0>
# ./app/controllers/sessions_controller.rb:9:in `create'
# (eval):2:in `click_button'
# ./spec/requests/authentication_pages_spec.rb:35:in `block (4 levels) in <top (required)>'
3) Authentication signin with valid information
Failure/Error: click_button "Sign in"
NoMethodError:
undefined method `sign_in' for #<SessionsController:0x007fef6698bba8>
# ./app/controllers/sessions_controller.rb:9:in `create'
# (eval):2:in `click_button'
# ./spec/requests/authentication_pages_spec.rb:35:in `block (4 levels) in <top (required)>'
4) Authentication signin with valid information
Failure/Error: click_button "Sign in"
NoMethodError:
undefined method `sign_in' for #<SessionsController:0x007fef68286130>
# ./app/controllers/sessions_controller.rb:9:in `create'
# (eval):2:in `click_button'
# ./spec/requests/authentication_pages_spec.rb:35:in `block (4 levels) in <top (required)>'
Finished in 1.34 seconds
44 examples, 4 failures
Failed examples:
rspec ./spec/requests/authentication_pages_spec.rb:39 # Authentication signin with valid information
rspec ./spec/requests/authentication_pages_spec.rb:40 # Authentication signin with valid information
rspec ./spec/requests/authentication_pages_spec.rb:38 # Authentication signin with valid information
rspec ./spec/requests/authentication_pages_spec.rb:41 # Authentication signin with valid information
Based on the output, I checked spec/requests/authentication_pages_spec.rb, but I can't seem to find the error. This is what I have:
require 'spec_helper'
describe "Authentication" do
subject { page }
describe "signin page" do
before { visit signin_path }
it { should have_selector('h1', text: 'Sign in') }
it { should have_selector('title', text: 'Sign in') }
end
describe "signin" do
before { visit signin_path }
describe "with invalid information" do
before { click_button "Sign in" }
it { should have_selector('title', text: 'Sign in') }
it { should have_selector('div.alert.alert-error', text: 'Invalid') }
describe "after visiting antoher page" do
before { click_link "Home" }
it { should_not have_selector('div.alert.alert-error') }
end
end
describe "with valid information" do
let(:user) { FactoryGirl.create(:user) }
before do
fill_in "Email", with: user.email
fill_in "Password", with: user.password
click_button "Sign in"
end
it { should have_selector('title', text: user.name) }
it { should have_link('Profile', href: user_path(user)) }
it { should have_link('Sign out', href: signout_path) }
it { should_not have_link('Sign in', href: signin_path) }
end
end
end
I can't seem to find the error. Any suggestions on where I should look based on the error output? Thank you.
Check your config/routes.rb file to make sure that:
match '/signin', to: 'sessions#new'
matches what your session controllers is seeing. The create method for your "sessions_controller.rb" should have:
def create
user = User.find_by_email(params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
sign_in user
redirect_back_or user
else
flash.now[:error] = 'Invalid email/password combination'
render 'new'
end
end
Just my guess. I'm currently around that area too in the tutorial. Best of luck and I hope that helps!
A bit late probably but anyways...
Check if you got "include SessionsHelper" in app/controllers/application_controller.rb
helpers are included into views by default but you have to explicitly include them in controllers

Rails Tutorial: RSpec test decoupling

I'm trying to do Exercise 2 of Chapter 8.5 in Michael Hartl's Ruby on Rails Tutorial. The exercise is as follows:
Following the example in Section 8.3.3, go through the user and authentication request specs (i.e., the files currently in the spec/requests directory) and define utility functions in spec/support/utilities.rb to decouple the tests from the implementation. Extra credit: Organize the support code into separate files and modules, and get everything to work by including the modules properly in the spec helper file.
Example 8.3.3: utilities.rb
include ApplicationHelper
def valid_signin(user)
fill_in "Email", with: user.email
fill_in "Password", with: user.password
click_button "Sign in"
end
RSpec::Matchers.define :have_error_message do |message|
match do |page|
page.should have_selector('div.alert.alert-error', text: message)
end
end
The defined valid_signin(user) function is used in the following block of authentication_pages_spec.rb and works fine.
describe "with valid information" do
let(:user){FactoryGirl.create(:user)}
before { valid_signin(user) }
it { should have_selector('title', text: user.name) }
it { should have_link('Profile', href: user_path(user)) }
it { should have_link('Sign out', href: signout_path) }
it { should_not have_link('Sign in', href: signin_path) }
describe "followed by signout" do
before { click_link "Sign out" }
it { should have_link('Sign in') }
end
end
So with this example I set about to create my own named valid_signup(user):
def valid_signup(user)
fill_in "Name", with: user.name
fill_in "Email", with: user.email
fill_in "Password", with: user.password
fill_in "Confirmation", with: user.password_confirmation
end
I'm using this block in user_pages_spec.rb like this:
describe "with valid information" do
let(:user){FactoryGirl.create(:user)}
before { valid_signup(user) }
it "should create a user" do
expect { click_button submit }.to change(User, :count).by(1)
end
describe "after saving the user" do
before { click_button submit }
let(:user) { User.find_by_email(user.email) }
it { should have_selector('title', text: user.name) }
it { should have_selector('div.alert.alert-success', text: 'Welcome') }
it { should have_link('Sign out') }
end
end
It doesn't work. Spork/Guard reports these errors:
Failures:
1) UserPages signup with valid information should create a user
Failure/Error: expect { click_button submit }.to change(User, :count).by(1)
count should have been changed by 1, but was changed by 0
# ./spec/requests/user_pages_spec.rb:46:in `block (4 levels) in '
2) UserPages signup with valid information after saving the user
Failure/Error: before { valid_signup(user) }
NoMethodError:
undefined method `name' for nil:NilClass
# ./spec/support/utilities.rb:10:in `valid_signup'
# ./spec/requests/user_pages_spec.rb:43:in `block (4 levels) in '
3) UserPages signup with valid information after saving the user
Failure/Error: before { valid_signup(user) }
NoMethodError:
undefined method `name' for nil:NilClass
# ./spec/support/utilities.rb:10:in `valid_signup'
# ./spec/requests/user_pages_spec.rb:43:in `block (4 levels) in '
4) UserPages signup with valid information after saving the user
Failure/Error: before { valid_signup(user) }
NoMethodError:
undefined method `name' for nil:NilClass
# ./spec/support/utilities.rb:10:in `valid_signup'
# ./spec/requests/user_pages_spec.rb:43:in `block (4 levels) in '
The errors seem to suggest the user.name in my valid_signup(user) function in utilities.rb isn't defined, but I don't see any reason why. I've restarted Guard several times, and did a rake db:test:prepare to make sure the testing db (using postgresql) was in order.
Here's my factories.rb for completeness:
FactoryGirl.define do
factory :user do
name "Example User"
email "user#example.com"
password "foobar"
password_confirmation "foobar"
end
end
Before I continue to try and decouple more of the testing suite I'd very much like to solve this error and, more importantly, understand the reason for it.
EDIT
I've tried your tips, and edited the function in user_pages_spec.rb as follows:
describe "with valid information" do
before { valid_signup(user) }
it "should create a user" do
expect { click_button submit }.to change(User, :count).by(1)
end
describe "after saving the user" do
before { click_button submit }
let(:user) { User.find_by_email('user#example.com') }
it { should have_selector('title', text: user.name) }
it { should have_selector('div.alert.alert-success', text: 'Welcome') }
it { should have_link('Sign out') }
end
end
Since I removed let(:user){FactoryGirl.create(:user)} from the function I guessed there was no longer a user created in the function so I needed to define valid_signup(user) as such as the user variable for valid_signup was no longer being filled by FactoryGirl:
def valid_signup(user)
fill_in "Name", with: "Example User"
fill_in "Email", with: "user#example.com"
fill_in "Password", with: "foobar"
fill_in "Confirmation", with: "foobar"
end
This didn't work and gave me the following errors:
Failures:
1) UserPages signup with valid information should create a user
Failure/Error: before { valid_signup(user) }
NameError:
undefined local variable or method user' for #<RSpec::Core::ExampleGroup::Nested_5::Nested_3::Nested_2:0x007fdafc5088c0>
# ./spec/requests/user_pages_spec.rb:42:inblock (4 levels) in '
2) UserPages signup with valid information after saving the user
Failure/Error: it { should have_selector('title', text: user.name) }
NoMethodError:
undefined method name' for nil:NilClass
# ./spec/requests/user_pages_spec.rb:52:inblock (5 levels) in '
I also tried running the test with valid_signup(user) the way I used to have it before (with user.name, user.email, user.password, user.password_confirmation, which didn't work either, with errors:
Failures:
1) UserPages signup with valid information should create a user
Failure/Error: before { valid_signup(user) }
NameError:
undefined local variable or method `user' for #
# ./spec/requests/user_pages_spec.rb:42:in `block (4 levels) in '
2) UserPages signup with valid information after saving the user
Failure/Error: it { should have_selector('title', text: user.name) }
NoMethodError:
undefined method `name' for nil:NilClass
# ./spec/requests/user_pages_spec.rb:52:in `block (5 levels) in '
Next I tried running it without passing variables in user_pages_spec.rb: before { valid_signup() } and without a variable in the function in utilities.rb:
def valid_signup()
fill_in "Name", with: "Example User"
fill_in "Email", with: "user#example.com"
fill_in "Password", with: "foobar"
fill_in "Confirmation", with: "foobar"
end
This returned:
Failures:
1) UserPages signup with valid information should create a user
Failure/Error: before { valid_signup(user) }
NameError:
undefined local variable or method `user' for #
# ./spec/requests/user_pages_spec.rb:42:in `block (4 levels) in '
2) UserPages signup with valid information after saving the user
Failure/Error: it { should have_selector('title', text: user.name) }
NoMethodError:
undefined method `name' for nil:NilClass
# ./spec/requests/user_pages_spec.rb:52:in `block (5 levels) in '
Still no closer to the answer. I might be overlooking something simple. No clue what though. I got what I first did wrong though: I just thought FactoryGirl was a way to create variables, and I didn't know it actually did something to my test database.
I will try to explain what is going on in your original test (which I find easier to fix than the edited version):
describe "with valid information" do
let(:user) {FactoryGirl.build(:user)} # FactoryGirl.create will save the instance, you should be using build instead
before { valid_signup(user) }
it "should create a user" do
expect { click_button submit }.to change(User, :count).by(1)
end
describe "after saving the user" do
before { click_button submit }
# let(:user) { User.find_by_email(user.email) } # this is not needed any more
it { should have_selector('title', text: user.name) }
it { should have_selector('div.alert.alert-success', text: 'Welcome') }
it { should have_link('Sign out') }
end
end
More info on FactoryGirl usage: https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md#using-factories
FactoryGirl saves the user to the database, then you visit the sign_in_path with the user already on the database and fill the form for sign_in with valid_sigin(user)
let(:user){FactoryGirl.create(:user)}
before { valid_signin(user) }
When you do:
let(:user){FactoryGirl.create(:user)}
before { valid_signup(user) }
factory girl saves the user in the database, and you fill a form with an email already taken.
EDIT:
describe "with valid information" do
before { valid_signup(user) }
You dont have a variable user defined, since you deleted let(:user){FactoryGilr.create(:user)},and you should visit the right path, your current path is "sign_in_path" and should be "sign_up_path"
You should do something like this:
utilities.rb
def valid_sign_up(user)
fill_in "Name", with: user.name
fill_in "Email", with: user.email
fill_in "Password", with: user.password
fill_in "Confirmation", with: user.password_confirmation
end
user_pages_spec.rb
describe "with valid information" do
let(:user){User.new(name: "my name", email: "myemail#example"...)
before do
visit sign_up
valid_sign_up(user)
end
it "should create a user" do
expect { click_button submit }.to change(User, :count).by(1)
end
end
I had the same problem and figured out the solution: when you define valid_signup, it should take 'page' as the argument. After all, you are testing the page elements, not the user.
spec/support/utilities.rb
def valid_signup(page)
fill_in "Name", with: "Example User"
fill_in "Email", with: "user#example.com"
fill_in "Password", with: "foobar"
fill_in "Confirmation", with: "foobar"
end
spec/requests/user_pages_spec.rb
describe "with valid information" do
before { valid_signup(page) }
it "should create a user" do
expect { click_button submit }.to change(User, :count).by(1)
end
I hope this helps!
UPDATE I realize now that this works because of the scope of the variable 'page' (since it's the subject). To use "user" I added the line
let(:user) { FactoryGirl.create(:user) }
above
before { sign_up(user) }. This then broke a later spec where I also tried using 'user' as a variable, so I changed the name to 'editeduser'. Here's the full example:
user_pages_spec.rb
require 'spec_helper'
describe "UserPages" do
subject { page }
...
describe "signup page" do
before { visit signup_path }
let(:submit) { "Create my account" }
it { should have_selector('h1', text: 'Sign up') }
it { should have_selector('title', text: full_title('Sign up')) }
describe "with invalid information" do
it "should not create a user" do
expect { click_button submit }.not_to change(User, :count)
end
describe "after submission" do
before { click_button submit }
it { should have_selector('title', text: 'Sign up') }
it { should have_content('error') }
end
end
describe "with valid information" do
let(:user) { FactoryGirl.create(:user) }
before { sign_up(user) }
it "should create a user" do
expect { click_button submit }.to change(User, :count).by(1)
end
describe "after saving the user" do
before { click_button submit }
let(:editeduser) { User.find_by_email('user#example.com') }
it { should have_selector('title', text: editeduser.name) }
it { should have_selector('div.alert.alert-success', text: 'Welcome') }
it { should have_link('Sign out') }
end
end
end
Hopefully this helps someone!
I was curious about this one as well, and found an answer that may be more in line with what Hartl was expecting (though as just learning, I'm not 100% certain the top answer isn't more elegant or not).
Since we weren't using FactoryGirl to sign up users, but instead to sign them in, I didn't want to use it in my refactoring. This is what I have in my utilities.rb:
def valid_signup
fill_in "Name", with: "Example User"
fill_in "Email", with: "user#example.com"
fill_in "Password", with: "foobar"
fill_in "Confirmation", with: "foobar"
end
and then in user_pages_spec.rb I replaced
describe "with valid information" do
before do
fill_in "Name", with: "Example User"
fill_in "Email", with: "user#example.com"
fill_in "Password", with: "foobar"
fill_in "Confirmation", with: "foobar"
end
with
describe "with valid information" do
before { valid_signup }
We don't need a user to be saved to the database just to check a one time sign up, since they don't need to persist through multiple page views. Also, since we don't look up a user, we don't need a (user) argument after valid_signup method (I think I have the terminology correct. Please correct me if I do not.)

Ruby on Rails Tutorial - Getting Errors, pulling my hair out

Im following [Michael Hartl's tutorial][1] and did the exercises in Chapter 7, and now have 4 errors that I cant figure out how to fix for the life of me. When I test the production app manually, the errors dont exist at all. So I don't know if there is something wrong with my text development or something, but Im at a total loss so I thought I'd post here to see if my total noobness is blinding me...thanks for your help!
Here's the 4 error messages I'm getting:
Failures:
1) signup with invalid information after submission
Failure/Error: it { should have_selector('title', text: "Sign up") }
expected css "title" with text "Sign up" to return something
# ./spec/requests/user_pages_spec.rb:38:in `block (4 levels) in <top (required)>'
2) signup with invalid information after submission
Failure/Error: it { should have_content('error') }
expected there to be content "error" in "after submission"
# ./spec/requests/user_pages_spec.rb:39:in `block (4 levels) in <top (required)>'
3) signup after saving the user
Failure/Error: it { should have_selector('title', text: user.name) }
NoMethodError:
undefined method `name' for nil:NilClass
# ./spec/requests/user_pages_spec.rb:60:in `block (3 levels) in <top (required)>'
4) signup after saving the user
Failure/Error: it { should have_selector('div.alert.alert-success', text: 'Welcome') }
expected css "div.alert.alert-success" with text "Welcome" to return something
# ./spec/requests/user_pages_spec.rb:61:in `block (3 levels) in <top (required)>'
Finished in 6.8 seconds
10 examples, 4 failures
Failed examples:
rspec ./spec/requests/user_pages_spec.rb:38 # signup with invalid information after submission
rspec ./spec/requests/user_pages_spec.rb:39 # signup with invalid information after submission
rspec ./spec/requests/user_pages_spec.rb:60 # signup after saving the user
rspec ./spec/requests/user_pages_spec.rb:61 # signup after saving the user
Here's the code on my user_pages_spec.rb:
require 'spec_helper'
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') }
it { should have_selector('title', text: full_title('Sign up')) }
end
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
end
describe "signup" do
before { visit signup_path }
let(:submit) { "Create my account" }
describe "with invalid information" do
it "should not create a user" do
expect { click_button submit }.not_to change(User, :count)
end
describe "after submission" do
before { click_button submit }
it { should have_selector('title', text: "Sign up") }
it { should have_content('error') }
end
end
describe "with valid information" do
before do
fill_in "Name", with: "Example User"
fill_in "Email", with: "user#example.com"
fill_in "Password", with: "foobar"
fill_in "Confirmation", with: "foobar"
end
it "should create a user" do
expect { click_button submit }.to change(User, :count).by(1)
end
end
describe "after saving the user" do
before { click_button submit }
let(:user) { User.find_by_email('user#example.com') }
it { should have_selector('title', text: user.name) }
it { should have_selector('div.alert.alert-success', text: 'Welcome') }
end
end
[1]: http://ruby.railstutorial.org/
Here's the template code for views/users/show.html.erb
<% provide(:title, #user.name) %>
<div class="row">
<aside class="span4">
<section>
<h1>
<%= gravatar_for #user %>
<%= #user.name %>
</h1>
</section>
</aside>
</div>
and then here's the users_controller.rb
class UsersController < ApplicationController
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
end
Allright y'all,
I dont know if not answering my question was some sort of torturous initiation for noobs in this forum, but after almost 24 hours and a good night sleep, I solved the problem!
After a few G searches, I found that I could be stopping some of the variables from passing through by having "end" in the wrong places. It turns out there were 2 main areas where I was doing this. Once I found and fixed those, all the errors went away.
I will now pat myself on the back. I hope this helps any total noobs who run into this same problem in the future.

Chapter 7 Ruby on Rails users_controller.rb error

I followed all the instructions in chapter 7 Ruby on Rails tutorial, when I finally run $ Bundle exec rspec spec/ a series of errors are being displayed. I doubled checked if my codes had any spelling mistakes or any symbols left out. Everything seems to fine. Could you please kindly interpret the errors and tell me where I am going wrong??? Thanks
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 ') }
it { should have_selector('title', text: full_title('Sign up')) }
end
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
describe "signup" do
before { visit signup_path }
let(:submit) { "Create my account" }
describe "with invalid information" do
it "should not create a user" do
expect { click_button submit }.not_to change(User, :count)
end
end
describe "with valid information" do
before do
fill_in "Name", with: "Example User"
fill_in "Email", with: "user#example.com"
fill_in "Password", with: "foobar"
fill_in "Confirmation", with: "foobar"
end
it "should create a user" do
expect { click_button submit }.to change(User, :count).by(1)
end
describe "after saving a user" do
before {click_button submit}
let (:user) {user.find_by_email("user#example.com")}
it {should have_selector('title', text:user.name)}
end
end
end
end
USER_CONTROLLER.RB
class UsersController < ApplicationController
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
end
ERRORS DISPLAYED ON COMMAND LINE
3) User pages signup page
←[31mFailure/Error:←[0m ←[31mit { should have_selector('title', text: full_
title('Sign up')) }←[0m
←[31mNoMethodError:←[0m
←[31mundefined method full_title' for #<RSpec::Core::ExampleGroup::Neste
d_2::Nested_1:0x461b260>←[0m
←[36m # ./spec/requests/user_pages_spec.rb:11:inblock (3 levels) in '←[0m
4) User pages profile page
←[31mFailure/Error:←[0m ←[31mit { should have_selector('title', text: user.
name) }←[0m
←[31mexpected css "title" with text "Michael Hartl" to return something←[
0m
←[36m # ./spec/requests/user_pages_spec.rb:19:in `block (3 levels) in '←[0m
5) User pages signup with valid information should create a user
←[31mFailure/Error:←[0m ←[31mexpect { click_button submit }.to change(User,
:count).by(1)←[0m
←[31mNoMethodError:←[0m
←[31mundefined method sign_in' for #<UsersController:0x45a8f00>←[0m
←[36m # ./app/controllers/users_controller.rb:14:increate'←[0m
←[36m # (eval):2:in click_button'←[0m
←[36m # ./spec/requests/user_pages_spec.rb:43:inblock (5 levels) in '←[0m
←[36m # ./spec/requests/user_pages_spec.rb:43:in `block (4 levels) in '←[0m
6) User pages signup with valid information after saving a user
←[31mFailure/Error:←[0m ←[31mbefore {click_button submit}←[0m
←[31mNoMethodError:←[0m
←[31mundefined method sign_in' for #<UsersController:0x46341c0>←[0m
←[36m # ./app/controllers/users_controller.rb:14:increate'←[0m
←[36m # (eval):2:in click_button'←[0m
←[36m # ./spec/requests/user_pages_spec.rb:47:inblock (5 levels) in '←[0m
1) undefined method full_title
Are you defined it?
2) expected css "title" with text "Michael Hartl" to return something
You haven't <title>Michael Hartl</title> in output html.
3, 4) undefined method sign_in
Where are you defined it?
Correct your code and all tests will be passed.

Resources