Railstutorial.org Michael Hartl Chapter 9 Exercise 3 "Should not allow the admin attribute to be edited over the Internet"

I started learning Rails and I got stuck in the third exercise of the 9th chapter.

the exercise looks like this:

  test "should not allow the admin attribute to be edited via the web" do
    log_in_as(@other_user)
    assert_not @other_user.admin?
    patch :update, id: @other_user, user: { password:              FILL_IN,
                                            password_confirmation: FILL_IN,
                                            admin: FILL_IN }
    assert_not @other_user.FILL_IN.admin?
  end

      

My problem is last Fill_IN >> assert_not @other_user.FILL_IN.admin

?

@other_user

is taken from Fixture and looks like this:

archer:
  name: Sterling Archer
  email: duchess@example.gov
  password_digest: <%= User.digest('password') %>

      

Update action

as follows:

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

      

I also added :admin

to user_params so that it :admin param

can be changed:

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

      

The answer I thought was correct was:

  test "should not allow the admin attribute to be edited via the web" do
    log_in_as(@other_user)
    assert_not @other_user.admin?
    patch :update, id: @other_user, user: { password:              @other_user.password,
                                            password_confirmation: @other_user.password_confirmation,
                                            admin: true }
    assert_not @other_user.admin?
  end

      

But it looks like @other_user doesn't change, so I think the mistake is in the last statement.

My answer is wrong, I cannot get this test to fail because in the last statement "assert_not @other_user.FILL_IN.admin?"

I don't know what to add to the FILL_IN section. I tried to disable FILL_IN, but it doesn't work.

+3


source to share


3 answers


You have to reload the instance variable after making changes to the base record. This will load in new changes.



assert_not @other_user.reload.admin?

      

+19


source


Currently, with 4th edition of the tutorial, using Rails 5.0.0, my answer is:

test "should not allow the admin attribute to be edited via the web" do
  log_in_as(@other_user)
  assert_not @other_user.admin?
  patch user_path(@other_user), params: {
                                  user: { password:              "",
                                          password_confirmation: "",
                                          admin: true } }
  assert_not @other_user.reload.admin?
end

      



The password and password_confirmation fields can be empty, imho; as shown in another example, Listing 10.11 (Rails 5 edition).

+3


source


One more thing about your code - I am also working on a Hartl tutorial, and I think if your password in the prompt is PATCH

set to @other_user.password

(as well as confirm the password), then your test will be green even if :user

allowed in user_params

, and the test should actually be red at this point.

This is because it has no attribute :archer

in your file ; it only has , and you cannot revoke the password after hashing it like you can.users.yml

:password

password_digest: <%= User.digest('password') %>

Just change the entries to

{ password: 'password', password_confirmation: 'password' ... }

      

and tests should verify correctness.

0


source







All Articles