Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions app/mailers/school_ownership_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,28 @@ def complete_ownership_transfer
message_stream: 'outbound')
end

def complete_ownership_transfer_previous_owner
@school = ownership_transfer.school
previous_owner = users_by_id[ownership_transfer.requested_by_user_id]
@previous_owner_name = previous_owner&.name.presence || 'there'

mail(to: previous_owner&.email,
subject: "Ownership of the Code Classroom account for #{@school.name} has been transferred",
track_opens: 'true',
message_stream: 'outbound')
end

def decline_ownership_transfer_previous_owner
@school = ownership_transfer.school
previous_owner = users_by_id[ownership_transfer.requested_by_user_id]
@previous_owner_name = previous_owner&.name.presence || 'there'

mail(to: previous_owner&.email,
subject: "New owner declined ownership of the Code Classroom account for #{@school.name}",
track_opens: 'true',
message_stream: 'outbound')
end

private

def ownership_transfer
Expand Down
12 changes: 12 additions & 0 deletions app/models/ownership_transfer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ class OwnershipTransfer < ApplicationRecord
if: -> { saved_change_to_status?(from: 'pending', to: 'cancelled') }
after_update_commit :send_ownership_transfer_completed_email,
if: -> { saved_change_to_status?(from: 'pending', to: 'completed') }
after_update_commit :send_ownership_transfer_completed_email_to_previous_owner,
if: -> { saved_change_to_status?(from: 'pending', to: 'completed') }
after_update_commit :send_ownership_transfer_declined_email_to_previous_owner,
if: -> { saved_change_to_status?(from: 'pending', to: 'rejected') }
encrypts :email_address

private
Expand All @@ -47,4 +51,12 @@ def send_ownership_transfer_cancelled_email
def send_ownership_transfer_completed_email
SchoolOwnershipMailer.with(ownership_transfer: self).complete_ownership_transfer.deliver_later
end

def send_ownership_transfer_completed_email_to_previous_owner
SchoolOwnershipMailer.with(ownership_transfer: self).complete_ownership_transfer_previous_owner.deliver_later
end

def send_ownership_transfer_declined_email_to_previous_owner
SchoolOwnershipMailer.with(ownership_transfer: self).decline_ownership_transfer_previous_owner.deliver_later
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Hi <%= @previous_owner_name %>,

Ownership of the Code Classroom account for <%= @school.name %> has been successfully transferred to the new owner.

You are no longer the owner of this school. As part of the transfer, your role has automatically been changed to Teacher. You will still be able to create students, classes and projects within the account.

If you would like to be removed from the school, please contact us at websupport@raspberrypi.org.

Kind Regards,
The Code Classroom team
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Hi <%= @previous_owner_name %>,

The person you nominated as the new owner of the Code Classroom account for <%= @school.name %> has declined the ownership transfer.

You will remain the owner, and no changes have been made to your school.

If you'd still like to transfer ownership, you can submit a new request and nominate another person within your school.

Kind Regards,
The Code Classroom team
32 changes: 31 additions & 1 deletion spec/mailers/previews/school_ownership_mailer_preview.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Preview all emails at http://localhost:3009/rails/mailers/school_ownership_mailer
class SchoolOwnershipMailerPreview < ActionMailer::Preview
NOMINEE = { id: SecureRandom.uuid, name: 'Eliseo Ortiz' }.freeze
REQUESTED_OWNER = { id: SecureRandom.uuid, name: 'Oaklynn Duran' }.freeze
REQUESTED_OWNER = { id: SecureRandom.uuid, name: 'Oaklynn Duran', email: 'oaklynn@example.com' }.freeze

def request_ownership_transfer
school = School.new(name: 'Elmwood Secondary School')
Expand Down Expand Up @@ -43,6 +43,36 @@ def complete_ownership_transfer
with_stubbed_user_info_api { SchoolOwnershipMailer.with(ownership_transfer:).complete_ownership_transfer.message }
end

def complete_ownership_transfer_previous_owner
school = School.new(name: 'Elmwood Secondary School')
ownership_transfer = OwnershipTransfer.new(
email_address: 'teacher@example.com',
school:,
nominated_user_id: NOMINEE[:id],
requested_by_user_id: REQUESTED_OWNER[:id],
status: :completed
)

with_stubbed_user_info_api do
SchoolOwnershipMailer.with(ownership_transfer:).complete_ownership_transfer_previous_owner.message
end
end

def decline_ownership_transfer_previous_owner
school = School.new(name: 'Elmwood Secondary School')
ownership_transfer = OwnershipTransfer.new(
email_address: 'teacher@example.com',
school:,
nominated_user_id: NOMINEE[:id],
requested_by_user_id: REQUESTED_OWNER[:id],
status: :rejected
)

with_stubbed_user_info_api do
SchoolOwnershipMailer.with(ownership_transfer:).decline_ownership_transfer_previous_owner.message
end
end

private

# fake the user info response, but only for the duration of
Expand Down
108 changes: 108 additions & 0 deletions spec/mailers/school_ownership_mailer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -174,4 +174,112 @@
end
end
end

describe 'complete_ownership_transfer_previous_owner' do
subject(:email) { described_class.with(ownership_transfer:).complete_ownership_transfer_previous_owner }

let(:school) { create(:verified_school) }
let(:nominee) { create(:teacher, school:) }
let(:requested_owner) { create(:owner, school:) }
let(:ownership_transfer) do
create(
:ownership_transfer,
school:,
nominated_user_id: nominee.id,
requested_by_user_id: requested_owner.id,
status: :completed
)
end

