Skip to content

Commit

Permalink
Merge pull request #2139 from unboxed/notify-template-id
Browse files Browse the repository at this point in the history
Add notify template ID and ensure 1 min before resending magic link
  • Loading branch information
benbaumann95 authored Jan 30, 2025
2 parents cc58c57 + ba5e975 commit 0390043
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 16 deletions.
5 changes: 5 additions & 0 deletions app/models/consultee.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@ def application_link
end
end

def can_resend_magic_link?
# Resend if never sent or at least 1 minute has passed
magic_link_last_sent_at.nil? || magic_link_last_sent_at <= 1.minute.ago
end

delegate :received_at, to: :last_response, prefix: :last, allow_nil: true

private
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

class AddMagicLinkLastSentAtToConsultees < ActiveRecord::Migration[7.2]
def change
add_column :consultees, :magic_link_last_sent_at, :datetime
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.2].define(version: 2025_01_20_122725) do
ActiveRecord::Schema[7.2].define(version: 2025_01_30_115103) do
# These are extensions that must be enabled in order to support this database
enable_extension "btree_gin"
enable_extension "plpgsql"
Expand Down Expand Up @@ -300,6 +300,7 @@
t.datetime "last_email_delivered_at"
t.datetime "expires_at"
t.datetime "last_response_at"
t.datetime "magic_link_last_sent_at"
t.index ["consultation_id"], name: "ix_consultees_on_consultation_id"
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class PlanningApplicationsController < ApplicationController
before_action :authenticate_with_sgid!, only: :show
before_action :set_planning_application, only: %i[show resend_link]
before_action :set_consultee, only: :resend_link
before_action :ensure_magic_link_resend_allowed, only: :resend_link

def show
respond_to do |format|
Expand All @@ -15,12 +16,11 @@ def show
def resend_link
BopsCore::MagicLinkMailerJob.perform_later(
resource: @consultee,
subdomain: @current_local_authority.subdomain,
planning_application: @planning_application.presented
)

respond_to do |format|
format.html { redirect_to root_url, notice: "A magic link has been sent to: #{@consultee.email_address}" }
format.html { redirect_to root_url, notice: t(".success", email: @consultee.email_address) }
end
end

Expand Down Expand Up @@ -51,5 +51,13 @@ def reference
def render_expired
render "bops_consultees/dashboards/show"
end

def ensure_magic_link_resend_allowed
return if @consultee.can_resend_magic_link?

flash.now[:alert] = t(".failure")
@expired_resource = @consultee
render_expired
end
end
end
3 changes: 3 additions & 0 deletions engines/bops_consultees/config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ en:
show:
consultee_overview: Consultee overview
planning_applications:
resend_link:
failure: A magic link was sent recently. Please wait at least 1 minute before requesting another.
success: 'A magic link has been sent to: %{email}'
show:
application_number: Application number
no_digital_sitemap: No digital site map provided
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,12 @@
let!(:sgid) { consultee.sgid(expires_in: 1.minute, for: "magic_link") }
let(:mail) { ActionMailer::Base.deliveries }

it "I can see that the link has expired" do
before do
travel 2.minutes
visit "/consultees/planning_applications/#{reference}?sgid=#{sgid}"
end

it "I can see that the link has expired and can resend link" do
expect(page).not_to have_content(planning_application.full_address)
expect(page).not_to have_content(reference)
expect(page).to have_content("Your magic link has expired")
Expand All @@ -56,6 +59,28 @@
visit url
expect(page).to have_content(reference)
end

it "does not resend the link if attempted within 1 minute" do
delivered_emails = mail.count
click_button("Send a new magic link")
expect(page).to have_content("A magic link has been sent to: #{consultee.email_address}")
perform_enqueued_jobs
expect(mail.count).to eql(delivered_emails + 1)

# Attempt to resend immediately
delivered_emails = mail.count
visit "/consultees/planning_applications/#{reference}?sgid=#{sgid}"
click_button("Send a new magic link")
expect(page).to have_content("A magic link was sent recently. Please wait at least 1 minute before requesting another.")
expect(mail.count).to eql(delivered_emails)

# Wait for 1 minute and try again
travel 1.minute
click_button("Send a new magic link")
expect(page).to have_content("A magic link has been sent to: #{consultee.email_address}")
perform_enqueued_jobs
expect(mail.count).to eql(delivered_emails + 1)
end
end

context "with expired magic link for other sgid purpose" do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ module BopsCore
class MagicLinkMailerJob < ApplicationJob
queue_as :low_priority

def perform(resource:, planning_application:, subdomain:)
def perform(resource:, planning_application:)
MagicLinkMailer.magic_link_mail(
resource: resource,
planning_application: planning_application,
subdomain: subdomain
planning_application: planning_application
).deliver_now
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,20 @@

module BopsCore
class MagicLinkMailer < ApplicationMailer
def magic_link_mail(resource:, subdomain:, planning_application:, subject: "Your BOPS magic link")
def magic_link_mail(resource:, planning_application:, subject: "Your BOPS magic link")
resource.touch(:magic_link_last_sent_at)

@resource = resource
@sgid = resource.sgid
@subdomain = subdomain
@planning_application = planning_application
@subdomain = planning_application.local_authority.subdomain
@url = magic_link_url

mail(
view_mail(
NOTIFY_TEMPLATE_ID,
to: resource.email_address,
subject:
subject:,
reply_to_id: planning_application.local_authority.email_reply_to_id
)
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,24 @@

it "enqueues the job" do
expect {
BopsCore::MagicLinkMailerJob.perform_later(resource: consultee, planning_application:, subdomain: "southwark")
}.to have_enqueued_job(BopsCore::MagicLinkMailerJob).with(resource: consultee, planning_application:, subdomain: "southwark")
BopsCore::MagicLinkMailerJob.perform_later(resource: consultee, planning_application:)
}.to have_enqueued_job(BopsCore::MagicLinkMailerJob).with(resource: consultee, planning_application:)
end

it "updates the magic link last sent at time" do
travel_to("2025-01-30")

expect {
perform_enqueued_jobs do
BopsCore::MagicLinkMailerJob.perform_now(resource: consultee, planning_application:)
end
}.to change { consultee.magic_link_last_sent_at }.from(nil).to("2025-01-30".to_datetime)
end

it "sends the email" do
expect {
perform_enqueued_jobs do
BopsCore::MagicLinkMailerJob.perform_now(resource: consultee, planning_application:, subdomain: "southwark")
BopsCore::MagicLinkMailerJob.perform_now(resource: consultee, planning_application:)
end
}.to change { ActionMailer::Base.deliveries.count }.by(1)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
let(:consultation) { create(:consultation) }
let(:consultee) { create(:consultee, consultation:, email_address: "[email protected]", name: "Bops Consultee") }
let(:planning_application) { consultation.planning_application }
let(:mail) { described_class.magic_link_mail(resource: consultee, planning_application:, subdomain: "southwark", subject: "Your magic link") }
let(:mail) { described_class.magic_link_mail(resource: consultee, planning_application:, subject: "Your magic link") }

before do
allow(consultee).to receive(:sgid).and_return("123456789")
Expand All @@ -22,7 +22,7 @@
end

it "assigns the correct magic link URL" do
expect(mail.body.encoded).to include("http://southwark.bops.services/consultees/planning_applications/25-00100-LDCE?sgid=123456789")
expect(mail.body.encoded).to include("http://buckinghamshire.bops.services/consultees/planning_applications/25-00100-LDCE?sgid=123456789")
end

it "includes the planning application reference in the email body" do
Expand Down

0 comments on commit 0390043

Please sign in to comment.