Rails Tutorial 9.3 failed test updating User authentication - ruby-on-rails

I am having a problem with the Rails Tutorial (rails 3). I'm currently on 9.28 rSpec tests and I have been in constant search to figure out what I did to make these two errors.
user#ubuntu:~/rails_projects/sample_app$ bundle exec rspec spec/
......................F.F............................................
Failures:
1) Authentication authorization in the Users controller visiting the edit page
Failure/Error: before { visit edit_user_path(user) }
NameError:
undefined local variable or method `user' for #<RSpec::Core::ExampleGroup::Nested_3::Nested_3::Nested_2::Nested_1:0x9685354>
# ./spec/requests/authentication_pages_spec.rb:75:in `block (5 levels) in <top (required)>'
2) Authentication authorization in the Users controller submitting to the update action
Failure/Error: before { put user_path(user) }
NameError:
undefined local variable or method `user' for #<RSpec::Core::ExampleGroup::Nested_3::Nested_3::Nested_2::Nested_3:0x9b12034>
# ./spec/requests/authentication_pages_spec.rb:85:in `block (5 levels) in <top (required)>'
Finished in 10.86 seconds
69 examples, 2 failures
Failed examples:
rspec ./spec/requests/authentication_pages_spec.rb:76 # Authentication authorization in the Users controller visiting the edit page
rspec ./spec/requests/authentication_pages_spec.rb:86 # Authentication authorization in the Users controller submitting to the update action
This is the authentication spec:
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: full_title('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: full_title('Sign in')) }
it { should have_selector('div.alert.alert-error', text: 'Invalid')}
describe "after visiting another page" do
before { click_link "Home" }
it { should_not have_selector ('div.alert.alert-error') }
end
end
describe "valid information" do
let (:user) { FactoryGirl.create(:user) }
before { sign_in user }
it { should have_selector('title', text: full_title(user.name)) }
it { should have_link('Users', href: users_path) }
it { should have_link('Profile', href: user_path(user)) }
it { should have_link('Settings', href: edit_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', href: signin_path) }
end
end
end
describe "authorization" do
describe "for non-signed-in users" do
let(:user) { FactoryGirl.create(:user) }
describe "when attempting to visit a protected page" do
before do
visit edit_user_path(user)
fill_in "Email", with: user.email
fill_in "Password", with: user.password
click_button "Sign in"
end
describe "after signing in" do
it "should render the desired protected page" do
expect(page).to have_selector('title', text: ('Edit user'))
end
end
end
end
describe "in the Users controller" do
describe "visiting the edit page" do
before { visit edit_user_path(user) }
it { should have_selector('title', text: full_title('Sign in')) }
end
describe "visiting the user index" do
before { visit users_path }
it { should have_selector('title', text: full_title('Sign in')) }
end
describe "submitting to the update action" do
before { put user_path(user) }
specify { response.should redirect_to(signin_path) }
end
end
describe "as wrong user" do
let(:user) { FactoryGirl.create(:user) }
let(:wrong_user) { FactoryGirl.create(:user, email: "wrong#example.com") }
before { sign_in user, no_capybara: true }
describe "submitting a GET request to the Users#edit action" do
before { get edit_user_path(wrong_user) }
specify { expect(response.body).not_to match(full_title('Edit user')) }
specify { expect(response).to redirect_to(root_url) }
end
describe "submitting a PUT request to the Users#update action" do
before { put user_path(wrong_user) }
specify { expect(response).to redirect_to(root_url) }
end
end
end
end
Really I have been trying to figure this out for quite sometime, if it is possible to walk through explanation ( if it is not typo ) would be awesome. Starting to grasp Rails but not quite there.

If you reindent the messy spec code, you can see that you are missing the user definition in your describe "in the Users controller" block.
Seeing that you are using the user in all three describe blocks in the Authorization, I'd move it one level up, so you'll end up with:
describe "authorization" do
let(:user) { FactoryGirl.create(:user) }
describe "for non-signed-in users" do
...
end
describe "in the Users controller" do
...
end
describe "as wrong user" do
let(:wrong_user) { FactoryGirl.create(:user, email: "wrong#example.com") }
before { sign_in user, no_capybara: true }
...
end
end

Related

Rails Tutorial Unable to find field "Name" at spec run after 10.34 [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am going through the Rails tutorial and I have an issue that seems to be causing a lot of other tests to fail. There are 23 errors and most of them explain that there is a missing field called "Name". When I run the command
bundle exec rspec spec/requests/user_pages_spec.rb
I get the following errors (that seem to change order every time I run it):
1) User pages edit with valid information
Failure/Error: fill_in "Name", with: new_name
Capybara::ElementNotFound:
Unable to find field "Name"
# ./spec/requests/user_pages_spec.rb:136:in `block (4 levels) in '
As a result, many other cases seem to fail. What app file would cause this issue? sessions_helper.rb?
Here is my spec/requests/user_pages_spec.rb: require 'spec_helper'
describe "User pages" do
subject { page }
describe "index" do
let(:user) { FactoryGirl.create(:user) }
before do
sign_in user
visit users_path
end
it { should have_title('All users') }
it { should have_content('All users') }
describe "pagination" do
before(:all) { 30.times { FactoryGirl.create(:user) } }
after(:all) { User.delete_all }
it { should have_selector('div.pagination') }
it "should list each user" do
User.paginate(page: 1).each do |user|
expect(page).to have_selector('li', text: user.name)
end
end
end
describe "delete links" do
it { should_not have_link('delete') }
describe "as an admin user" do
let(:admin) { FactoryGirl.create(:admin) }
before do
sign_in admin
visit users_path
end
it { should have_link('delete', href: user_path(User.first)) }
it "should be able to delete another user" do
expect do
click_link('delete', match: :first)
end.to change(User, :count).by(-1)
end
it { should_not have_link('delete', href: user_path(admin)) }
end
end
end
describe "profile page" do
let(:user) { FactoryGirl.create(:user) }
let!(:m1) { FactoryGirl.create(:micropost, user: user, content: "Foo") }
let!(:m2) { FactoryGirl.create(:micropost, user: user, content: "Bar") }
before { visit user_path(user) }
it { should have_content(user.name) }
it { should have_title(user.name) }
describe "microposts" do
it { should have_content(m1.content) }
it { should have_content(m2.content) }
it { should have_content(user.microposts.count) }
end
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 }
signup_errors
end
end
describe "with valid information" do
before { valid_signup }
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_welcome_message( 'Welcome')}
describe "followed by signout" do
before { click_link "Sign out" }
it { should have_link('Sign in') }
end
end
end
end
describe "edit" do
let(:user) { FactoryGirl.create(:user) }
before do
sign_in user
visit edit_user_path(user)
end
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 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
The error you receive when running your spec suggests that Capybara expects a field called "Name" to fill (because you ask it to at line fill_in "Name", with: new_name).
If for some reason, after sign-in you don't get to the user form, or the user form is missing the "Name" field - that would explain your failures.
In your comment you say that you get no form after sign-up, so that would definitely explain that.
To verify that, you can add a test to describe "page" like this:
it { should have_field("Name") }
If that fails - you can't expect any of the tests counting on that field to pass...

Failing rspec test

I have a failing Rspec test, _pages_spec.rb. I am following Micheal Hartl's Rails Tutorial.
When I have the second "end" at line 83, all tests pass but one:
Failures:
1) User pages signup edit with valid information
←[31mFailure/Error:←[0m ←[31mit { should have_selector('div.alert.alert-suc
cess') }←[0m
←[31mexpected css "div.alert.alert-success" to return something←[0m
←[36m # ./spec/requests/user_pages_spec.rb:77:in `block (5 levels) in <top (
required)>'←[0m
Finished in 1.28 seconds
←[31m60 examples, 1 failure←[0m
Failed examples:
←[31mrspec ./spec/requests/user_pages_spec.rb:77←[0m ←[36m# User pages signup ed
it with valid information ←[0m
Here is the code:
require 'spec_helper'
describe "User pages" do
subject { page }
let (:base_title) {"Tom Gong's Sample App"}
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 page" do
before { visit signup_path }
it { should have_selector('h1', text: 'Sign up') }
it { should have_selector('title', content: "#{base_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_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
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
describe "edit" do
let(:user) { FactoryGirl.create(:user) }
before { visit edit_user_path(user) }
describe "page" do
it { should have_selector('h1', text: "Update your profile") }
it { should have_selector('title', text:"Edit user") }
it { should have_selector('a', href: 'http://gravatar.com/emails') }
end
describe "with invalid information" do
before { click_button "Save changes" }
it { should have_content('error') }
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_selector('title', text: new_name) }
it { should have_selector('div.alert.alert-success') }
it { should have_link('Sign out', href: signout_path) }
specify { user.reload.name.should == new_name }
specify { user.reload.email.should == new_email }
end
end
end
end
Can anyone find the problem?
User pages signup edit with valid information
Here's how it looks like:
User pages
|- signup
|- edit
|- with valid information
It should be
User pages edit with valid information
i.e.
User pages
|- edit
|- with valid information
Currently edit is described under signup. That's not quite right.
I have the second "end" at line 83
It should be right after the line 53 rather than 83. i.e. right before describe "edit" do.
With consistent indentation you don't need to guess where to put matching end, it should be obvious from code.
The error message is telling you that the page does not have the selector 'div.alert.alert-success'. It looks like the error is related to this line:
it { should have_selector('div.alert.alert-success', text:'Welcome') }`
Capybara has a nifty method called save_and_open_page that lets you inspect the HTML file that Capybara parses. Call this method and view the source to inspect the selector that is not working for you. If you are still having trouble, paste the HTML that corresponds to the selector in your question.
You should clean up the formatting of your code because it is very hard to read with the inconsistent spacing and indentation.

Hartl Tutorial chapter 10 Factory Girl error - factory not registered: micropost

I am getting this error in relation to: "Authentication authorization in the Microposts controller submitting to the destroy action"
spec/requests.authentication_pages_spec.rb:119
The only solutions I have seen to this involve restarting the rails server and/or spork (which I am not using) have restarted the server though.
git://github.com/princeofburma/sample_app.git
spec/requests.authentication_pages_spec.rb
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_error_message }
describe "after visiting another page" do
before { click_link "Home" }
it { should_not have_error_message }
end
end
describe "with valid information" do
let(:user) { FactoryGirl.create(:user) }
before { sign_in 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 have_link('Settings', href: edit_user_path(user)) }
it { should have_link('Users', href: users_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
end
describe "authorization" do
describe "for non-signed-in users" do
let(:user) { FactoryGirl.create(:user) }
describe "when attempting to visit a protected page" do
before do
visit edit_user_path(user)
fill_in "Email", with: user.email
fill_in "Password", with: user.password
click_button "Sign in"
end
describe "after signing in" do
it "should render the desired protected page" do
page.should have_selector('title', text: 'Edit user')
end
describe "when signing in again" do
before do
click_link "Sign out"
click_link "Sign in"
fill_in "Email", with: user.email
fill_in "Password", with: user.password
click_button "Sign in"
end
it "should render the default (profile) page" do
page.should have_selector('title', text: user.name)
end
end
end
end
describe "in the Users controller" do
describe "visiting the edit page" do
before { visit edit_user_path(user) }
it { should have_selector('title', text: 'Sign in') }
it { should have_selector('div.alert.alert-notice') }
end
describe "submitting to the update action" do
before { put user_path(user) }
specify { response.should redirect_to(signin_path) }
end
describe "visiting the user index" do
before { visit users_path }
it { should have_selector('title', text: 'Sign in') }
end
describe "visiting the following page" do
before { visit following_user_path(user) }
it { should have_selector('title', text: 'Sign in') }
end
describe "visiting the followers page" do
before { visit followers_user_path(user) }
it { should have_selector('title', text: 'Sign in') }
end
end
end
describe "in the Microposts controller" do
describe "submitting to the create action" do
before { post microposts_path }
specify { response.should redirect_to(signin_path)}
end
describe "submitting to the destroy action" do
before { delete micropost_path(FactoryGirl.create(:micropost)) }
specify { response.should redirect_to(signin_path) }
end
end
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: '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
describe "as non-admin user" do
let(:user) { FactoryGirl.create(:user) }
let(:non_admin) { FactoryGirl.create(:user) }
before { sign_in non_admin }
describe "submitting a DELETE request to the Users#destroy action" do
before { delete user_path(user) }
specify { response.should redirect_to(root_path) }
end
end
end
end
Here is my factories.rb file
FactoryGirl.define do
factory :user do
sequence(:name) { |n| "Person #{n}" }
sequence(:email) { |n| "person_#{n}#example.com"}
password "foobar"
password_confirmation "foobar"
factory :admin do
admin true
end
end
factory :micropost do
content "Lorem ipsum"
user
end
end
here is the spec_helper.rb
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
# ## Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
# --seed 1234
config.order = "random"
end
ran the FactoryGirl.create(:micropost) from the test console and got:
irb(main):002:0> FactoryGirl.create(:micropost)
ArgumentError: Factory not registered: micropost
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/factory_girl-4
.1.0/lib/factory_girl/registry.rb:24:in `find'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/factory_girl-4
.1.0/lib/factory_girl/decorator.rb:10:in `method_missing'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/factory_girl-4
.1.0/lib/factory_girl.rb:71:in `factory_by_name'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/factory_girl-4
.1.0/lib/factory_girl/factory_runner.rb:12:in `run'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/factory_girl-4
.1.0/lib/factory_girl/strategy_syntax_method_registrar.rb:19:in `block in define
_singular_strategy_method'
from (irb):2
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/railties-3.2.9
/lib/rails/commands/console.rb:47:in `start'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/railties-3.2.9
/lib/rails/commands/console.rb:8:in `start'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/railties-3.2.9
from script/rails:6:in `require
from script/rails:6:in `<main>'
i think your problem is in your spec_helper.rb
take a look how it manages factories definitions
https://gist.github.com/scottvrosenthal/1724370
i hope it helps.
I downloaded your project and I am not getting that error. The only problem that I had seen in your application is that you don't have a remember_token method in your User model.
class User < ActiveRecord::Base
attr_accessible :name, :email, :password, :password_confirmation, :remember_token
...
private
def create_remember_token
# NoMethodError: undefined method `remember_token=' for User
self.remember_token = SecureRandom.urlsafe_base64
end
end

Rails Tutorial: Chapter 8.1.5 error (rendering with a flash message; listings 8.11 and 8.12)

I am taking the RoR Tutorial. In the last part of chapter 8.1.5, when all the rspec tests should turn green, I just can't get mine to work. I run bundle exec rspec spec/requests/authentication_pages_spec.rb -e "signin with invalid information" and of the four tests, one fails, with this error:
1) Authentication signin with invalid information after visiting another page
Failure/Error: it { should_not have_selector('div.alert.alert-error') }
expected css "div.alert.alert-error" not to return anything
# ./spec/requests/authentication_pages_spec.rb:25:in `block (5 levels) in <top (required)>'
The text for app/controllers/sessions_controller.rb is below:
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:session][:email])
if user && user.authenticate(params[:session][:password])
# Sign the user in and redirect to the user's show page.
else
flash.now[:error] = 'Invalid email/password combination'
render 'new'
end
end
def destroy
end
end
The text for spec/requests/authetication_pages_spec.rb is below:
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 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
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
If you have any thoughts or ideas, please let me know, I'm totally stumped!
I cloned your repo and found your problem.
The links in your header file (app/views/layouts/_header.html.erb) don't go anywhere:
<li><%= link_to "Home", '#' %></li>
<li><%= link_to "Help", '#' %></li>
So, when your tests are run, the following tests pass because an error is displayed...
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') }
...but when you then click on a link that doesn't go anywhere...
describe "after visiting another page" do
before { click_link "Home" } # goes nowhere
it { should_not have_selector('div.alert.alert-error') }
end
end
...that error is still on the page, so the test correctly fails.
Once you change your "Home" link destination from '#' to root_path, your test should pass.
Looking at the text, if you're on Chapter 8, it seems you missed a step a few chapters back on Listing 5.2.4 in Chapter 5.3.3, so you should be in a better state once you've gone back and fixed it.
I'd also recommend installing the launchy gem so that you can call helpful Capybara methods like save_and_open_page in your tests and it will open a browser for you with the state of your page at the time you called the method; helps a lot with debugging.
Replace
it { should_not have_selector('div.alert.alert-error') }
by
it { should_not have_selector('div.alert.alert-error', text: 'Invalid') }

Michael Hartl's Ruby on Rails Tutorial. Failed test in Chapter 9

I'm a newbie working through Michael Hartl's Tuby on Rails Tutorial and I have a couple of failed items in a test in Chapter 9.
Running RSPEC test returns:
sis-macbook-pro:sample_app Lagaspi$ bundle exec rspec spec/
...................................FF................................
Failures:
1) Authentication authorization in the Users controller visiting the edit page
Failure/Error: before { visit edit_user_path(user) }
NameError:
undefined local variable or method `user' for #<RSpec::Core::ExampleGroup::Nested_2::Nested_3::Nested_2::Nested_1:0x007fca6433d3b8>
# ./spec/requests/authentication_pages_spec.rb:72:in `block (5 levels) in <top (required)>'
2) Authentication authorization in the Users controller submitting to the update action
Failure/Error: before { put user_path(user) }
NameError:
undefined local variable or method `user' for #<RSpec::Core::ExampleGroup::Nested_2::Nested_3::Nested_2::Nested_2:0x007fca6434db50>
# ./spec/requests/authentication_pages_spec.rb:77:in `block (5 levels) in <top (required)>'
Finished in 1.85 seconds
69 examples, 2 failures
Failed examples:
rspec ./spec/requests/authentication_pages_spec.rb:73 # Authentication authorization in the Users controller visiting the edit page
rspec ./spec/requests/authentication_pages_spec.rb:78 # Authentication authorization in the Users controller submitting to the update action
My authentication_pages_spec.rb
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 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 { sign_in 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 have_link('Settings', href: edit_user_path(user)) }
it { should have_link('Users', href: users_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
end
describe "authorization" do
describe "for non-signed-in users" do
let(:user) { FactoryGirl.create(:user) }
describe "when attempting to visit a protected page" do
before do
visit edit_user_path(user)
fill_in "Email", with: user.email
fill_in "Password", with: user.password
click_button "Sign in"
end
describe "after signing in" do
it "should render the desired protected page" do
page.should have_selector('title', text: 'Edit user')
end
end
end
end
describe "in the Users controller" do
describe "visiting the edit page" do
before { visit edit_user_path(user) }
it { should have_selector('title', text: 'Sign in') }
end
describe "submitting to the update action" do
before { put user_path(user) }
specify { response.should redirect_to(signin_path) }
end
end
end
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
end
Here's line 73 from above
it { should have_selector('title', text: 'Sign in') }
And line 78 from above
specify { response.should redirect_to(signin_path) }
Any ideas? I'm really stuck as to what this means.Thanks Si.
On line 50 you have
let(:user) { FactoryGirl.create(:user) }
But :user is no longer available by the time you reach line 73 because you close off the describe block that :user is defined within in line 68. Same thing on line 77 where you try to use it again.
My recommendation is to move the let(:user) to the top of the spec so you only need to define it once instead of including it throughout the spec. Failing that, define it again on line 71 (the line after describe "in the Users controller" do)
Potential solution is defining let(:user)..... at the top so you only need to define user once instead of in each block
require 'spec_helper'
describe "authentication" do
subject { page }
let(:user) { FactoryGirl.create(:user) }
...

Resources