Files
sanasto-wiki/test/controllers/password_resets_controller_test.rb

197 lines
5.6 KiB
Ruby

require "test_helper"
class PasswordResetsControllerTest < ActionDispatch::IntegrationTest
setup do
@user = users(:admin_user)
@user.update!(invitation_accepted_at: Time.current)
end
# NEW tests
test "should get new" do
get new_password_reset_url
assert_response :success
end
test "should show password reset form" do
get new_password_reset_url
assert_select "form"
assert_select "input[type=email]"
end
# CREATE tests
test "should send reset email for existing user" do
assert_enqueued_emails 1 do
post password_resets_url, params: { email: @user.email }
end
assert_redirected_to login_url
assert_match /password reset instructions/i, flash[:notice]
end
test "should generate reset token for existing user" do
post password_resets_url, params: { email: @user.email }
@user.reload
assert_not_nil @user.reset_password_token
assert_not_nil @user.reset_password_sent_at
end
test "should handle non-existent email gracefully" do
post password_resets_url, params: { email: "nonexistent@example.com" }
assert_redirected_to login_url
assert_match /if that email address is in our system/i, flash[:notice]
end
test "should send invitation for user without accepted invitation" do
pending_user = users(:pending_invitation)
assert_nil pending_user.invitation_accepted_at
assert_enqueued_emails 1 do
post password_resets_url, params: { email: pending_user.email }
end
assert_redirected_to login_url
end
test "should handle blank email" do
post password_resets_url, params: { email: "" }
assert_redirected_to login_url
end
test "should handle email with whitespace" do
post password_resets_url, params: { email: " #{@user.email} " }
@user.reload
assert_not_nil @user.reset_password_token
end
# EDIT tests
test "should show reset password form with valid token" do
@user.update!(
reset_password_token: SecureRandom.urlsafe_base64(32),
reset_password_sent_at: Time.current
)
get edit_password_reset_url(@user.reset_password_token)
assert_response :success
assert_select "form"
assert_select "input[type=password]", count: 2
end
test "should reject invalid token" do
get edit_password_reset_url("invalid_token")
assert_redirected_to login_url
assert_match /invalid/i, flash[:alert]
end
test "should reject expired token" do
@user.update!(
reset_password_token: SecureRandom.urlsafe_base64(32),
reset_password_sent_at: 2.hours.ago
)
get edit_password_reset_url(@user.reset_password_token)
assert_redirected_to new_password_reset_url
assert_match /expired/i, flash[:alert]
end
# UPDATE tests
test "should reset password with valid token" do
@user.update!(
reset_password_token: SecureRandom.urlsafe_base64(32),
reset_password_sent_at: Time.current
)
patch password_reset_url(@user.reset_password_token), params: {
password: "newpassword12345",
password_confirmation: "newpassword12345"
}
assert_redirected_to root_url
assert_match /password has been reset/i, flash[:notice]
@user.reload
assert_nil @user.reset_password_token
assert_nil @user.reset_password_sent_at
assert @user.authenticate("newpassword12345")
end
test "should auto-login after successful password reset" do
@user.update!(
reset_password_token: SecureRandom.urlsafe_base64(32),
reset_password_sent_at: Time.current
)
patch password_reset_url(@user.reset_password_token), params: {
password: "newpassword12345",
password_confirmation: "newpassword12345"
}
assert_equal @user.id, session[:user_id]
end
test "should reject mismatched passwords" do
@user.update!(
reset_password_token: SecureRandom.urlsafe_base64(32),
reset_password_sent_at: Time.current
)
patch password_reset_url(@user.reset_password_token), params: {
password: "newpassword12345",
password_confirmation: "differentpassword"
}
assert_response :unprocessable_entity
assert_match /doesn't match/i, flash[:alert]
end
test "should reject blank password" do
@user.update!(
reset_password_token: SecureRandom.urlsafe_base64(32),
reset_password_sent_at: Time.current
)
patch password_reset_url(@user.reset_password_token), params: {
password: "",
password_confirmation: ""
}
assert_response :unprocessable_entity
assert_match /cannot be blank/i, flash[:alert]
end
test "should reject expired token on update" do
@user.update!(
reset_password_token: SecureRandom.urlsafe_base64(32),
reset_password_sent_at: 2.hours.ago
)
patch password_reset_url(@user.reset_password_token), params: {
password: "newpassword12345",
password_confirmation: "newpassword12345"
}
assert_redirected_to new_password_reset_url
assert_match /expired/i, flash[:alert]
end
test "should reject invalid token on update" do
patch password_reset_url("invalid_token"), params: {
password: "newpassword12345",
password_confirmation: "newpassword12345"
}
assert_redirected_to login_url
assert_match /invalid/i, flash[:alert]
end
test "should enforce password validations" do
@user.update!(
reset_password_token: SecureRandom.urlsafe_base64(32),
reset_password_sent_at: Time.current
)
# Password too short (less than 12 characters)
patch password_reset_url(@user.reset_password_token), params: {
password: "short",
password_confirmation: "short"
}
assert_response :unprocessable_entity
end
end