From 97f335c36aad5126d5e6cb1099a442a6bde164e6 Mon Sep 17 00:00:00 2001 From: simon lehericey Date: Fri, 26 Jan 2024 10:00:23 +0100 Subject: [PATCH] add a cron job to send expiration notice --- .../send_api_token_expiration_notice_job.rb | 21 +++++ ...nd_api_token_expiration_notice_job_spec.rb | 83 +++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 app/jobs/cron/send_api_token_expiration_notice_job.rb create mode 100644 spec/jobs/cron/send_api_token_expiration_notice_job_spec.rb diff --git a/app/jobs/cron/send_api_token_expiration_notice_job.rb b/app/jobs/cron/send_api_token_expiration_notice_job.rb new file mode 100644 index 000000000..48d69c0d8 --- /dev/null +++ b/app/jobs/cron/send_api_token_expiration_notice_job.rb @@ -0,0 +1,21 @@ +class Cron::SendAPITokenExpirationNoticeJob < Cron::CronJob + self.schedule_expression = "every day at midnight" + + def perform + windows = [ + 1.day, + 1.week, + 1.month + ] + + windows.each do |window| + APIToken + .with_expiration_notice_to_send_for(window) + .find_each do |token| + APITokenMailer.expiration(token).deliver_later + token.expiration_notices_sent_at << Time.zone.today + token.save! + end + end + end +end diff --git a/spec/jobs/cron/send_api_token_expiration_notice_job_spec.rb b/spec/jobs/cron/send_api_token_expiration_notice_job_spec.rb new file mode 100644 index 000000000..ae2af0421 --- /dev/null +++ b/spec/jobs/cron/send_api_token_expiration_notice_job_spec.rb @@ -0,0 +1,83 @@ +RSpec.describe Cron::SendAPITokenExpirationNoticeJob, type: :job do + describe 'perform' do + let(:administrateur) { create(:administrateur) } + let!(:token) { APIToken.generate(administrateur).first } + let(:mailer_double) { double('mailer', deliver_later: true) } + let(:today) { Date.new(2018, 01, 01) } + + def perform_now + Cron::SendAPITokenExpirationNoticeJob.perform_now + end + + before do + travel_to(today) + token.update!(created_at: today) + allow(APITokenMailer).to receive(:expiration).and_return(mailer_double) + end + + context 'when the token does not expire' do + before { perform_now } + + it { expect(mailer_double).not_to have_received(:deliver_later) } + end + + context 'when the token expires in 6 months' do + let(:expires_at) { Date.new(2018, 06, 01) } + before do + token.update(expires_at:) + perform_now + end + + it { expect(mailer_double).not_to have_received(:deliver_later) } + + context 'when the token expires less than a month' do + before do + travel_to(expires_at - 1.month - 1.day) + perform_now + + travel_to(expires_at - 1.month) + perform_now + + travel_to(expires_at - 1.month + 1.day) + perform_now + end + + it do + expect(mailer_double).to have_received(:deliver_later).once + expect(token.reload.expiration_notices_sent_at).to match_array([expires_at - 1.month]) + end + end + + context 'when the token expires less than a week' do + before do + travel_to(expires_at - 1.week) + 2.times.each { perform_now } + end + + it { expect(mailer_double).to have_received(:deliver_later).once } + end + + context 'when we simulate the whole sequence' do + before do + travel_to(expires_at - 1.month) + 2.times.each { perform_now } + + travel_to(expires_at - 1.week) + 2.times.each { perform_now } + + travel_to(expires_at - 1.day) + 2.times.each { perform_now } + end + + it do + expect(mailer_double).to have_received(:deliver_later).exactly(3).times + expect(token.reload.expiration_notices_sent_at).to match_array([ + expires_at - 1.month, + expires_at - 1.week, + expires_at - 1.day + ]) + end + end + end + end +end