From 5ac871b70a6819db096a1f8483b56f54f9b624fc Mon Sep 17 00:00:00 2001 From: Morgan Roderick Date: Fri, 9 Oct 2026 08:45:50 +0200 Subject: [PATCH] test: assert the waiting-list promotion email on reject The reject flow emails the promoted member via WorkshopPresenter#send_attending_email(invitation, true), and no spec asserted any of it (only the resulting invitation state). Pin it: the promoted member receives an attending confirmation, the body uses the promotion copy (only rendered when waiting_list is true; the plain accept copy differs), and exactly one email goes out. The admin-removal call site assertion is out of scope here; it can be added once the feat/post-close-rsvp-waitlist branch merges. --- .../workshop_invitation_controller_spec.rb | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/spec/controllers/workshop_invitation_controller_spec.rb b/spec/controllers/workshop_invitation_controller_spec.rb index 21fbc136d..3aab37dd4 100644 --- a/spec/controllers/workshop_invitation_controller_spec.rb +++ b/spec/controllers/workshop_invitation_controller_spec.rb @@ -8,6 +8,13 @@ before { login(member) } + # The invitation mailer sends multipart/mixed > multipart/alternative > text/html; + # the root body is empty, so read the nested html part. + def html_body(mail) + parts = mail.parts.flat_map { |part| part.multipart? ? part.parts : [part] } + parts.find { |part| part.content_type.match?('text/html') }&.body&.decoded + end + describe 'GET #show' do it 'returns http success' do get :show, params: { id: invitation.token } @@ -169,6 +176,27 @@ post :reject, params: { id: invitation.token } expect(waitlisted_invitation.reload.attending).to be true end + + it 'emails the promoted member a confirmation they are attending' do + post :reject, params: { id: invitation.token } + + mail = ActionMailer::Base.deliveries.find { |m| m.to.include?(waitlisted_member.email) } + expect(mail).not_to be_nil + expect(html_body(mail)).to include('been confirmed') + end + + it 'sends the promotion variant of the email (waiting-list flag set)' do + post :reject, params: { id: invitation.token } + + mail = ActionMailer::Base.deliveries.find { |m| m.to.include?(waitlisted_member.email) } + expect(html_body(mail)).to include('A spot became available and your attendance has now been confirmed!') + end + + it 'does not email anyone else (the rejecting member gets no promotion copy)' do + expect do + post :reject, params: { id: invitation.token } + end.to change { ActionMailer::Base.deliveries.count }.by(1) + end end end