加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – RSpec与Cookies – 即使应用程序正常工作(模拟

发布时间:2020-12-17 02:31:29 所属栏目:百科 来源:网络整理
导读:我正在阅读Michael Hartl的“ Ruby on Rails”Turorial“但我被困 here. 我编写测试来检查用户编辑/更新的用户授权,我还编写了控制器代码,它的工作原理如下: 如果用户未登录并尝试访问用户#edit或用户#news,则会将其重定向到登录页面 如果用户已登录并且他
我正在阅读Michael Hartl的“ Ruby on Rails”Turorial“但我被困 here.

我编写测试来检查用户编辑/更新的用户授权,我还编写了控制器代码,它的工作原理如下:

>如果用户未登录并尝试访问用户#edit或用户#news,则会将其重定向到登录页面
>如果用户已登录并且他尝试编辑另一个用户,则会将其重定向到根目录

问题是在测试第2点的规范中,我检查发送PUT请求到user_path我被重定向到root但是运行rspec我得到以下错误:

Failures:

  1) Authentication authorization as wrong user submitting a PUT request to users#update 
     Failure/Error: specify { response.should redirect_to(root_url) }
       Expected response to be a redirect to <http://www.example.com/> but was a redirect to <http://www.example.com/signin>
     # ./spec/requests/authentication_pages_spec.rb:73:in `block (5 levels) in <top (required)>'

它似乎被重定向到signin_url而不是root_url,就像用户根本没有登录一样……这就是我猜测导致问题的原因.

应用程序在cookie中存储令牌以验证用户.
为了测试这个,我编写了一个名为signin_user(user)的辅助方法,并将其放在spec / support / utilities.rb文件中:

# spec/support/utilities.rb
def sign_in(user)
  visit signin_path
  fill_in "Email",with: user.email
  fill_in "Password",with: user.password
  click_button "Sign in"
  # Make signin work even when not using capybara (e.g. when using get,or post)
  cookies[:remember_token] = user.remember_token 
end

正如您所看到的那样,设置remember_token cookie以确保用户即使在使用put,delete等时也会被记录…或者至少它应该工作!

我怎样才能使这个规格通过呢?

# spec/requests/authentication_pages_spec.rb
require 'spec_helper'

describe "Authentication" do
  subject { page }

  # ...

  describe "authorization" do
    # ...

    describe "as wrong user" do
      let(:user) { FactoryGirl.create(:user) }
      let(:another_user) { FactoryGirl.create(:user,email: "another@example.com") }

      before { sign_in(user) }

      # ...

      describe "submitting a PUT request to users#update" do
        before { put user_path(another_user) } 

        specify { response.should redirect_to(root_url) }
      end
    end
  end
end

更新:这是我的UsersController:

class UsersController < ApplicationController
  before_filter :signed_in_user,:only => [:edit,:update]
  before_filter :correct_user,: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 the sample App!"
      redirect_to @user
    else
      render "new"
    end
  end

  def edit
  end

  def update   
    if @user.update_attributes(params[:user])
      sign_in(@user)
      flash[:success] = "Your profile was successfully updated"
      redirect_to @user
    else
      render "edit"
    end
  end

  private
    def signed_in_user
      unless signed_in?
        redirect_to signin_url,notice: "Please sign in to access this page."
      end
    end

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

解决方法

在查看github存储库中其余代码的帮助程序后,我认为我发现了问题.

您正在使用会话变量来存储:remember_token:

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

这本书使用cookies:

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

您的测试助手设置了cookie:

# Make signin work even when not using capybara (e.g. when using get,or post)
cookies[:remember_token] = user.remember_token

但是因为你的user_from_remember_token正在寻找会话[:remember_token]而不是cookie,它认为用户没有登录,所以测试被重定向到login_path而不是root_path.

它说他们为什么在这里使用cookie:http://ruby.railstutorial.org/chapters/sign-in-sign-out?version=3.2#sec:a_working_sign_in_method

如果您想继续使用会话,则需要调整测试以通过post登录,以便put具有会话集,例如:

describe "submitting a PUT request to users#update" do
    before do 
      post sessions_path,:email => user.email,:password => user.password
      put user_path(another_user)
    end
    specify { response.should redirect_to(root_url) }
  end

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读