RailsによるアジャイルWebアプリケーション開発
第14章 タスクI:ログイン
書籍にあるように、全てのテストに共通するbeforeの定義の仕方が分からなかったので、
Everyday Railsにあるように、LoginMacrosを定義して、各Controller Specでセットした。
ログイン画面ではform_tagではなくform_forを使うようにした。
- app/controllers/sessions_controller.rb
class SessionsController < ApplicationController skip_before_action :authorize def new @user = User.new end def create @user = User.find_by(name: user_params[:name]) if @user && @user.authenticate(user_params[:password]) session[:user_id] = @user.id redirect_to admin_url else redirect_to login_url, alert: "無効なユーザ/パスワードの組み合わせです" end end def destroy session[:user_id] = nil redirect_to store_url, notice: "ログアウト" end private def user_params params.require(:user).permit(:name, :password) end end
- app/views/sessions/new.html.haml
.depot_form - if alert %p#notice= alert = form_for @user, url: login_url do |f| %fieldset %legend ログインしてください .field = f.label :name, "名前:" = f.text_field :name .field = f.label :password, "パスワード:" = f.password_field :password .field = f.submit "ログイン"
- spec/support/login_macros.rb
module LoginMacros def login_as(user) session[:user_id] = user.id end def logout session.delete :user_id end end
- spec/controllers/users_controller_spec.rb
require 'rails_helper' RSpec.describe UsersController, type: :controller do before do login_as create(:user) end describe "POST create" do let(:user) { attributes_for(:user) } it "should create yser" do expect { post :create, user: user }.to change(User, :count).by(1) end it "redirects to users#index" do post :create, user: user expect(response).to redirect_to users_path end end describe "PATCH update" do before do @user = create(:user) end let(:update_user) { attributes_for(:user) } it "should update user" do patch :update, id: @user, user: update_user @user.reload expect(@user.name).to eq update_user[:name] end it "redirects to users#index" do patch :update, id: @user, user: update_user expect(response).to redirect_to users_path end end end
- spec/controllers/sessions_controller_spec.rb
require 'rails_helper' RSpec.describe SessionsController, :type => :controller do describe "GET new" do it "returns http success" do get :new expect(response).to have_http_status(:success) end end describe "GET create" do before do @user = create(:user) end context "with valid attributes" do it "should login" do post :create, user: { name: @user.name, password: @user.password } expect(response).to redirect_to admin_url expect(session[:user_id]).to eq @user.id end end context "with invalid attributes" do it "should fail login" do post :create, user: { name: @user.name, password: "miss" } expect(response).to redirect_to login_url end end end describe "GET destroy" do before do @user = create(:user) end it "should logout" do get :destroy expect(response).to redirect_to store_url end end end