我在调试Rails教程的Rspec代码时遇到问题。当我运行我的rspec代码时,我收到此错误:
1) Authentication authorization as non-admin user submitting a DELETE request to the Users#destroy action
Failure/Error: specify { expect(response).to 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>.
Expected "http://www.example.com/" to be === "http://www.example.com/signin".
# ./spec/requests/authentication_pages_spec.rb:106:in `block (5 levels) in <top (required)>'
2) Authentication authorization as wrong user submitting a GET request to the Users#edit action
Failure/Error: specify { expect(response).to 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>.
Expected "http://www.example.com/" to be === "http://www.example.com/signin".
# ./spec/requests/authentication_pages_spec.rb:90:in `block (5 levels) in <top (required)>'
3) Authentication authorization as wrong user submitting a PATCH request to the Users#update action
Failure/Error: specify { expect(response).to 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>.
Expected "http://www.example.com/" to be === "http://www.example.com/signin".
# ./spec/requests/authentication_pages_spec.rb:95:in `block (5 levels) in <top (required)>'
我的/spec/requests/authentication_pages_spec.rb的代码是:
require 'spec_helper'
describe "Authentication" 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_error_message('Invalid') }
describe "after visiting another page" do
before { click_link "Home" }
it { should_not have_error_message('Invalid') }
end
end
describe "with valid information" do
let(:user) { FactoryGirl.create(:user) }
before { sign_in user }
it { should have_title(user.name) }
it { should have_link('Users', href: users_path) }
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) { FactoryGirl.create(:user) }
describe "when attempting to visit a protected page" do
before do
visit edit_user_path(user)
valid_signin(user)
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 "visiting the user index" do
before { visit users_path }
it { should have_title('Sign in') }
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, no_capybara: true }
describe "submitting a GET request to the Users#edit action" do
before { get edit_user_path(wrong_user) }
specify { expect(response.body).not_to match(full_title('Edit user')) }
specify { expect(response).to redirect_to(root_url) }
end
describe "submitting a PATCH request to the Users#update action" do
before { patch user_path(wrong_user) }
specify { expect(response).to redirect_to(root_url) }
end
end
describe "as non-admin user" do
let(:user) { FactoryGirl.create(:user) }
let(:non_admin) { FactoryGirl.create(:user) }
before { sign_in non_admin, no_capybara: true }
describe "submitting a DELETE request to the Users#destroy action" do
before { delete user_path(user) }
specify { expect(response).to redirect_to(root_url) }
end
end
end
end
我的utilities.rb的代码是:
include ApplicationHelper
def valid_signin(user)
fill_in "Email", with: user.email
fill_in "Password", with: user.password
click_button "Sign in"
end
def sign_in(user, options={})
if options[:no_capybara]
# Sign in when not using Capybara.
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
fill_in "Password", with: user.password
click_button "Sign in"
end
end
def valid_user()
fill_in "Name", with: "Example User"
fill_in "Email", with: "user@example.com"
fill_in "Password", with: "foobar"
fill_in "Confirmation", with: "foobar"
end
RSpec::Matchers.define :have_error_message do |message|
match do |page|
expect(page).to have_selector('div.alert.alert-error', text: message)
end
end
当我运行rails服务器时,一切都运行良好。
有趣的是,当我在服务器上运行以及运行实际测试时,我的日志不同。在服务器上,以用户ID 2身份登录,我得到了:
Started GET "/users/1/edit" for 127.0.0.1 at 2013-12-31 21:28:31 -0800
Processing by UsersController#edit as HTML
Parameters: {"id"=>"1"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", "1"]]
Redirected to http://localhost:3000/
Filter chain halted as :correct_user rendered or redirected
Completed 302 Found in 4ms (ActiveRecord: 0.2ms)
在我的test.log文件中,我看到了:
Binary data inserted for `string` type on column `password_digest`
[1m[35mSQL (0.4ms)[0m INSERT INTO "users" ("created_at", "email", "name", "password_digest", "remember_token", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["created_at", Sat, 28 Dec 2013 18:50:19 UTC +00:00], ["email", "michael@example.com"], ["name", "Michael Hartl"], ["password_digest", "$2a$04$qTOUv775ioIiAdufscqASuTZBoJEafqvDzc/.FGqmFR30NzQPalLa"], ["remember_token", "698696f7cfbefa641e2b87450b57499b056932ff"], ["updated_at", Sat, 28 Dec 2013 18:50:19 UTC +00:00]]
[1m[36m (0.0ms)[0m [1mRELEASE SAVEPOINT active_record_1[0m
Started GET "/users/1/edit" for 127.0.0.1 at 2013-12-28 10:50:19 -0800
Processing by UsersController#edit as HTML
Parameters: {"id"=>"1"}
Redirected to http://www.example.com/signin
Filter chain halted as :signed_in_user rendered or redirected
Completed 302 Found in 1ms (ActiveRecord: 0.0ms)
编辑1:这是我的signed_in_user
代码:
private
def user_params
params.require(:user).permit(:admin, :name, :email, :password, :password_confirmation)
end
# Before filters
def signed_in_user
debugger
unless signed_in?
store_location
redirect_to signin_url, notice: "Please sign in."
end
end
def correct_user
@user = User.find(params[:id])
redirect_to root_path unless current_user?(@user)
end
def admin_user
redirect_to root_path unless current_user.admin?
end
def strict_signed_in_user
redirect_to root_url, notice: "You are already signed in." unless !signed_in?
end
Edit2 :使用debugger
我设法找到了一些错误:
F/Users/rasheedbustamam/Rails projects/sample_app/spec/support/utilities.rb:11
if options[:no_capybara]
[6, 15] in /Users/rasheedbustamam/Rails projects/sample_app/spec/support/utilities.rb
6 click_button "Sign in"
7 end
8
9 def sign_in(user, options={})
10 debugger
=> 11 if options[:no_capybara]
12 # Sign in when not using Capybara.
13 remember_token = User.new_remember_token
14 cookies[:remember_token] = remember_token
15 user.update_attribute(:remember_token, User.encrypt(remember_token))
(rdb:1) v l
self = #<RSpec::Core::ExampleGroup::Nested_1::Nested_3::Nested_2::Nested_2:0x00000109aeb1b8>
options = {:no_capybara=>true}
remember_token = nil
user = #<User:0x00000109af02f8>
值得注意的是,remember_token
是nil
这似乎是一个问题。
提前非常感谢!
答案 0 :(得分:1)
根据测试结果,您的signed_in_user
过滤器会导致重定向,表明登录失败。我建议通过您的控制器代码跟踪登录执行和/或在此处共享相关代码以供审核。
更新:作为评论主题的后续行动,Hartl教程已经被成千上万的用户使用和验证,而迈克尔升级偶尔会出现新版本的缺陷,一般而言,它非常准确而且你如果你小心翼翼地跟着它会好的。你不能做的一件事是混合和匹配本教程各种版本的软件。