mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-10 17:21:38 -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,7 +13,8 @@ class Family::Invitations::CleanupJob < ApplicationJob
|
|||
Rails.logger.info "Updated #{expired_count} expired family invitations"
|
||||
|
||||
cleanup_threshold = 30.days.ago
|
||||
deleted_count = Family::Invitation.where(status: [:expired, :cancelled])
|
||||
deleted_count =
|
||||
Family::Invitation.where(status: %i[expired cancelled])
|
||||
.where('updated_at < ?', cleanup_threshold)
|
||||
.delete_all
|
||||
|
||||
|
|
|
|||
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?
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
create_invitation
|
||||
send_invitation_email
|
||||
invitation = create_invitation
|
||||
send_invitation_email(invitation)
|
||||
send_notification
|
||||
end
|
||||
|
||||
|
|
@ -80,16 +80,18 @@ module Families
|
|||
)
|
||||
end
|
||||
|
||||
def send_invitation_email
|
||||
# Send email in background with retry logic
|
||||
FamilyMailer.invitation(@invitation).deliver_later(
|
||||
queue: :mailer,
|
||||
retry: 3,
|
||||
wait: 30.seconds
|
||||
)
|
||||
def send_invitation_email(invitation)
|
||||
Families::Invitations::SendingJob.perform_later(invitation.id)
|
||||
end
|
||||
|
||||
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!(
|
||||
user: invited_by,
|
||||
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)
|
||||
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
|
||||
expect(FamilyMailer).to receive(:invitation).and_call_original
|
||||
expect_any_instance_of(ActionMailer::MessageDelivery).to receive(:deliver_later)
|
||||
|
|
|
|||
Loading…
Reference in a new issue