Capybara's click_link and Rails controller actions - test is passing when it should not?

StackOverflow https://stackoverflow.com/questions/23285257

  •  09-07-2023
  •  | 
  •  

Question

I am writing Capybara integration tests for my engine while developing.

I have an integration test to check that an account owner can actually delete a user. It uses the 'destroy' action of an Users Controller.

To my understanding, Capybara's default driver will do a GET when you click a link when you don't use a driver with javascript enabled so the 'destroy' action should not actually be called and the test should fail. In fact, I haven't even included the default rails javascripts at all yet.

However, my Capybara test which presses the delete link actually passes the test even though it fails as expected when I open a Chrome browser window and do the sequence manually.

User code:

View: show.html.slim

h2 User

= @user.to_yaml

= link_to 'Edit User',  edit_user_path(@user) if policy(@user).edit?
br
= link_to 'Delete User',  user_path(@user), method: :delete if policy(@user).destroy?

Controller: users_controller.rb

module Subscribe
  class Account::UsersController < Account::BaseController
    def index
      @users  = current_account.users
    end

    def show
      @user = current_account.users.find_by(id: params[:id])
      authorize @user
    end

    def new
      @user = User.new
      @user.account_id = current_account.id # required for authorize
      authorize @user
    end

    def edit
      @user = current_account.users.find_by(id: params[:id])
      authorize @user
    end

    def update
      @user = current_account.users.find_by(id: params[:id])
      authorize @user

      do_new_sign_in = (current_user == @user)

      if @user.update_attributes(user_params)
        sign_in(@user, bypass: true) if  do_new_sign_in

        flash[:success] = "Update successful."
        redirect_to @user
      else
        render 'edit'
      end
    end

    def create
      @user = User.new(user_params)
      @user.account_id = current_account.id
      authorize @user

      if @user.save
        flash[:success] = "User successfully added."
        redirect_to users_path
      else
        flash.now["Sorry, could not create a new user. Please review the error messages."]
        render :new
      end
    end

    def destroy
      @user = current_account.users.find_by(id: params[:id])
      authorize @user

      @user.destroy
      flash[:success] = "User successfully deleted."
      redirect_to users_path

    end

    private

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

Test: spec/features/users/sign_up_authorization.rb

scenario "Can delete user" do
    click_link "#{user1.email}"

    click_link "Delete User"

    success_message = "User successfully eleted."
    expect(page).to have_content(success_message)
end
Was it helpful?

Solution

Because these links are so common, the rack test driver has code (see source) to detect this and follow the link with the correct method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top