Hartl Ruby on Rails tutorial 4 ch 10, users edit test fails

一世执手 提交于 2019-12-11 05:05:55

问题


I am practicing Ruby on Rails by trying to create a custom website based off of Hartl's tutorial. Things have been going well so far but I am getting an error in the users edit test "Successful edit with friendly forwarding" in which the user is not redirected back to the edit page after logging in. This is the error message I get:

FAIL["test_successful_edit_with_friendly_forwarding", UsersEditTest, 3.1409137547016144]
 test_successful_edit_with_friendly_forwarding#UsersEditTest (3.14s)
    Expected response to be a redirect to <http://www.example.com/users/787258272/edit> but was a redirect to <http://www.example.com/users/787258272>.
    Expected "http://www.example.com/users/787258272/edit" to be === "http://www.example.com/users/787258272".
    test/integration/users_edit_test.rb:23:in `block in <class:UsersEditTest>'

I feel like the solution is something really simple that I missed but I can't seem to figure out what it is.

Here is my users_controller:

class UsersController < ApplicationController
  before_action :logged_in_user, only: [:edit, :update]
  before_action :correct_user,   only: [:edit, :update]

  def show
    @user = User.find(params[:id])
  end

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
      log_in @user
      flash[:success] = "Account created, welcome to Amplifire Energetics!"
      redirect_to @user
    else
      render 'new'
    end
  end

  def edit
  end

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

  private

    def user_params
      params.require(:user).permit(:name, :email, :password,
                                   :password_confirmation)
    end

    # Before filters

    # Confirms a logged-in user.
    def logged_in_user
      unless logged_in?
        flash[:danger] = "Please log in."
        redirect_to login_url
      end
    end

    # Confirms the correct user.
    def correct_user
      @user = User.find(params[:id])
      redirect_to(root_url) unless current_user?(@user)
    end
end

Here is my sessions_controller:

class SessionsController < ApplicationController
  def new
  end

  def create
    # Finds user in databse by email
    @user = User.find_by(email: params[:session][:email].downcase)
    # Authenticates user based on password
    if @user && @user.authenticate(params[:session][:password])
      log_in @user
      params[:session][:remember_me] == '1' ? remember(@user) :    forget(@user)
      redirect_back_or @user
    else
      flash.now[:danger] = "Invalid email/password combination"
      render 'new'
    end
  end

  def destroy
    log_out if logged_in?
    redirect_to root_url
  end
end

Here is my sessions_helper

module SessionsHelper

    # Logs in user 
    def log_in(user)
        session[:user_id] = user.id
    end

    # Remebers user in persistent session
    def remember(user)
        user.remember
        cookies.permanent.signed[:user_id] = user.id
        cookies.permanent[:remember_token] = user.remember_token
    end

    # Returns true if the given user is the current user.
    def current_user?(user)
        user == current_user
    end

    # Returns current logged in user
    def current_user
        if (user_id = session[:user_id])
            @current_user ||= User.find_by(id: session[:user_id])
        elsif (user_id = cookies.signed[:user_id])
            user = User.find_by(id: user_id)
            if user && user.authenticated?(cookies[:remember_token])
                log_in user
                @current_user = user
            end
        end
    end

    # Returns true if user logged in
    def logged_in?
        !current_user.nil?
    end

    # Logs out user
    def log_out
        session.delete(:user_id)
        @current_user = nil
    end

    # Forgets a persistent session
    def forget(user)
        user.forget
        cookies.delete(:user_id)
        cookies.delete(:remember_token)
    end

    # Logs out current user
    def log_out
        forget(current_user)
        session.delete(:user_id)
        @current_user = nil
    end

    # Redirects to stored location (or to the default).
    def redirect_back_or(default)
        redirect_to(session[:forwarding_url] || default)
        session.delete(:forwarding_url)
    end

    # Stores the URL trying to be accessed.
    def store_location
        session[:forwarding_url] = request.original_url if request.get?
    end

end

Here is my routes file:

Rails.application.routes.draw do

  get 'sessions/new'

  get 'users/new'

  root 'static_pages#home'
  get '/help',            to: 'static_pages#help'
  get '/about',           to: 'static_pages#about'
  get '/contact',         to: 'static_pages#contact'
  get '/signup',          to: 'users#new'
  post '/signup',         to: 'users#create'
  get '/login',           to: 'sessions#new'
  post '/login',          to: 'sessions#create'
  delete '/logout',       to: 'sessions#destroy'
  resources :users
end

Here is my users.yml file:

example: 
    name: Lil Wayne
    email: wheezy@youngmoney.com
    password_digest: <%= User.digest('password') %>
    admin: true

archer: 
    name: Sterling Archer
    email: dutchess@isis.gov
    password_digest: <%= User.digest('password') %>
    admin: false

Here is my user model file:

class User < ApplicationRecord
    attr_accessor :remember_token
    before_save :downcase_email
    validates :name,  presence: true, length: { maximum: 50 }
    EMAIL_REGEX = /\A([\w+\-].?)+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i
    validates :email, presence: true, length: { maximum: 245 },
                      format: { with: EMAIL_REGEX },
                      uniqueness: { case_sensitive: false }
    has_secure_password 
    validates :password, presence: true, length: { minimum: 6 }, allow_nil: true

    class << self
        # Returns hash digest of given string
        def digest(s)
            cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
                                                        BCrypt::Engine.cost
            BCrypt::Password.create(s, cost: cost)
        end

        # Returns random token
        def new_token
            SecureRandom.urlsafe_base64
        end
    end

    # Remembers user in database for persistent sessions
    def remember
        self.remember_token = User.new_token
        update_attribute(:remember_digest, User.digest(remember_token))
    end

    def authenticated?(remember_token)
        return false if remember_digest.nil?
        BCrypt::Password.new(remember_digest).is_password?(remember_token)
    end

    # Forgets a user
    def forget
        update_attribute(:remember_digest, nil)
    end

    private 

        def downcase_email
            self.email = email.downcase
        end
end

And here is my users_edit_test:

require 'test_helper'

class UsersEditTest < ActionDispatch::IntegrationTest

  def setup
    @user = users(:example)
  end

  test "unsuccessful edit" do
    log_in_as(@user)
    get edit_user_path(@user)
    assert_template 'users/edit'
    patch user_path(@user), params: { user: { name:  "",
                                              email: "foo@invalid",
                                              password:              "foo",
                                              password_confirmation: "bar" } }
    assert_template 'users/edit'
  end

  test "successful edit with friendly forwarding" do
    get edit_user_path(@user)
    log_in_as(@user)
    assert_redirected_to edit_user_path(@user)
    name  = "Foo Bar"
    email = "foo@bar.com"
    patch user_path(@user), params: { user: { name:  name,
                                              email: email,
                                              password:              "",
                                              password_confirmation: "" } }
    assert_not flash.empty?
    assert_redirected_to @user
    @user.reload
    assert_equal name,  @user.name 
    assert_equal email, @user.email
  end

end

回答1:


I found out what my problem was, I forgot to add the store_location method to the logged_in_user method in the users_controller.



来源:https://stackoverflow.com/questions/39647760/hartl-ruby-on-rails-tutorial-4-ch-10-users-edit-test-fails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!