Implement unsubscribe functionality and add tests for email unsubscription

This commit is contained in:
Brenda Wallace committed 2026-10-31 19:23:52 +13:00
1 parent f7ff9acca3
commit bc5cfafb1c
2 files changed
+56 -2

No files matched your search

+5 -2
View File
@@ -58,10 +58,13 @@ class MembersController < ApplicationController
def unsubscribe
verifier = ActiveSupport::MessageVerifier.new(ENV.fetch('RAILS_SECRET_TOKEN', nil))
decrypted_message = verifier.verify(params[:message])
# The message is JSON, so its keys and the type come back as strings.
decrypted_message = verifier.verify(params[:message]).with_indifferent_access
@member = Member.find(decrypted_message[:member_id])
@type = decrypted_message[:type]
@type = decrypted_message[:type].to_sym
raise ActiveSupport::MessageVerifier::InvalidSignature unless EMAIL_TYPE_STRING.key?(@type)
@member.update(@type => false)
flash.now[:notice] = I18n.t('members.unsubscribed', email_type: EMAIL_TYPE_STRING[@type])
+51
View File
@@ -0,0 +1,51 @@
# frozen_string_literal: true
require 'rails_helper'
describe 'Unsubscribing from emails' do
let(:member) { create(:member) }
let(:verifier) { ActiveSupport::MessageVerifier.new(ENV.fetch('RAILS_SECRET_TOKEN', nil)) }
def link_in(mail, text)
Nokogiri::HTML(mail.body.encoded).css('a').find { |anchor| anchor.text.include?(text) }['href']
end
def unsubscribe_via(mail, text)
get URI(link_in(mail, text)).request_uri
end
context 'with the link in the planting reminder' do
before { unsubscribe_via(NotifierMailer.planting_reminder(member), 'Unsubscribe from planting reminders') }
it { expect(response).to have_http_status(:ok) }
it { expect(response.body).to include 'unsubscribed from planting reminders' }
it { expect(member.reload.send_planting_reminder).to be false }
it { expect(member.reload.send_harvest_reminder).to be true }
it { expect(member.reload.send_notification_email).to be true }
end
context 'with the link in the harvest reminder' do
let(:crop) { create(:crop, median_days_to_first_harvest: 20) }
before do
create(:planting, owner: member, crop:, planted_at: 15.days.ago)
unsubscribe_via(NotifierMailer.harvest_reminder(member), 'Unsubscribe from harvest reminders')
end
it { expect(member.reload.send_harvest_reminder).to be false }
it { expect(member.reload.send_planting_reminder).to be true }
end
context 'with a signed message for a column that is not an email setting' do
before { get unsubscribe_member_path(verifier.generate({ member_id: member.id, type: :email })) }
it { expect(response.body).to include 'there was an error' }
it { expect(member.reload.email).to eq member.email }
end
context 'with a message that was not signed by us' do
before { get unsubscribe_member_path('not-signed') }
it { expect(response.body).to include 'there was an error' }
end
end