jeudi 23 juillet 2015

Why is my integration test failing while application works?

I have this integration test that controls that a logged in user can't edit another user's data. The code is mostly from Hartl's RoR tutorial. Those 2 tests fail but when I test myself, the application is behaving as expected (I can't open the edit page of another user)

users_controller_test.rb

require 'test_helper'

class UsersControllerTest < ActionController::TestCase

    def setup
        @user = users(:guillaume)
        @other_user = users(:peter)
    end

    ## other tests ##

  test "should redirect edit when logged in as wrong user" do 
    log_in_as(@other_user)
    get :edit, id: @user 
    assert flash.empty?
    assert_redirected_to root_url
  end

  test "should redirect update when logged in as wrong user" do 
    log_in_as(@other_user)
    patch :update, id: @user, user: {name: @user.name, email: @user.email}
    assert flash.empty?
    assert_redirected_to root_url
  end

the lines that fail are the assert and assert_redirect lines

test_helper.rb

ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
require 'minitest/reporters'
Minitest::Reporters.use!

class ActiveSupport::TestCase
  # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
  fixtures :all

  # Returns true if a test user is logged in
  def is_logged_in?
    !session[:user_id].nil?
  end

  # Logs in a test user
  def log_in_as(user, options = {})
    password = options[:password]   ||  'password'
    if integration_test?
        post login_path, session: {email: user.email,
                                   password: password}
    else
        session[:user] = user.id 
    end
  end

  private

  # Return true inside an integration test
  def integration_test?
    defined?(post_via_redirect)
  end

end

users_controller.rb

class UsersController < ApplicationController

    before_action :logged_in_user,  only: [:edit, :update]
    before_action :correct_user,    only: [:edit, :update]

    ## new and create methods here ##

    def edit
        @user = User.find(params[:id])
    end

    def update
        if @user.update_attributes(user_params)
            flash[:success] = "Profile updated"
            redirect_to @user
        else
            render 'edit'
        end
    end

    private

        def user_params
            params.require(:user).permit(:name, 
                                         :email,
                                         :club_id,
                                         :access_key, 
                                         :password,
                                         :password_confirmation)
        end

        ## Before filters ##

        # Confirms a logged-in user
        def logged_in_user
            unless logged_in?
                flash[:danger] = "Please log in."
                redirect_to login_url
            end
        end

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

users.yml

guillaume:
    name: Guillaume
    email: guillaume@example.com
    password_digest: <%= User.digest('password') %>

peter:
    name: Peter
    email: peter@example.com
    password_digest: <%= User.digest('password') %>

I went though the code several times but I can't find what's missing. This is also the first app I'm trying to develop on my own, so for this part, I'm working from Hartl's rails tutorial material.

Aucun commentaire:

Enregistrer un commentaire