Reputation: 131
I am using Rails 5.2, Ruby 2.4.1, and Rspec. I am trying to make an automation test using Rspec to update a User's password. I know the code works from manually testing.
The RSpec test does not pass the @user.update_attributes(user_params) condition in the controller and then goes to the else condition. Thus, my RSpec test says that the passwords are still equal to each other. How can I get my RSpec test to pass the condition?
Here is the method
# Creates user, saves old password, generates a url for user to go to, updates password, reloads user, and test if old password equals new password
context "with a valid token" do
it "updates the user's password and resets the token" do
test_users = User.create(first_name: 'chase', last_name: 'dougherty', email: '[email protected]', password: '1', password_confirmation: '1')
old_password = test_users.password
test_users.generate_password_reset_token!
patch :update, params: { id: test_users.password_reset_token, user: { password: 'newpassword', password_confirmation: 'newpassword' } }
test_users.reload
expect(test_users.password).to_not eq(old_password)
end
end
Here is the Controller
# Finds user, test if update_attributes is true, updates password, logs user in, redirects user, displays flash
def update
@user = User.find_by(password_reset_token: params[:id])
if @user && @user.update_attributes(user_params)
@user.update_attribute(:password_reset_token, nil)
session[:user_id] = @user.id
redirect_to '/maps'
flash[:notice] = "Password updated"
else
flash[:notice] = "Password reset failure."
render action: 'edit'
end
end
private
def user_params
params.require(:user).permit(:password, :password_confirmation)
end
Upvotes: 2
Views: 1078
Reputation: 1907
If you use has_secure_password
method in your user
model, you can use this syntax for check password has been changed:
it "changes user's password" do
expect { send_request }.to change { user.reload.authenticate(password) }.from(false).to(user)
end
Upvotes: 2
Reputation: 250
If the update_attributes line is failing, you probably have some validations on the User model that are firing and causing it to return false.
Also, I would advise against "creating" a user object in the test files. Especially because the first time you run the tests it will create the entry, but then every time after that it will return a User instance that is not saved to the database (because of uniqueness violations in the data) and the tests may not run as expected.
Unless you want to clean up your created user objects after the test runs. Otherwise you will want to use factory_bot and stub out most of these models and the database calls.
Upvotes: 1