Skip to content

Commit

Permalink
[RUBY-2658] Classes and specs for unlock_instructions and reset_passw…
Browse files Browse the repository at this point in the history
…ord notify emails
  • Loading branch information
jjromeo committed Oct 10, 2023
1 parent d8363a2 commit 1a9d63c
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 37 deletions.
4 changes: 2 additions & 2 deletions app/mailers/waste_carriers_engine/devise_notify_mailer.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
class DeviseNotifyMailer < Devise::Mailer
include Devise::Controllers::UrlHelpers

def password_change(record, opts = {})
send_via_gov_notify(:password_change, record, opts)
def reset_password_instructions(record, token, opts = {})
send_via_gov_notify(:reset_password_instructions, record, opts.merge(token: token))
end

def unlock_instructions(record, token, opts = {})
Expand Down
27 changes: 22 additions & 5 deletions app/services/waste_carriers_engine/notify/devise_sender.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,31 @@ class DeviseSender
include ActionView::Helpers::NumberHelper

def run(template:, record:, opts:)
return unless record&.email.present?
service_class = service_for_template(template)
service = service_class.new

@record = record
@token = opts[:token]
service.send_email(record, opts[:token])
end

def send_email(record, token)
client.send_email(notify_options(record, token))
end

client = Notifications::Client.new(WasteCarriersEngine.configuration.notify_api_key)
private

def service_for_template(template)
case template
when :reset_password_instructions
ResetPasswordInstructionsEmailService
when :unlock_instructions
UnlockInstructionsEmailService
else
raise ArgumentError, "Unknown email template: #{template}"
end
end

client.send_email(notify_options)
def client
@client ||= Notifications::Client.new(WasteCarriersEngine.configuration.notify_api_key)
end
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

module WasteCarriersEngine
module Notify
class ResetPasswordInstructionsEmailService < DeviseSender
private
def reset_url(token)
Rails.application.routes.url_helpers.edit_user_password_url(
host: Rails.configuration.wcrs_back_office_url,
reset_password_token: token
)
end

def notify_options(record, token)
{
email_address: record.email,
template_id: "bfe66f5e-29ed-4f78-82e1-8baf5548f97a",
personalisation: {
reset_password_link: reset_url(token)
}
}
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,21 @@