before do
stub_user_info_api_fetch_by_ids(
user_ids: [nominee.id, requested_owner.id],
users: [{ id: nominee.id, name: nominee.name }, { id: requested_owner.id, name: requested_owner.name,
email: requested_owner.email }]
)
end

it 'is sent to the previous owner' do
expect(email.to).to eq([requested_owner.email])
end

it 'includes the previous owner\'s name in the body' do
expect(email.body.to_s).to include(requested_owner.name)
end

it 'includes the school name in the body' do
expect(email.body.to_s).to include(ownership_transfer.school.name)
end

it 'includes the school name in the subject' do
expect(email.subject).to include(ownership_transfer.school.name)
end

context 'when the previous owner is missing from the user-info response' do
before do
stub_user_info_api_fetch_by_ids(
user_ids: [nominee.id, requested_owner.id],
users: [{ id: nominee.id, name: nominee.name }]
)
end

it 'greets them generically instead of leaving the greeting blank' do
expect(email.body.to_s).to include('Hi there,')
end
end
end

describe 'decline_ownership_transfer_previous_owner' do
subject(:email) { described_class.with(ownership_transfer:).decline_ownership_transfer_previous_owner }

let(:school) { create(:verified_school) }
let(:nominee) { create(:teacher, school:) }
let(:requested_owner) { create(:owner, school:) }
let(:ownership_transfer) do
create(
:ownership_transfer,
school:,
nominated_user_id: nominee.id,
requested_by_user_id: requested_owner.id,
status: :rejected
)
end

before do
stub_user_info_api_fetch_by_ids(
user_ids: [nominee.id, requested_owner.id],
users: [{ id: nominee.id, name: nominee.name }, { id: requested_owner.id, name: requested_owner.name,
email: requested_owner.email }]
)
end

it 'is sent to the previous owner' do
expect(email.to).to eq([requested_owner.email])
end

it 'includes the previous owner\'s name in the body' do
expect(email.body.to_s).to include(requested_owner.name)
end

it 'includes the school name in the body' do
expect(email.body.to_s).to include(ownership_transfer.school.name)
end

it 'includes the school name in the subject' do
expect(email.subject).to include(ownership_transfer.school.name)
end

context 'when the previous owner is missing from the user-info response' do
before do
stub_user_info_api_fetch_by_ids(
user_ids: [nominee.id, requested_owner.id],
users: [{ id: nominee.id, name: nominee.name }]
)
end

it 'greets them generically instead of leaving the greeting blank' do
expect(email.body.to_s).to include('Hi there,')
end
end
end
end
74 changes: 71 additions & 3 deletions spec/models/ownership_transfer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,9 @@
end

it 'is not enqueued when the transfer resolves to a different status' do
assert_no_enqueued_emails do
expect do
ownership_transfer.update!(status: :rejected)
end
end.not_to have_enqueued_mail(SchoolOwnershipMailer, :cancel_ownership_transfer)
end

it 'is not enqueued when an already-cancelled transfer is saved again unchanged' do
Expand Down Expand Up @@ -220,10 +220,44 @@
end

it 'is not enqueued when the transfer resolves to a different status' do
assert_no_enqueued_emails do
expect do
ownership_transfer.update!(status: :rejected)
end.not_to have_enqueued_mail(SchoolOwnershipMailer, :complete_ownership_transfer)
end

it 'is not enqueued when an already-completed transfer is saved again unchanged' do
ownership_transfer.update!(status: :completed)

assert_no_enqueued_emails do
ownership_transfer.update!(status: :completed)
end
end

it 'is not enqueued when a non-pending transfer is corrected to completed' do
ownership_transfer.update!(status: :rejected)

assert_no_enqueued_emails do
ownership_transfer.update!(status: :completed)
end
end
end

describe 'the completion email to the previous owner' do
before { ownership_transfer.save! }

it 'is enqueued with the transfer as the mailer param when the transfer completes' do
ownership_transfer.update!(status: :completed)

assert_enqueued_email_with(
SchoolOwnershipMailer, :complete_ownership_transfer_previous_owner, params: { ownership_transfer: }
)
end

it 'is not enqueued when the transfer resolves to a different status' do
expect do
ownership_transfer.update!(status: :rejected)
end.not_to have_enqueued_mail(SchoolOwnershipMailer, :complete_ownership_transfer_previous_owner)
end

it 'is not enqueued when an already-completed transfer is saved again unchanged' do
ownership_transfer.update!(status: :completed)
Expand All @@ -241,4 +275,38 @@
end
end
end

describe 'the decline email to the previous owner' do
before { ownership_transfer.save! }

it 'is enqueued with the transfer as the mailer param when the transfer is declined' do
ownership_transfer.update!(status: :rejected)

assert_enqueued_email_with(
SchoolOwnershipMailer, :decline_ownership_transfer_previous_owner, params: { ownership_transfer: }
)
end

it 'is not enqueued when the transfer resolves to a different status' do
expect do
ownership_transfer.update!(status: :completed)
end.not_to have_enqueued_mail(SchoolOwnershipMailer, :decline_ownership_transfer_previous_owner)
end

it 'is not enqueued when an already-declined transfer is saved again unchanged' do
ownership_transfer.update!(status: :rejected)

assert_no_enqueued_emails do
ownership_transfer.update!(status: :rejected)
end
end

it 'is not enqueued when a non-pending transfer is corrected to rejected' do
ownership_transfer.update!(status: :completed)

assert_no_enqueued_emails do
ownership_transfer.update!(status: :rejected)
end
end
end
end
Loading