diff --git a/app/interactors/send_password_reset_email.rb b/app/interactors/send_password_reset_email.rb index cd732d9..1f70a1e 100644 --- a/app/interactors/send_password_reset_email.rb +++ b/app/interactors/send_password_reset_email.rb @@ -1,6 +1,19 @@ -class SendPasswordResetEmail - include Interactor +class SendPasswordResetEmail < StandardInteraction + def validate_input + context.fail!(errors: "invalid input") unless valid_input + end + + def execute + context.fail!(errors: "delivery failed") unless send_reset_email + end + + private + + def send_reset_email + UserMailer.password_reset(context.user).deliver_now + end - def call + def valid_input + context.user && context.user.reset_digest && context.user.reset_token end end diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb new file mode 100644 index 0000000..08cdd55 --- /dev/null +++ b/app/mailers/user_mailer.rb @@ -0,0 +1,11 @@ +class UserMailer < ActionMailer::Base + default from: "admin@meetmeeples.com" + + def password_reset(user) + @user = user + @first_name = user.first_name + + mail(to: "#{@user.email}", + subject: "Meet Meeples Password Reset") + end +end diff --git a/app/models/user.rb b/app/models/user.rb index cd6fc3a..090a0fa 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,4 +1,6 @@ class User < ActiveRecord::Base + attr_accessor :reset_token + has_secure_password has_many :user_group_memberships diff --git a/app/views/user_mailer/password_reset.html.erb b/app/views/user_mailer/password_reset.html.erb new file mode 100644 index 0000000..cf389ec --- /dev/null +++ b/app/views/user_mailer/password_reset.html.erb @@ -0,0 +1,2 @@ +

Hi <%= @first_name %>,

+

Please click the link below to reset your password

diff --git a/spec/interactors/send_password_reset_email_spec.rb b/spec/interactors/send_password_reset_email_spec.rb new file mode 100644 index 0000000..288f250 --- /dev/null +++ b/spec/interactors/send_password_reset_email_spec.rb @@ -0,0 +1,73 @@ +RSpec.describe SendPasswordResetEmail do + describe ".call" do + let(:token) { Encryptor.generate_token } + + let(:user) do + create(:confirmed_user, reset_digest: token[0], + reset_token: token[1]) + end + + subject(:send_email) do + described_class.call(user: user) + end + + before do + ActionMailer::Base.deliveries.clear + end + + context "when successful" do + it "is a success" do + is_expected.to be_a_success + end + + it "sends an email" do + send_email + expect(ActionMailer::Base.deliveries.count).to eq(1) + end + end + + context "when user not provided" do + subject(:send_email) do + described_class.call(user: nil) + end + + it "fails" do + is_expected.to be_a_failure + end + + it "adds an error to errors" do + expect(subject.errors).to eq("invalid input") + end + end + + context "when user does not have a valid reset_digest" do + let(:user) do + create(:confirmed_user, reset_digest: nil, + reset_token: token[1]) + end + + it "fails" do + is_expected.to be_a_failure + end + + it "adds an error to errors" do + expect(subject.errors).to eq("invalid input") + end + end + + context "when user does not have a valid reset_token" do + let(:user) do + create(:confirmed_user, reset_digest: token[0], + reset_token: nil) + end + + it "fails" do + is_expected.to be_a_failure + end + + it "adds an error to errors" do + expect(subject.errors).to eq("invalid input") + end + end + end +end diff --git a/spec/mailers/user_mailer_spec.rb b/spec/mailers/user_mailer_spec.rb new file mode 100644 index 0000000..fb5ba69 --- /dev/null +++ b/spec/mailers/user_mailer_spec.rb @@ -0,0 +1,26 @@ +RSpec.describe UserMailer do + describe ".password_reset" do + let(:token) { Encryptor.generate_token } + let(:user) { create(:confirmed_user, reset_token: token[1]) } + + let(:mail) do + described_class.password_reset(user) + end + + it "sets the subject" do + expect(mail.subject).to eq("Meet Meeples Password Reset") + end + + it "sets the receiver email" do + expect(mail.to).to eq([user.email]) + end + + it "sets the sender email" do + expect(mail.from).to eq(["admin@meetmeeples.com"]) + end + + it "assigns @first_name" do + expect(mail.body.encoded).to match(user.first_name) + end + end +end