module WasteCarriersEngine
module Notify
class UnlockInstructionsEmailService < BaseSendEmailService
class UnlockInstructionsEmailService < DeviseSender
private
def unlock_url
Rails.application.routes.url_helpers.unlock_url(
@record,
host: Rails.configuration.x.notify.host,
unlock_token: @token
def unlock_url(token)
Rails.application.routes.url_helpers.user_unlock_url(
host: Rails.configuration.wcrs_back_office_url,
unlock_token: token
)
end

def notify_options
def notify_options(record, token)
{
email_address: @record.email,
email_address: record.email,
template_id: "a3295516-26a6-4c01-9e3a-d5000f1a86c6",
personalisation: {
unlock_link: unlock_url
unlock_link: unlock_url(token)
}
}
end
Expand Down
2 changes: 1 addition & 1 deletion spec/dummy/config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class Application < Rails::Application
# Paths
# This is the domain to use on URLs for FO services such as renewal and deregistration
config.wcrs_fo_link_domain = ENV["WCRS_RENEWALS_DOMAIN"] || "http://localhost:3002"

config.wcrs_back_office_url = ENV["WCRS_BACK_OFFICE_DOMAIN"] || "http://localhost:8001"
config.wcrs_frontend_url = ENV["WCRS_FRONTEND_DOMAIN"] || "http://localhost:3000"
config.wcrs_services_url = ENV["WCRS_SERVICES_DOMAIN"] || "http://localhost:8003"
config.os_places_service_url = ENV["WCRS_OS_PLACES_DOMAIN"] || "http://localhost:8005"
Expand Down
43 changes: 43 additions & 0 deletions spec/services/waste_carriers_engine/notify/devise_sender_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
require "rails_helper"

module WasteCarriersEngine
module Notify
RSpec.describe DeviseSender do
let(:user_with_email) { create(:user, email: "[email protected]") }
let(:user_without_email) { create(:user, email: nil) }
let(:token) { "example_token" }

let(:notifications_client) { instance_double(Notifications::Client) }

before do
allow(Notifications::Client).to receive(:new).and_return(notifications_client)
allow(notifications_client).to receive(:send_email)
end

describe "#run" do
context "with :reset_password_instructions template" do
it "uses ResetPasswordInstructionsEmailService" do
expect(ResetPasswordInstructionsEmailService).to receive(:new).and_call_original
described_class.new.run(template: :reset_password_instructions, record: user_with_email, opts: { token: token })
end
end

context "with :unlock_instructions template" do
it "uses UnlockInstructionsEmailService" do
expect(UnlockInstructionsEmailService).to receive(:new).and_call_original
described_class.new.run(template: :unlock_instructions, record: user_with_email, opts: { token: token })
end
end

context "with unknown template" do
it "raises an error" do
expect {
described_class.new.run(template: :unknown_template, record: user_with_email, opts: { token: token })
}.to raise_error(ArgumentError, "Unknown email template: unknown_template")
end
end
end
end
end
end

Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# frozen_string_literal: true

require "rails_helper"

module WasteCarriersEngine
module Notify
RSpec.describe ResetPasswordInstructionsEmailService do
describe ".send_email" do
let(:template_id) { "bfe66f5e-29ed-4f78-82e1-8baf5548f97a" }
let(:user) { create(:user, email: "[email protected]") }
let(:token) { "example_token" }

let(:expected_notify_options) do
{
email_address: user.email,
template_id: template_id,
personalisation: {
reset_password_link: Rails.application.routes.url_helpers.edit_user_password_url(
host: Rails.configuration.wcrs_back_office_url,
reset_password_token: token
)
}
}
end

let(:notifications_client) { instance_double(Notifications::Client) }

before do
allow(Notifications::Client).to receive(:new).and_return(notifications_client)
allow(notifications_client).to receive(:send_email)

described_class.new.send_email(user, token)
end

context "with an email" do

it "sends an email" do
expect(notifications_client).to have_received(:send_email).with(expected_notify_options)
end
end

context "with no email" do
before { user.email = nil }

it "sends an email" do
expect(notifications_client).not_to have_received(:send_email).with(expected_notify_options)
end
end
end
end
end
end


Original file line number Diff line number Diff line change
Expand Up @@ -5,50 +5,45 @@
module WasteCarriersEngine
module Notify
RSpec.describe UnlockInstructionsEmailService do
describe ".run" do
describe ".send_email" do
let(:template_id) { "a3295516-26a6-4c01-9e3a-d5000f1a86c6" }
let(:user) { create(:user, email: "[email protected]") } # Assuming you have a factory for User
let(:user) { create(:user, email: "[email protected]") }
let(:token) { "example_token" }

let(:expected_notify_options) do
{
email_address: user.email,
template_id: template_id,
personalisation: {
unlock_link: Rails.application.routes.url_helpers.unlock_url(
user,
unlock_link: Rails.application.routes.url_helpers.user_unlock_url(
host: Rails.configuration.wcrs_back_office_url,
unlock_token: token
)
}
}
end

context "with an email" do
before do
allow_any_instance_of(Notifications::Client)
.to receive(:send_email)
.with(expected_notify_options)
.and_call_original
end
let(:notifications_client) { instance_double(Notifications::Client) }

subject(:run_service) do
described_class.new.run(template: template_id, record: user, opts: { token: token })
end
before do
allow(Notifications::Client).to receive(:new).and_return(notifications_client)
allow(notifications_client).to receive(:send_email)

described_class.new.send_email(user, token)
end

context "with an email" do

it "sends an email" do
expect(run_service).to be_a(Notifications::Client::ResponseNotification)
expect(run_service.template["id"]).to eq(template_id)
expect(notifications_client).to have_received(:send_email).with(expected_notify_options)
end
end

context "with no email" do
before { user.email = nil }

it "does not attempt to send an email" do
expect_any_instance_of(Notifications::Client).not_to receive(:send_email)

described_class.new.run(template: template_id, record: user, opts: { token: token })
it "sends an email" do
expect(notifications_client).not_to have_received(:send_email).with(expected_notify_options)
end
end
end
Expand Down

0 comments on commit 1a9d63c

Please sign in to comment.