0
votes

I have been working on the ruby on rails tutorial. I am totally new to this stuff. I am in chapter 9 and totally stuck. I am hoping someone might help me decipher the error messages. Up until now I have just searched them and figured it out but I think it would be more valuable to just learn how to decipher the error message to fix the problem. If it is too long or cumbersome to explain than than I totally understand if no one wants to take it on. I was unable to find something online that helped me with this on my own.

Here are the errors that I am currently getting

1) AuthenticationPages signin with valid information authorization for non-signed-in users when attempting to visit a protected page after signing in should render the desired protected page

 Failure/Error: click_button "Sign in"
 Capybara::ElementNotFound:
   Unable to find button "Sign in"
 # ./spec/requests/authentication_pages_spec.rb:61:in `block (7 levels) in <top (required)>'

2) AuthenticationPages signin with valid information authorization for non-signed-in users in the Users controller visiting the edit page

 Failure/Error: it { should have_title('Sign in') }
   expected #has_title?("Sign in") to return true, got false
 # ./spec/requests/authentication_pages_spec.rb:76:in `block (8 levels) in <top (required)>'

3) AuthenticationPages signin with valid information authorization for non-signed-in users in the Users controller as wrong user visiting Users#edit page

 Failure/Error: before { sign_in user, no_capybara: true }
 NoMethodError:
   undefined method `sign_in' for #<RSpec::Core::ExampleGroup::Nested_2::Nested_2::Nested_2::Nested_2::Nested_1::Nested_2::Nested_3::Nested_1:0xabbb9e4>
 # ./spec/requests/authentication_pages_spec.rb:87:in `block (8 levels) in <top (required)>'

4) AuthenticationPages signin with valid information authorization for non-signed-in users in the Users controller as wrong user submitting a PATCH request to the User#update action

 Failure/Error: before { sign_in user, no_capybara: true }
 NoMethodError:
   undefined method `sign_in' for #<RSpec::Core::ExampleGroup::Nested_2::Nested_2::Nested_2::Nested_2::Nested_1::Nested_2::Nested_3::Nested_2:0xa82d354>
 # ./spec/requests/authentication_pages_spec.rb:87:in `block (8 levels) in <top (required)>'

Finished in 6.6 seconds 65 examples, 4 failures

Failed examples:

rspec ./spec/requests/authentication_pages_spec.rb:66 # AuthenticationPages signin with valid information authorization for non-signed-in users when attempting to visit a protected page after signing in should render the desired protected page

rspec ./spec/requests/authentication_pages_spec.rb:76 # AuthenticationPages signin with valid information authorization for non-signed-in users in the Users controller visiting the edit page

rspec ./spec/requests/authentication_pages_spec.rb:91 # AuthenticationPages signin with valid information authorization for non-signed-in users in the Users controller as wrong user visiting Users#edit page

rspec ./spec/requests/authentication_pages_spec.rb:96 # AuthenticationPages signin with valid information authorization for non-signed-in users in the Users controller as wrong user submitting a PATCH request to the User#update action

authentication_pages_spec.rb

require 'spec_helper'

describe "AuthenticationPages" do


subject { page }


describe "signin page" do
    before { visit signin_path }

    it { should have_content('Sign in') }
    it { should have_title('Sign in') }
