Search code examples
ruby-on-railstestingtddminitest

How to update a boolean attribute in Rails using a patch request


I have a boolean attribute that I'm trying to test using Minitest in Rails. Here's the test in question:

test "admins can change a user's board member status" do
    patch user_path(@member, as: @admin), params: { user: { board_member: true } }
    assert_redirected_to(user_path(@member))
    assert_equal "Profile was successfully updated.", flash[:notice]
    assert_equal true, @member.board_member
end

I don't understand why that's not working. I'm able to set the board_member attribute to true in my fixtures, db seeds, manually in the browser, and also in a system test with Capybara.

I tried setting passing the user params to the patch request with to_json but that did not work either. I keep getting the same error as if the boolean attribute was not toggled to true:

 test_admins_can_change_a_user's_board_member_status#UsersControllerTest (1.28s)
   Expected: true
   Actual: false

Here's how I'm whitelisting my params in the user's controller:

def user_params
   # List of common params
   list_params_allowed = [:email, :profile_photo, :first_name, :last_name, :title, :organization, :street, :city, :state, :zip_code, :phone]
   # Add the params only for admin
   list_params_allowed += [:role, :board_member] if current_user.admin?

   params.require(:user).permit(list_params_allowed)
end

Again, this works as expected in the browser, but I want to test the params to ensure there is no security hole if you try to submit the "board_member" attribute through a url.


Solution

  • You need to reload @member in order for it to reflect the changes made by your app to the database.

    test "admins can change a user's board member status" do
      assert_changes -> { @member.board_member }, from: false, to: true do
        patch user_path(@member, as: @admin), params: { user: { board_member: true } }
        @member.reload # get changes performed by app to db
      end
      # consider extracting this into separate examples
      assert_redirected_to(user_path(@member))
      assert_equal "Profile was successfully updated.", flash[:notice]
    end