Files
clinch/test/jobs/passwords_mailer_test.rb

197 lines
5.6 KiB
Ruby

require "test_helper"
class PasswordsMailerTest < ActionMailer::TestCase
setup do
@user = users(:alice)
@reset_mail = PasswordsMailer.reset(@user)
end
test "should queue password reset email job" do
# Note: In test environment, deliver_later might not enqueue jobs the same way
# This test focuses on the mail delivery functionality
assert_nothing_raised do
PasswordsMailer.reset(@user).deliver_later
end
end
test "should deliver password reset email successfully" do
assert_emails 1 do
PasswordsMailer.reset(@user).deliver_now
end
end
test "should have correct email content" do
email = @reset_mail
assert_equal "Reset your password", email.subject
assert_equal [@user.email_address], email.to
assert_equal [], email.cc || []
assert_equal [], email.bcc || []
# From address is configured in ApplicationMailer
assert_not_nil email.from
assert email.from.is_a?(Array)
end
test "should include user data and reset token in email body" do
# Set a password reset token for testing
@user.generate_token_for(:password_reset)
@user.save!
email = PasswordsMailer.reset(@user)
email_body = email.body.encoded
# Should include user's email address
assert_includes email_body, @user.email_address
# Should include reset link structure
assert_includes email_body, "reset"
assert_includes email_body, "password"
# Use text_part to get readable content
email_text = email.text_part&.decoded || email.body.decoded
# Should include reset-related text
assert_includes email_text, "reset"
assert_includes email_text, "password"
end
test "should handle users with different statuses" do
# Test with active user
active_user = users(:bob)
assert active_user.status == "active"
assert_emails 1 do
PasswordsMailer.reset(active_user).deliver_now
end
# Test with disabled user (should still send reset if they request it)
active_user.status = :disabled
active_user.save!
assert_emails 1 do
PasswordsMailer.reset(active_user).deliver_now
end
end
test "should queue multiple password reset emails" do
users = [users(:alice), users(:bob)]
# Test that multiple deliveries don't raise errors
assert_nothing_raised do
users.each do |user|
user.generate_token_for(:password_reset)
PasswordsMailer.reset(user).deliver_later
end
end
# Test synchronous delivery to verify functionality
assert_emails 2 do
users.each do |user|
user.generate_token_for(:password_reset)
PasswordsMailer.reset(user).deliver_now
end
end
end
test "should handle user with reset token" do
# User should have a reset token for the email to be useful
assert_respond_to @user, :password_reset_token
# Generate token and test email content
@user.generate_token_for(:password_reset)
@user.save!
email = PasswordsMailer.reset(@user)
email_text = email.text_part&.decoded || email.body.decoded
assert_not_nil @user.password_reset_token
assert_includes email_text, "reset"
end
test "should handle expired reset tokens gracefully" do
# Test email generation even with expired tokens
@user.generate_token_for(:password_reset)
# Manually expire the token by updating its created_at time
@user.instance_variable_set(:@password_reset_token_created_at, 25.hours.ago)
# Email should still generate (validation happens elsewhere)
assert_emails 1 do
PasswordsMailer.reset(@user).deliver_now
end
end
test "should respect mailer configuration" do
# Test that the mailer inherits from ApplicationMailer properly
assert PasswordsMailer < ApplicationMailer
assert_respond_to PasswordsMailer, :default
end
test "should handle concurrent password reset deliveries" do
# Simulate concurrent password reset deliveries
users = User.limit(3)
# Test that multiple deliveries don't raise errors
assert_nothing_raised do
users.each do |user|
user.generate_token_for(:password_reset)
PasswordsMailer.reset(user).deliver_later
end
end
# Test synchronous delivery to verify functionality
assert_emails users.count do
users.each do |user|
user.generate_token_for(:password_reset)
PasswordsMailer.reset(user).deliver_now
end
end
end
test "should have proper email headers and security" do
email = @reset_mail
# Test common email headers
assert_not_nil email.message_id
assert_not_nil email.date
# Test content-type
if email.html_part
assert_includes email.content_type, "text/html"
elsif email.text_part
assert_includes email.content_type, "text/plain"
end
# Should not include sensitive data in headers
email.header.each do |key, value|
refute_includes value.to_s.downcase, "password"
refute_includes value.to_s.downcase, "token"
end
end
test "should handle users with different email formats" do
# Test with different email formats to ensure proper handling
test_emails = [
"user+tag@example.com",
"user.name@example.com",
"user@example.co.uk",
"123user@example.com"
]
test_emails.each do |email_address|
temp_user = User.new(
email_address: email_address,
password: "password123",
status: :active
)
temp_user.save!(validate: false) # Skip validation for testing
assert_emails 1 do
PasswordsMailer.reset(temp_user).deliver_now
end
email = PasswordsMailer.reset(temp_user)
assert_equal [email_address], email.to
end
end
end