end

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', text: 'Invalid') }

        describe "after visiting another page" do
            before { click_link "Home" }
            it { should_not have_selector('div.alert.alert-error', text: 'Invalid') }
        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('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') }
        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_title('Edit user')
                        end
                    end
                end

                describe "in the Users controller" do

                    describe "visiting the edit page" do
                        before { visit edit_user_path(user) }
                        it { should have_title('Sign in') }
                    end

                    describe "submitting to the update action" do
                        before { patch user_path(user) }
                        specify { expect(response).to redirect_to(signin_path) }
                    end

                    describe "as wrong user" do
                        let(:user) { FactoryGirl.create(:user) }
                        let(:wrong_user) { FactoryGirl.create(:user, email: "[email protected]") }
                        before { sign_in user, no_capybara: true }

                        describe "visiting Users#edit page" do
                            before { visit edit_user_path(wrong_user) }
                            it { should_not have_title(full_title('Edit user')) }
                        end

                        describe "submitting a PATCH request to the User#update action" do
                            before { patch user_path(wrong_user) }
                            specify { expect(response).to redirect_to(root_url) }
                        end
                    end
                end
            end
        end
    end
  end
 end

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

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


  describe "with valid information" do
    before do
      fill_in "Name",  with: "Example User"
      fill_in "Email",with: "[email protected]"
      fill_in "Password",  with: "foobar"
      fill_in "Confirmation", with: "foobar"
    end

    it "should create a new 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: '[email protected]') }

      it { should have_title(user.name) }
      it { should have_selector('div.alert.alert-success', text: 'Welcome') }
    end

    it "should create a user" do
      expect { click_button submit }.to change(User, :count).by(1)
    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 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) { "[email protected]" }
        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
     end
  end
 end

I am particularly curious what "in 'block(7 levels)in" means. Are the levels something on that page or is it referring to something else? What is 'The block' in reference to?

I also cannot seem to understand the capybara error that I am getting. It appeared in chapter 8, went away and now has come back. The button is there on the page when I bring it up so capybara is just not finding it I guess. Can anyone explain how that works?

What does the 'nested" refer to?

Anyone know a good website that breaks this down? I would be more than happy to do the work myself but I could not find one. I would really love to be able to decipher this myself instead of just googling it and hoping the answer is somewhere or having to rely on someone else to explain it all the time.

Thanks so much for your time and any help.

2

2 Answers

1
votes

Now is the time on Stack Overflow when I oversimplify. (Google 'ruby block' to read a lot more on this.) A block in Ruby is a bunch of code that gets passed to a method like an argument. For example,

[1,2,3].each{|n| puts n * n }

each is the method (called on the array [1,2,3]), and everything in the brackets is the block. The way the method each works is, it takes every element in the enumerable it`s called on ([1,2,3]) and yields one element at a time to the code block:

|the first element is 1| puts 1 * 1
|next is 2| puts 2 * 2
|etc| puts 3 * 3

A block can also be written between do...end. The Ruby way is to use brackets if you can fit the block on one line, and do...end otherwise - which is just how you have it in your specs. Everywhere you have a do and a matching end in your specs is a block, nested one inside another. The methods are harder to notice, because RSpec makes it look like natural language, but every time you write describe or it at the start of a line is a method call. (So are let and before and subject and expect, for that matter, which get called with single line blocks in your specs.)

So the message 'block(7 levels)' means your error is nested in that many blocks:

describe "AuthenticationPages" do #starts the first block
  ...
  describe "signup" do #starts the second

and so on.

Now, your error messages. The first and second are basically telling you the same thing - you visit edit_user_path(user) and you don't see a "Sign In" button or "Sign In" in the page title. Check the log/test.log file - what happens when you visit that page? Is it a redirect to the signin page? It ought to be, but it looks like it isn't.

The other two error messages say exactly the same thing - the spec doesn't know what sign_in means. You need to have a method by that name defined somewhere RSpec can find it - either in the spec itself, or the spec_helper file that you require at the top of the spec, or in some file which is itself required inside spec_helper.

Finally, I think Hartl is right - you Google as best you can with error messages and stack traces, ask when you can't find what you're looking for, and you'll get better figuring things out yourself with time.

1
votes

Re: sign_in -- The sign_in function was added to spec/support/utilities.rb in section 9.1.1, Listing 9.6 (in Rails 4 version of book).

I got the same error because my function in utilities.rb was "signin" without the underscore. Once I added the underscore (and changed the other reference to the same function to match), the test went green.