Michael Hartl book Rails v 4.0 の第 9.6 章の問題 6 を解決しようとしています。
rspec テストではすべて問題ないように見えますが:
describe "should redirect a logged in user to root url if user tries to hit new in users controller" do
let(:user) {FactoryGirl.create(:user)}
before do
sign_in user
get new_user_path
end
specify{expect(response).to redirect_to(root_url)}
end
describe "should redirect a logged in user to root url if user tries to hit create in users controller" do
let(:params) do {user: {name: "Tester", email: "test@example.com", password: "password",
password_confirmation: "password"}}
end
let(:user) {FactoryGirl.create(:user)}
before do
sign_in user
post users_path, params
end
specify{expect(response).to redirect_to(root_url)}
end
そして、ここに私のコントローラースニペットがあります:
class UsersController < ApplicationController
before_action :is_signed_in, only: [:new, :create]
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
sign_in @user
flash[:success] = "Welcome to the Sample App!"
redirect_to @user
else
render 'new'
end
end
private
def is_signed_in
redirect_to(root_url) if signed_in?
end
end
utility.rb の sign_in メソッド
def sign_in(user, options = {})
if options[:no_capybara]
# Signin 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
しかし、私のテストケースは次のエラーで失敗しています:
Failures:
1) Authentication signin with valid information should redirect a logged in user to root url if user tries to hit create in users controller
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/users/2>.
Expected "http://www.example.com/" to be === "http://www.example.com/users/2".
# ./spec/requests/authentication_pages_spec.rb:69:in `block (5 levels) in <top (required)>'
2) Authentication signin with valid information should redirect a logged in user to root url if user tries to hit new in users controller
Failure/Error: specify{expect(response).to redirect_to(root_url)}
Expected response to be a <redirect>, but was <200>
# ./spec/requests/authentication_pages_spec.rb:55:in `block (5 levels) in <top (required)>'
Finished in 5.22 seconds
95 examples, 2 failures
Failed examples:
rspec ./spec/requests/authentication_pages_spec.rb:69 # Authentication signin with valid information should redirect a logged in user to root url if user tries to hit create in users controller
rspec ./spec/requests/authentication_pages_spec.rb:55 # Authentication signin with valid information should redirect a logged in user to root url if user tries to hit new in users controller
Randomized with seed 58509
デバッグしようとしましたが、正確な問題を把握できませんでした。誰でもこれについて私を助けることができますか?
編集: 1: route.rb Routes.rb を追加
SampleApp::Application.routes.draw do
resources :users
resources :sessions, only: [:new, :create, :destroy]
root "static_pages#home"
match '/help', to: "static_pages#help", via: 'get'
match '/about', to: "static_pages#about", via: 'get'
match '/contact', to: "static_pages#contact", via: 'get'
match '/signup', to: "users#new", via: 'get'
match '/signin', to: "sessions#new", via: 'get'
match '/signout', to: "sessions#destroy", via: 'delete'
end
EDIT 2 カピバラでテストしています。
Gemfile
group :test do
gem 'selenium-webdriver', '2.35.1'
gem 'capybara', '2.1.0'
gem 'growl', '1.0.3'
gem 'factory_girl_rails', '4.2.1'
gem 'database_cleaner', '<1.1.0'
gem "launchy", "2.3.0"
gem 'cucumber-rails', '1.4.0', :require => false
end
session_helper.rb
module SessionsHelper
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
def current_user=(user)
@current_user = user
end
def current_user
remember_token = User.encrypt(cookies[:remember_token])
@current_user ||= User.find_by(remember_token: remember_token)
end
def signed_in?
!current_user.nil?
end
def sign_out
self.current_user = nil
cookies.delete(:remember_token)
end
def current_user?(user)
current_user == user
end
def store_location
session[:return_to] = request.url if request.get?
end
def redirect_back_or(default)
redirect_to(session[:return_to] || default)
session.delete(:return_to)
end
def signed_in_user
unless signed_in?
store_location
redirect_to signin_url, notice: "Please sign in."
end
end
end