mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-11 09:41:40 -05:00
Move sending family invitation email to a background job
This commit is contained in:
parent
a6f2bd3662
commit
eed9480a9e
5 changed files with 104 additions and 12 deletions
|
|
@ -13,9 +13,10 @@ class Family::Invitations::CleanupJob < ApplicationJob
|
||||||
Rails.logger.info "Updated #{expired_count} expired family invitations"
|
Rails.logger.info "Updated #{expired_count} expired family invitations"
|
||||||
|
|
||||||
cleanup_threshold = 30.days.ago
|
cleanup_threshold = 30.days.ago
|
||||||
deleted_count = Family::Invitation.where(status: [:expired, :cancelled])
|
deleted_count =
|
||||||
.where('updated_at < ?', cleanup_threshold)
|
Family::Invitation.where(status: %i[expired cancelled])
|
||||||
.delete_all
|
.where('updated_at < ?', cleanup_threshold)
|
||||||
|
.delete_all
|
||||||
|
|
||||||
Rails.logger.info "Deleted #{deleted_count} old family invitations"
|
Rails.logger.info "Deleted #{deleted_count} old family invitations"
|
||||||
|
|
||||||
|
|
|
||||||
13
app/jobs/family/invitations/sending_job.rb
Normal file
13
app/jobs/family/invitations/sending_job.rb
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class Family::Invitations::SendingJob < ApplicationJob
|
||||||
|
queue_as :families
|
||||||
|
|
||||||
|
def perform(invitation_id)
|
||||||
|
invitation = Family::Invitation.find_by(id: invitation_id)
|
||||||
|
|
||||||
|
return unless invitation&.pending?
|
||||||
|
|
||||||
|
FamilyMailer.invitation(invitation).deliver_now
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -19,8 +19,8 @@ module Families
|
||||||
return false unless invite_sendable?
|
return false unless invite_sendable?
|
||||||
|
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
create_invitation
|
invitation = create_invitation
|
||||||
send_invitation_email
|
send_invitation_email(invitation)
|
||||||
send_notification
|
send_notification
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -80,16 +80,18 @@ module Families
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def send_invitation_email
|
def send_invitation_email(invitation)
|
||||||
# Send email in background with retry logic
|
Families::Invitations::SendingJob.perform_later(invitation.id)
|
||||||
FamilyMailer.invitation(@invitation).deliver_later(
|
|
||||||
queue: :mailer,
|
|
||||||
retry: 3,
|
|
||||||
wait: 30.seconds
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def send_notification
|
def send_notification
|
||||||
|
message =
|
||||||
|
if DawarichSettings.self_hosted?
|
||||||
|
"Family invitation sent to #{email} if SMTP is configured properly. If you're not using SMTP, copy the invitation link from the family page and share it manually."
|
||||||
|
else
|
||||||
|
"Family invitation sent to #{email}"
|
||||||
|
end
|
||||||
|
|
||||||
Notification.create!(
|
Notification.create!(
|
||||||
user: invited_by,
|
user: invited_by,
|
||||||
kind: :info,
|
kind: :info,
|
||||||
|
|
|
||||||
71
spec/jobs/family/invitations/sending_job_spec.rb
Normal file
71
spec/jobs/family/invitations/sending_job_spec.rb
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe Family::Invitations::SendingJob, type: :job do
|
||||||
|
let(:user) { create(:user) }
|
||||||
|
let(:family) { create(:family, creator: user) }
|
||||||
|
let(:invitation) { create(:family_invitation, family: family, invited_by: user, status: :pending) }
|
||||||
|
|
||||||
|
describe '#perform' do
|
||||||
|
context 'when invitation exists and is pending' do
|
||||||
|
it 'sends the invitation email' do
|
||||||
|
mailer_double = double('mailer')
|
||||||
|
expect(FamilyMailer).to receive(:invitation).with(invitation).and_return(mailer_double)
|
||||||
|
expect(mailer_double).to receive(:deliver_now)
|
||||||
|
|
||||||
|
described_class.perform_now(invitation.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when invitation does not exist' do
|
||||||
|
it 'does not raise an error' do
|
||||||
|
expect do
|
||||||
|
described_class.perform_now(999_999)
|
||||||
|
end.not_to raise_error
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not send any email' do
|
||||||
|
expect(FamilyMailer).not_to receive(:invitation)
|
||||||
|
|
||||||
|
described_class.perform_now(999_999)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when invitation is not pending' do
|
||||||
|
let(:accepted_invitation) do
|
||||||
|
create(:family_invitation, family: family, invited_by: user, status: :accepted)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not send the invitation email' do
|
||||||
|
expect(FamilyMailer).not_to receive(:invitation)
|
||||||
|
|
||||||
|
described_class.perform_now(accepted_invitation.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when invitation is cancelled' do
|
||||||
|
let(:cancelled_invitation) do
|
||||||
|
create(:family_invitation, family: family, invited_by: user, status: :cancelled)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not send the invitation email' do
|
||||||
|
expect(FamilyMailer).not_to receive(:invitation)
|
||||||
|
|
||||||
|
described_class.perform_now(cancelled_invitation.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'integration test' do
|
||||||
|
it 'actually sends the email' do
|
||||||
|
expect do
|
||||||
|
described_class.perform_now(invitation.id)
|
||||||
|
end.to change { ActionMailer::Base.deliveries.count }.by(1)
|
||||||
|
|
||||||
|
email = ActionMailer::Base.deliveries.last
|
||||||
|
expect(email.to).to include(invitation.email)
|
||||||
|
expect(email.subject).to include("You've been invited to join #{family.name}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -21,6 +21,11 @@ RSpec.describe Families::Invite do
|
||||||
expect(invitation.invited_by).to eq(owner)
|
expect(invitation.invited_by).to eq(owner)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'enqueues invitation sending job' do
|
||||||
|
expect(Family::Invitations::SendingJob).to receive(:perform_later).with(an_instance_of(Integer))
|
||||||
|
service.call
|
||||||
|
end
|
||||||
|
|
||||||
it 'sends invitation email' do
|
it 'sends invitation email' do
|
||||||
expect(FamilyMailer).to receive(:invitation).and_call_original
|
expect(FamilyMailer).to receive(:invitation).and_call_original
|
||||||
expect_any_instance_of(ActionMailer::MessageDelivery).to receive(:deliver_later)
|
expect_any_instance_of(ActionMailer::MessageDelivery).to receive(:deliver_later)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue