RoR v3.2 Учебник - Застрял Глава 9.2.2 - PullRequest
4 голосов
/ 20 февраля 2012

введите код здесь Я пытаюсь завершить обучение Майкла Хартла по Ruby on Rails v3.2 и застрял на Глава 9.2.2 .

Ниже приводится сообщение об ошибке, которое я получаю, хотя после завершения этого раздела все мои тесты должны пройти:

sample_app mikael$ bundle exec rspec spec/
.................................................................F..

Failures:

  1) User pages edit with valid information 
     Failure/Error: it { should have_link('Sign out', :href => signout_path) }
       expected link "Sign out" to return something
     # ./spec/requests/user_pages_spec.rb:91:in `block (4 levels) in <top (required)>'

Finished in 2.42 seconds
68 examples, 1 failure

Failed examples:

rspec ./spec/requests/user_pages_spec.rb:91 # User pages edit with valid information 

Проблема в том, что после того, как вошедший в систему пользователь успешно обновляет свой профиль, он автоматически выходит из системы, что приводит к сбою редактирования с действительным информационным тестом, поскольку после обновления пользователь должен оставаться в системе и ссылка «Выйти» должна существовать.

Я прочесал это в поисках своей ошибки или того, где я не следовал учебнику правильно, но не могу найти решение.

Я могу сдать все свои тесты до окончания раздела 9.2.2.

Вот файлы, которые я обновил в главе 9 (включает раздел 9.2.2 и все предыдущие разделы):

спецификация / запросы / 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.flash.error', text: 'Invalid') }

      describe "after visiting another page" do
        before { click_link "Home" }
        it { should_not have_selector('div.flash.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('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
    end
  end

  describe "authorization" do

    describe "for non-signed-in users" do
      let(:user) { Factory(:user) }

      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 have_selector('title', text: 'Home') }
      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
end

спецификация / запросы / user_pages_spec.rb

require 'spec_helper'

describe "User pages" do

  subject { page }

  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 }

    describe "with invalid information" do
      it "should not create a user" do
        expect { click_button "Sign up" }.not_to change(User, :count)
        end
      end

    describe "error messages" do
      before { click_button "Sign up" }

       let(:error) { 'errors prohibited this user from being saved' }

       it { should have_selector('title', text: '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: "user@example.com"
        fill_in "Password",     with: "foobar"
        fill_in "Confirmation", with: "foobar"
      end

      describe "after saving the user" do
        before { click_button "Sign up" }
        let(:user) { User.find_by_email('user@example.com') }

        it { should have_selector('title', text: user.name) }
        it { should have_selector('div.flash.success', text: 'Welcome') }
        it { should have_link('Sign out') }
      end

    it "should create a user" do
        expect { click_button "Sign up" }.to change(User, :count).by(1)
      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_selector('h1',    text: "Edit user") }
      it { should have_selector('title', text: "Edit user") }
      it { should have_link('change', href: 'http://gravatar.com/emails') }
    end

    describe "with invalid information" do
      let(:error) { '1 error prohibited this user from being saved' }
      before { click_button "Update" }

      it { should have_content(error) }
    end

    describe "with valid information" do
      let(:user)      { FactoryGirl.create(:user) }
      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 "Confirmation", with: user.password
        click_button "Update"
      end

      it { should have_selector('title', text: new_name) }
      it { should have_selector('div.flash.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

приложение / контроллеры / users_controller.rb

class UsersController < ApplicationController
  before_filter :signed_in_user, only: [:edit, :update]
  before_filter :correct_user,   only: [:edit, :update]

  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 MK Rails!"
      redirect_to @user
    else
      render 'new'
    end
  end

  def edit
  end

  def update
    if @user.update_attributes(params[:user])
      flash[:success] = "Profile updated"
      redirect_to @user
    else
      render 'edit'
    end
  end

  private

      def signed_in_user
        redirect_to signin_path, notice: "Please sign in." unless signed_in?
      end

      def correct_user
        @user = User.find(params[:id])
        redirect_to(root_path) unless current_user?(@user)
      end
end

приложение / хелперы / sessions_helper.rb

module SessionsHelper

  def sign_in(user)
    cookies.permanent[:remember_token] = user.remember_token
    current_user = user
  end

  def signed_in?
    !current_user.nil?
  end

  def current_user=(user)
    @current_user = user
  end

  def current_user
    @current_user ||= user_from_remember_token
  end

  def current_user?(user)
    user == current_user
  end

  def sign_out
    cookies.delete(:remember_token)
  end

  private

    def user_from_remember_token
      remember_token = cookies[:remember_token]
      User.find_by_remember_token(remember_token) unless remember_token.nil?
    end
end

Спецификация / поддержка / utilities.rb

def full_title(page_title)
  base_title = "MK Rails"
  if page_title.empty?
    base_title
  else
    "#{base_title} | #{page_title}"
  end
end

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.flash.error', text: message)
  end
end

def sign_in(user)
  visit signin_path
  fill_in "Email",    with: user.email
  fill_in "Password", with: user.password
  click_button "Sign in"
  # Sign in when not using Capybara as well.
  cookies[:remember_token] = user.remember_token
end

Любая помощь в понимании проблемы очень ценится!

Ответы [ 2 ]

3 голосов
/ 20 февраля 2012

Вы можете просто автоматически войти в систему, когда они обновят свой профиль:

def update
  if @user.update_attributes(params[:user])
     sign_in @user
     flash[:success] = "Profile updated"
     redirect_to @user
  else
    render 'edit'
  end
end
0 голосов
/ 27 декабря 2013

Я полагаю, вам не хватает обновления для метода sign_in (user) в spec / support / utilities.rb в листинге 9.6:

def sign_in(user, options = {})
  if options[:nocapybara]
    remember_token = User.new_remember_token
    cookies[:remember_token] = remember_token
    user.update_attribute(:remember_token, User.encrypt(remember_token))
  else
    visit signin_path
    fill_in "Email",     with: user.email.upcase
    fill_in "Password",  with: user.password
    click_button "Sign in"
  end
end

Также отсутствуют обновления для метода с тем же именемв app / helpers / session_helper.rb, который вы найдете в листинге 8.2.3:

def sign_in(user)
  remember_token = User.new_remember_token
  cookies.permanent[:remember_token] = remember_token
  user.update_attribute(:remember_token, User.encrypt(remember_token))
  self.current_user = user
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...