我正在阅读Michael Hartl关于RoR 4.0的教程,目前正在进行第9章的第一次练习。
我应该编写一个测试,确认无法发出PATCH请求来编辑用户的 admin 属性。为防止批量分配,本教程引入了一个仅允许某些属性的 user_params 函数。
在测试中,我正在发行
patch user_path(user), params
其中 params 是包含 admin 的 true 值的哈希值(见下文)。在此请求之后,我希望用户的属性仍为 false 。
以下是问题
当测试(正确)成功使用我当前的代码时,当我将admin属性添加到 user_params 中的允许属性列表时,它也会(错误地)成功功能。
使用curl向/ users /:id发出PATCH请求会给出一个我还不太了解的错误页面。我已经尝试用PUT替换PATCH,已经阅读了某个地方,支持这种方法是相当新的,并且认为我可能没有为每个宝石提供正确的版本。我正在使用ruby 1.9.3,而本教程使用2.x。
这里有什么我想念的吗? (有关如何在rails控制台中模拟这些请求的任何提示也会有所帮助!)
我粘贴了我正在使用的代码的相关部分:
<小时/> 代码
的应用程序/控制器/ users_controller.rb
class UsersController < ApplicationController before_action :signed_in_user, only: [:edit, :update, :index, :destroy] before_action :correct_user, only: [:edit, :update] before_action :admin_user, only: :destroy ... def update @user = User.find(params[:id]) if @user.update_attributes(user_params) sign_in @user 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, :admin) end ...
规格/特征/ users_pages_spec.rb
...
describe "edit page" do
let(:user) { FactoryGirl.create(:user) }
before do
sign_in user
visit edit_user_path(user)
end
...
describe "directly patch forbidden admin attribute" do
let(:params) do
{ user: { admin: true, password: user.password, password_confirmation: user.password } }
end
before {
patch user_path(user), params
}
specify { expect(user.reload).not_to be_admin }
end
...
app / models / user.rb
class User < ActiveRecord::Base
before_save { email.downcase! }
before_create :create_remember_token
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false }
validates :password, length: { minimum: 6 }
has_secure_password
def User.new_remember_token
SecureRandom.urlsafe_base64
end
def User.encrypt(token)
Digest::SHA1.hexdigest(token.to_s)
end
private
def create_remember_token
self.remember_token = User.encrypt(User.new_remember_token)
end
end
答案 0 :(得分:3)
前几天我遇到了同样的问题。如日志所示
Redirected to http://www.example.com/signin
Filter chain halted as :signed_in_user rendered or redirected
Completed 302 Found in 3ms (ActiveRecord: 0.7ms)
未将测试变为红色的原因是由于用户控制器中定义的过滤器之前的signed_in_user。因此,登录用户会修复遇到的“让测试变为红/绿”问题。
describe "forbidden attributes" do
let(:params) do
{ user: { admin: true, password: user.password,
password_confirmation: user.password } }
end
before {
sign_in user, no_capybara: true
patch user_path(user), params
}
specify { expect(user.reload).not_to be_admin }
end
插入sign_in后,您的测试应该是红色/绿色,具体取决于控制器中定义的强参数。
希望有助于您入门。
最佳, 本。
P.S。:但是,我没有花费太多精力调查上述提到的before_filter为何得出用户未登录的结论......