diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 0000000..1c44dd0 --- /dev/null +++ b/.tool-versions @@ -0,0 +1 @@ +ruby 2.6.6 diff --git a/app/mailers/rails_jwt_auth/mailer.rb b/app/mailers/rails_jwt_auth/mailer.rb index 6969e1b..014d3b3 100644 --- a/app/mailers/rails_jwt_auth/mailer.rb +++ b/app/mailers/rails_jwt_auth/mailer.rb @@ -2,9 +2,13 @@ class RailsJwtAuth::Mailer < ApplicationMailer default from: RailsJwtAuth.mailer_sender - def confirmation_instructions(user) + before_action do + @user = RailsJwtAuth.model.find(params[:user_id]) + @subject = I18n.t("rails_jwt_auth.mailer.#{action_name}.subject") + end + + def confirmation_instructions raise RailsJwtAuth::NotConfirmationsUrl unless RailsJwtAuth.confirmations_url.present? - @user = user @confirmations_url = add_param_to_url( RailsJwtAuth.confirmations_url, @@ -12,19 +16,15 @@ def confirmation_instructions(user) @user.confirmation_token ) - subject = I18n.t('rails_jwt_auth.mailer.confirmation_instructions.subject') - mail(to: @user.unconfirmed_email || @user[RailsJwtAuth.email_field_name], subject: subject) + mail(to: @user.unconfirmed_email || @user[RailsJwtAuth.email_field_name], subject: @subject) end - def email_changed(user) - @user = user - subject = I18n.t('rails_jwt_auth.mailer.email_changed.subject') - mail(to: @user[RailsJwtAuth.email_field_name!], subject: subject) + def email_changed + mail(to: @user[RailsJwtAuth.email_field_name!], subject: @subject) end - def reset_password_instructions(user) + def reset_password_instructions raise RailsJwtAuth::NotResetPasswordsUrl unless RailsJwtAuth.reset_passwords_url.present? - @user = user @reset_passwords_url = add_param_to_url( RailsJwtAuth.reset_passwords_url, @@ -32,13 +32,11 @@ def reset_password_instructions(user) @user.reset_password_token ) - subject = I18n.t('rails_jwt_auth.mailer.reset_password_instructions.subject') - mail(to: @user[RailsJwtAuth.email_field_name], subject: subject) + mail(to: @user[RailsJwtAuth.email_field_name], subject: @subject) end - def set_password_instructions(user) + def set_password_instructions raise RailsJwtAuth::NotSetPasswordsUrl unless RailsJwtAuth.set_passwords_url.present? - @user = user @reset_passwords_url = add_param_to_url( RailsJwtAuth.set_passwords_url, @@ -46,13 +44,11 @@ def set_password_instructions(user) @user.reset_password_token ) - subject = I18n.t('rails_jwt_auth.mailer.set_password_instructions.subject') - mail(to: @user[RailsJwtAuth.email_field_name], subject: subject) + mail(to: @user[RailsJwtAuth.email_field_name], subject: @subject) end - def send_invitation(user) + def send_invitation raise RailsJwtAuth::NotInvitationsUrl unless RailsJwtAuth.invitations_url.present? - @user = user @invitations_url = add_param_to_url( RailsJwtAuth.invitations_url, @@ -60,17 +56,13 @@ def send_invitation(user) @user.invitation_token ) - subject = I18n.t('rails_jwt_auth.mailer.send_invitation.subject') - mail(to: @user[RailsJwtAuth.email_field_name], subject: subject) + mail(to: @user[RailsJwtAuth.email_field_name], subject: @subject) end - def send_unlock_instructions(user) - @user = user - subject = I18n.t('rails_jwt_auth.mailer.send_unlock_instructions.subject') - + def send_unlock_instructions @unlock_url = add_param_to_url(RailsJwtAuth.unlock_url, 'unlock_token', @user.unlock_token) - mail(to: @user[RailsJwtAuth.email_field_name], subject: subject) + mail(to: @user[RailsJwtAuth.email_field_name], subject: @subject) end protected diff --git a/app/models/concerns/rails_jwt_auth/confirmable.rb b/app/models/concerns/rails_jwt_auth/confirmable.rb index 0cefba1..765f059 100644 --- a/app/models/concerns/rails_jwt_auth/confirmable.rb +++ b/app/models/concerns/rails_jwt_auth/confirmable.rb @@ -34,12 +34,10 @@ def self.included(base) self.confirmation_token = SecureRandom.base58(24) self.confirmation_sent_at = Time.current - mailer = Mailer.confirmation_instructions(self) - RailsJwtAuth.deliver_later ? mailer.deliver_later : mailer.deliver + RailsJwtAuth.send_email(:confirmation_instructions, self) if RailsJwtAuth.send_email_changed_notification - mailer = Mailer.email_changed(self) - RailsJwtAuth.deliver_later ? mailer.deliver_later : mailer.deliver + RailsJwtAuth.send_email(:email_changed, self) end end end @@ -58,8 +56,7 @@ def send_confirmation_instructions self.confirmation_sent_at = Time.current return false unless save - mailer = Mailer.confirmation_instructions(self) - RailsJwtAuth.deliver_later ? mailer.deliver_later : mailer.deliver + RailsJwtAuth.send_email(:confirmation_instructions, self) true end diff --git a/app/models/concerns/rails_jwt_auth/invitable.rb b/app/models/concerns/rails_jwt_auth/invitable.rb index 4faf9c1..4abc451 100644 --- a/app/models/concerns/rails_jwt_auth/invitable.rb +++ b/app/models/concerns/rails_jwt_auth/invitable.rb @@ -112,9 +112,8 @@ def generate_invitation_token end def send_invitation_mail - RailsJwtAuth.email_field_name! # ensure email field es valid - mailer = Mailer.send_invitation(self) - RailsJwtAuth.deliver_later ? mailer.deliver_later : mailer.deliver + RailsJwtAuth.email_field_name! # ensure email field is valid + RailsJwtAuth.send_email(:send_invitation, self) end def invitation_period_valid? diff --git a/app/models/concerns/rails_jwt_auth/lockable.rb b/app/models/concerns/rails_jwt_auth/lockable.rb index 43162aa..a0c0cb6 100644 --- a/app/models/concerns/rails_jwt_auth/lockable.rb +++ b/app/models/concerns/rails_jwt_auth/lockable.rb @@ -68,8 +68,7 @@ def send_unlock_instructions self.unlock_token = SecureRandom.base58(24) save(validate: false) - mailer = Mailer.send_unlock_instructions(self) - RailsJwtAuth.deliver_later ? mailer.deliver_later : mailer.deliver + RailsJwtAuth.send_email(:send_unlock_instructions, self) end def access_locked? diff --git a/app/models/concerns/rails_jwt_auth/recoverable.rb b/app/models/concerns/rails_jwt_auth/recoverable.rb index 903c38d..319fdcc 100644 --- a/app/models/concerns/rails_jwt_auth/recoverable.rb +++ b/app/models/concerns/rails_jwt_auth/recoverable.rb @@ -40,8 +40,7 @@ def send_reset_password_instructions self.reset_password_sent_at = Time.current return false unless save - mailer = Mailer.reset_password_instructions(self) - RailsJwtAuth.deliver_later ? mailer.deliver_later : mailer.deliver + RailsJwtAuth.send_email(:reset_password_instructions, self) end def set_and_send_password_instructions @@ -56,8 +55,7 @@ def set_and_send_password_instructions self.reset_password_sent_at = Time.current return false unless save - mailer = Mailer.set_password_instructions(self) - RailsJwtAuth.deliver_later ? mailer.deliver_later : mailer.deliver + RailsJwtAuth.send_email(:set_password_instructions, self) true end diff --git a/lib/rails_jwt_auth.rb b/lib/rails_jwt_auth.rb index 177c825..f1aa433 100644 --- a/lib/rails_jwt_auth.rb +++ b/lib/rails_jwt_auth.rb @@ -114,4 +114,9 @@ def self.email_field_name! field_name end + + def self.send_email(method, user) + mailer = RailsJwtAuth::Mailer.with(user_id: user.id.to_s).public_send(method) + RailsJwtAuth.deliver_later ? mailer.deliver_later : mailer.deliver + end end diff --git a/spec/controllers/confirmations_controller_spec.rb b/spec/controllers/confirmations_controller_spec.rb index bf0104e..f51ae1b 100644 --- a/spec/controllers/confirmations_controller_spec.rb +++ b/spec/controllers/confirmations_controller_spec.rb @@ -18,15 +18,9 @@ end it 'sends new confirmation email with new token' do - class Mock - def deliver - end - end - - expect(RailsJwtAuth::Mailer).to receive(:confirmation_instructions) - .with(user).and_return(Mock.new) - old_token = user.confirmation_token + expect(RailsJwtAuth).to receive(:send_email).with(:confirmation_instructions, anything) + post :create, params: {confirmation: {email: user.email}} expect(user.reload.confirmation_token).not_to eq(old_token) end diff --git a/spec/controllers/passwords_controller_spec.rb b/spec/controllers/passwords_controller_spec.rb index 96795a6..408bfec 100644 --- a/spec/controllers/passwords_controller_spec.rb +++ b/spec/controllers/passwords_controller_spec.rb @@ -29,13 +29,8 @@ end it 'sends new reset_password email with new token' do - class Mock - def deliver - end - end - - expect(RailsJwtAuth::Mailer).to receive(:reset_password_instructions) - .with(user).and_return(Mock.new) + expect(RailsJwtAuth).to receive(:send_email) + .with(:reset_password_instructions, anything) old_token = user.reset_password_token post :create, params: {password: {email: user.email}} diff --git a/spec/lib/rails_jwt_auth_spec.rb b/spec/lib/rails_jwt_auth_spec.rb new file mode 100644 index 0000000..cea6c55 --- /dev/null +++ b/spec/lib/rails_jwt_auth_spec.rb @@ -0,0 +1,41 @@ +require 'rails_helper' + +describe RailsJwtAuth do + before(:all) { RailsJwtAuth.model_name = "ActiveRecordUser" } + + describe '#send_email' do + let(:unconfirmed_user) { FactoryBot.create(:active_record_unconfirmed_user) } + + after { RailsJwtAuth.deliver_later = false } + + context 'when deliver_later options is false' do + before { RailsJwtAuth.deliver_later = false } + + it 'uses deliver method' do + mock2 = OpenStruct.new(deliver: true) + mock = OpenStruct.new(confirmation_instructions: mock2) + + expect(RailsJwtAuth::Mailer).to receive(:with).with(user_id: unconfirmed_user.id.to_s) + .and_return(mock) + expect(mock2).to receive(:deliver) + + RailsJwtAuth.send_email(:confirmation_instructions, unconfirmed_user) + end + end + + context 'when deliver_later options is false' do + before { RailsJwtAuth.deliver_later = true } + + it 'uses deliver method' do + mock2 = OpenStruct.new(deliver_later: true) + mock = OpenStruct.new(confirmation_instructions: mock2) + + expect(RailsJwtAuth::Mailer).to receive(:with).with(user_id: unconfirmed_user.id.to_s) + .and_return(mock) + expect(mock2).to receive(:deliver_later) + + RailsJwtAuth.send_email(:confirmation_instructions, unconfirmed_user) + end + end + end +end diff --git a/spec/mailers/mailer_spec.rb b/spec/mailers/mailer_spec.rb index 066abca..8d97393 100644 --- a/spec/mailers/mailer_spec.rb +++ b/spec/mailers/mailer_spec.rb @@ -1,13 +1,17 @@ require 'rails_helper' RSpec.describe RailsJwtAuth::Mailer, type: :mailer do + before(:all) { RailsJwtAuth.model_name = 'ActiveRecordUser' } + + let(:mail_params) { {user_id: user.id.to_s } } + describe 'confirmation_instructions' do let(:user) do FactoryBot.create(:active_record_unconfirmed_user, confirmation_token: 'abcd', confirmation_sent_at: Time.current) end - let(:mail) { described_class.confirmation_instructions(user).deliver_now } + let(:mail) { described_class.with(mail_params).confirmation_instructions.deliver_now } let(:url) { "#{RailsJwtAuth.confirmations_url}?confirmation_token=#{user.confirmation_token}" } it 'sends email with correct info' do @@ -46,7 +50,7 @@ reset_password_sent_at: Time.current) end - let(:mail) { described_class.reset_password_instructions(user).deliver_now } + let(:mail) { described_class.with(mail_params).reset_password_instructions.deliver_now } let(:url) { "#{RailsJwtAuth.reset_passwords_url}?reset_password_token=#{user.reset_password_token}" } it 'sends email with correct info' do @@ -75,7 +79,7 @@ reset_password_sent_at: Time.current) end - let(:mail) { described_class.set_password_instructions(user).deliver_now } + let(:mail) { described_class.with(mail_params).set_password_instructions.deliver_now } let(:url) { "#{RailsJwtAuth.set_passwords_url}?reset_password_token=#{user.reset_password_token}" } it 'sends email with correct info' do @@ -104,7 +108,7 @@ invitation_created_at: Time.current) end - let(:mail) { described_class.send_invitation(user).deliver_now } + let(:mail) { described_class.with(mail_params).send_invitation.deliver_now } let(:url) { "#{RailsJwtAuth.invitations_url}?invitation_token=#{user.invitation_token}" } it 'sends email with correct info' do @@ -136,7 +140,7 @@ ) end - let(:mail) { described_class.send_unlock_instructions(user).deliver_now } + let(:mail) { described_class.with(mail_params).send_unlock_instructions.deliver_now } let(:url) { "#{RailsJwtAuth.unlock_url}?unlock_token=#{user.unlock_token}" } it 'sends email with correct info' do diff --git a/spec/models/concerns/confirmable_spec.rb b/spec/models/concerns/confirmable_spec.rb index 3cf3299..219b1bb 100644 --- a/spec/models/concerns/confirmable_spec.rb +++ b/spec/models/concerns/confirmable_spec.rb @@ -71,45 +71,18 @@ end describe '#send_confirmation_instructions' do - before :all do - class Mock - def deliver - end - - def deliver_later - end - end - end - it 'fills confirmation fields' do - mock = Mock.new - allow(RailsJwtAuth::Mailer).to receive(:confirmation_instructions).and_return(mock) unconfirmed_user.send_confirmation_instructions expect(unconfirmed_user.confirmation_token).not_to be_nil expect(unconfirmed_user.confirmation_sent_at).not_to be_nil end it 'sends confirmation email' do - mock = Mock.new new_user = FactoryBot.build("#{orm.underscore}_unconfirmed_user") - allow(RailsJwtAuth::Mailer).to receive(:confirmation_instructions).and_return(mock) - expect(mock).to receive(:deliver) + expect(RailsJwtAuth).to receive(:send_email).with(:confirmation_instructions, anything) new_user.send_confirmation_instructions end - context 'when use deliver_later option' do - before { RailsJwtAuth.deliver_later = true } - after { RailsJwtAuth.deliver_later = false } - - it 'uses deliver_later method to send email' do - mock = Mock.new - new_user = FactoryBot.build("#{orm.underscore}_unconfirmed_user") - allow(RailsJwtAuth::Mailer).to receive(:confirmation_instructions).and_return(mock) - expect(mock).to receive(:deliver_later) - new_user.send_confirmation_instructions - end - end - context 'when user is confirmed' do it 'returns false' do expect(user.send_confirmation_instructions).to eq(false) @@ -121,9 +94,9 @@ def deliver_later end it 'does not send confirmation email' do - mock = Mock.new - allow(RailsJwtAuth::Mailer).to receive(:confirmation_instructions).and_return(mock) - expect(mock).not_to receive(:deliver) + expect(RailsJwtAuth).not_to receive(:send_email) + .with(:confirmation_instructions, anything) + user.send_confirmation_instructions end @@ -174,22 +147,19 @@ def deliver_later context 'when send_email_changed_notification option is false' do it 'sends only confirmation email' do allow(RailsJwtAuth).to receive(:send_email_changed_notification).and_return(false) + expect(RailsJwtAuth).to receive(:send_email).with(:confirmation_instructions, user) + expect(RailsJwtAuth).not_to receive(:send_email).with(:email_changed, user) user.update(email: 'new@email.com') - expect(ActionMailer::Base.deliveries.count).to eq(1) - expect(ActionMailer::Base.deliveries.first.subject).to eq('Confirmation instructions') - expect(ActionMailer::Base.deliveries.first.to).to eq(['new@email.com']) end end context 'when send_email_changed_notification option is true' do it 'sends confirmation and nofication email' do allow(RailsJwtAuth).to receive(:send_email_changed_notification).and_return(true) + expect(RailsJwtAuth).to receive(:send_email).with(:email_changed, user) + expect(RailsJwtAuth).to receive(:send_email).with(:confirmation_instructions, user) old_email = user.email user.update(email: 'new@email.com') - expect(ActionMailer::Base.deliveries.first.subject).to eq('Confirmation instructions') - expect(ActionMailer::Base.deliveries.first.to).to eq(['new@email.com']) - expect(ActionMailer::Base.deliveries.last.subject).to eq('Email changed') - expect(ActionMailer::Base.deliveries.last.to).to eq([old_email]) end end end diff --git a/spec/models/concerns/recoverable_spec.rb b/spec/models/concerns/recoverable_spec.rb index 62c5c2e..f0e0d0a 100644 --- a/spec/models/concerns/recoverable_spec.rb +++ b/spec/models/concerns/recoverable_spec.rb @@ -1,16 +1,6 @@ require 'rails_helper' describe RailsJwtAuth::Recoverable do - before :all do - class Mock - def deliver - end - - def deliver_later - end - end - end - %w(ActiveRecord Mongoid).each do |orm| context "when use #{orm}" do before(:all) { RailsJwtAuth.model_name = "#{orm}User" } @@ -24,8 +14,6 @@ def deliver_later describe '#send_reset_password_instructions' do it 'fills reset password fields' do - mock = Mock.new - allow(RailsJwtAuth::Mailer).to receive(:reset_password_instructions).and_return(mock) user.send_reset_password_instructions user.reload expect(user.reset_password_token).not_to be_nil @@ -33,24 +21,10 @@ def deliver_later end it 'sends reset password email' do - mock = Mock.new - allow(RailsJwtAuth::Mailer).to receive(:reset_password_instructions).and_return(mock) - expect(mock).to receive(:deliver) + expect(RailsJwtAuth).to receive(:send_email).with(:reset_password_instructions, user) user.send_reset_password_instructions end - context 'when use deliver_later option' do - before { RailsJwtAuth.deliver_later = true } - after { RailsJwtAuth.deliver_later = false } - - it 'uses deliver_later method to send email' do - mock = Mock.new - allow(RailsJwtAuth::Mailer).to receive(:reset_password_instructions).and_return(mock) - expect(mock).to receive(:deliver_later) - user.send_reset_password_instructions - end - end - context 'when user is unconfirmed' do let(:user) { FactoryBot.create("#{orm.underscore}_unconfirmed_user") } @@ -66,7 +40,9 @@ def deliver_later end it 'doe not send reset password email' do - expect(RailsJwtAuth::Mailer).not_to receive(:reset_password_instructions) + expect(RailsJwtAuth).not_to receive(:send_email) + .with(:reset_password_instructions, user) + user.send_reset_password_instructions end end @@ -106,8 +82,6 @@ def deliver_later let(:user) { FactoryBot.build("#{orm.underscore}_user", password: nil) } it 'set password and confirm' do - mock = Mock.new - allow(RailsJwtAuth::Mailer).to receive(:reset_password_instructions).and_return(mock) user.set_and_send_password_instructions user.reload expect(user.password).not_to be_nil @@ -115,8 +89,6 @@ def deliver_later end it 'fills set password fields' do - mock = Mock.new - allow(RailsJwtAuth::Mailer).to receive(:reset_password_instructions).and_return(mock) user.set_and_send_password_instructions user.reload expect(user.reset_password_token).not_to be_nil @@ -124,23 +96,9 @@ def deliver_later end it 'sends set password email' do - mock = Mock.new - allow(RailsJwtAuth::Mailer).to receive(:set_password_instructions).and_return(mock) - expect(mock).to receive(:deliver) + expect(RailsJwtAuth).to receive(:send_email).with(:set_password_instructions, user) user.set_and_send_password_instructions end - - context 'when use deliver_later option' do - before { RailsJwtAuth.deliver_later = true } - after { RailsJwtAuth.deliver_later = false } - - it 'uses deliver_later method to send email' do - mock = Mock.new - allow(RailsJwtAuth::Mailer).to receive(:set_password_instructions).and_return(mock) - expect(mock).to receive(:deliver_later) - user.set_and_send_password_instructions - end - end end describe '#before_save' do