From 27599b1bca587ec248780c6d26f26816e2d44a30 Mon Sep 17 00:00:00 2001 From: Elizabeth Prescott Date: Sat, 29 Aug 2026 11:38:34 -0400 Subject: [PATCH 1/8] Reminders toggle at the model level. Preserve behavior for existing orgs --- app/models/organization.rb | 2 ++ ...0_add_reminder_toggles_to_organizations.rb | 24 +++++++++++++++++++ db/schema.rb | 4 +++- spec/factories/organizations.rb | 2 ++ spec/models/organization_spec.rb | 16 +++++++++++++ 5 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20260829112930_add_reminder_toggles_to_organizations.rb diff --git a/app/models/organization.rb b/app/models/organization.rb index d6020c521e..e60c03d35e 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -6,8 +6,10 @@ # bank_is_set_up :boolean default(FALSE), not null # city :string # deadline_day :integer +# deadline_reminders_enabled :boolean default(FALSE), not null # default_storage_location :integer # distribute_monthly :boolean default(FALSE), not null +# distribution_reminders_enabled :boolean default(FALSE), not null # email :string # enable_child_based_requests :boolean default(TRUE), not null # enable_individual_requests :boolean default(TRUE), not null diff --git a/db/migrate/20260829112930_add_reminder_toggles_to_organizations.rb b/db/migrate/20260829112930_add_reminder_toggles_to_organizations.rb new file mode 100644 index 0000000000..5240ebfabd --- /dev/null +++ b/db/migrate/20260829112930_add_reminder_toggles_to_organizations.rb @@ -0,0 +1,24 @@ +class AddReminderTogglesToOrganizations < ActiveRecord::Migration[8.1] + def up + add_column :organizations, :deadline_reminders_enabled, :boolean, null: false, default: false + add_column :organizations, :distribution_reminders_enabled, :boolean, null: false, default: false + + # Preserve current behavior for organizations that already have any reminder + # configuration. New organizations opt in explicitly via their settings. + configured_ids = Set.new + configured_ids.merge Organization.where.not(reminder_schedule_definition: nil).ids + configured_ids.merge Organization.where.not(deadline_day: nil).ids + configured_ids.merge Organization.where.not(reminder_day: nil).ids + configured_ids.merge Organization.joins(:partners).where(partners: {send_reminders: true}).distinct.ids + configured_ids.merge Organization.joins(:partner_groups).where(partner_groups: {send_reminders: true}).distinct.ids + configured_ids.merge Organization.joins(:distributions).where(distributions: {reminder_email_enabled: true}).distinct.ids + + Organization.where(id: configured_ids.to_a) + .update_all(deadline_reminders_enabled: true, distribution_reminders_enabled: true) + end + + def down + remove_column :organizations, :distribution_reminders_enabled + remove_column :organizations, :deadline_reminders_enabled + end +end diff --git a/db/schema.rb b/db/schema.rb index 4e085b36df..60e9900e35 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.1].define(version: 2026_06_12_130000) do +ActiveRecord::Schema[8.1].define(version: 2026_08_29_112930) do # These are extensions that must be enabled in order to support this database enable_extension "pg_catalog.plpgsql" @@ -469,8 +469,10 @@ t.string "city" t.datetime "created_at", precision: nil, null: false t.integer "deadline_day" + t.boolean "deadline_reminders_enabled", default: false, null: false t.integer "default_storage_location" t.boolean "distribute_monthly", default: false, null: false + t.boolean "distribution_reminders_enabled", default: false, null: false t.string "email" t.boolean "enable_child_based_requests", default: true, null: false t.boolean "enable_individual_requests", default: true, null: false diff --git a/spec/factories/organizations.rb b/spec/factories/organizations.rb index fa35788030..bcfe8fe8c2 100644 --- a/spec/factories/organizations.rb +++ b/spec/factories/organizations.rb @@ -6,8 +6,10 @@ # bank_is_set_up :boolean default(FALSE), not null # city :string # deadline_day :integer +# deadline_reminders_enabled :boolean default(FALSE), not null # default_storage_location :integer # distribute_monthly :boolean default(FALSE), not null +# distribution_reminders_enabled :boolean default(FALSE), not null # email :string # enable_child_based_requests :boolean default(TRUE), not null # enable_individual_requests :boolean default(TRUE), not null diff --git a/spec/models/organization_spec.rb b/spec/models/organization_spec.rb index 854469d18f..cd2e2aaf1d 100644 --- a/spec/models/organization_spec.rb +++ b/spec/models/organization_spec.rb @@ -6,8 +6,10 @@ # bank_is_set_up :boolean default(FALSE), not null # city :string # deadline_day :integer +# deadline_reminders_enabled :boolean default(FALSE), not null # default_storage_location :integer # distribute_monthly :boolean default(FALSE), not null +# distribution_reminders_enabled :boolean default(FALSE), not null # email :string # enable_child_based_requests :boolean default(TRUE), not null # enable_individual_requests :boolean default(TRUE), not null @@ -100,6 +102,20 @@ end end + describe "reminder toggles" do + it "defaults deadline_reminders_enabled to false for a new organization" do + expect(Organization.new.deadline_reminders_enabled).to be false + expect(build(:organization).deadline_reminders_enabled).to be false + expect(create(:organization).reload.deadline_reminders_enabled).to be false + end + + it "defaults distribution_reminders_enabled to false for a new organization" do + expect(Organization.new.distribution_reminders_enabled).to be false + expect(build(:organization).distribution_reminders_enabled).to be false + expect(create(:organization).reload.distribution_reminders_enabled).to be false + end + end + context "Associations >" do it { should have_many(:item_categories) } it { should have_many(:product_drive_tags) } From 1ba2aa86240e5f49312df0974044bfb280169e94 Mon Sep 17 00:00:00 2001 From: Elizabeth Prescott Date: Sat, 29 Aug 2026 12:49:11 -0400 Subject: [PATCH 2/8] Controller and org-level views of disable toggle --- app/controllers/admin/organizations_controller.rb | 1 + app/controllers/organizations_controller.rb | 1 + app/views/organizations/_details.html.erb | 12 ++++++++++++ app/views/organizations/edit.html.erb | 2 ++ spec/requests/organization_requests_spec.rb | 13 +++++++++++++ spec/system/organization_system_spec.rb | 10 ++++++++++ 6 files changed, 39 insertions(+) diff --git a/app/controllers/admin/organizations_controller.rb b/app/controllers/admin/organizations_controller.rb index 65771b5e1b..a26861fa6e 100644 --- a/app/controllers/admin/organizations_controller.rb +++ b/app/controllers/admin/organizations_controller.rb @@ -73,6 +73,7 @@ def organization_params params.require(:organization) .permit(:name, :street, :city, :state, :zipcode, :email, :url, :logo, :intake_location, :default_email_text, :account_request_id, :bank_is_set_up, :reminder_schedule_definition, :deadline_day, + :deadline_reminders_enabled, :distribution_reminders_enabled, users_attributes: %i(name email organization_admin), account_request_attributes: %i(ndbn_member_id id)) end diff --git a/app/controllers/organizations_controller.rb b/app/controllers/organizations_controller.rb index 23677bc92f..8bc30a4b3d 100644 --- a/app/controllers/organizations_controller.rb +++ b/app/controllers/organizations_controller.rb @@ -102,6 +102,7 @@ def organization_params :ytd_on_distribution_printout, :one_step_partner_invite, :hide_value_columns_on_receipt, :hide_package_column_on_receipt, :signature_for_distribution_pdf, :receive_email_on_requests, + :deadline_reminders_enabled, :distribution_reminders_enabled, :bank_is_set_up, :include_in_kind_values_in_exported_files, :include_packages_in_distribution_export, diff --git a/app/views/organizations/_details.html.erb b/app/views/organizations/_details.html.erb index c406f604d6..66ca93c52e 100644 --- a/app/views/organizations/_details.html.erb +++ b/app/views/organizations/_details.html.erb @@ -175,6 +175,18 @@

Other emails

+
+
Send monthly deadline reminder emails to partners?
+

+ <%= humanize_boolean(@organization.deadline_reminders_enabled) %> +

+
+
+
Send day-before distribution reminder emails to partners?
+

+ <%= humanize_boolean(@organization.distribution_reminders_enabled) %> +

+
Reminder emails are sent

diff --git a/app/views/organizations/edit.html.erb b/app/views/organizations/edit.html.erb index b3618e4e34..9318a851d5 100644 --- a/app/views/organizations/edit.html.erb +++ b/app/views/organizations/edit.html.erb @@ -151,6 +151,8 @@


Other emails

+ <%= f.input :deadline_reminders_enabled, label: 'Send monthly deadline reminder emails to partners?', as: :radio_buttons, collection: [[true, 'Yes'], [false, 'No']], label_method: :second, value_method: :first %> + <%= f.input :distribution_reminders_enabled, label: 'Send day-before distribution reminder emails to partners?', as: :radio_buttons, collection: [[true, 'Yes'], [false, 'No']], label_method: :second, value_method: :first %> <%= render 'shared/deadline_day_fields', parent_form: f, parent_object: current_organization %> <% default_reminder_email_text_hint = "You can use the variable %{partner_name} to include the partner's name in the message." %> <%= f.input :reminder_email_text, label: "Additional text for reminder email", hint: default_reminder_email_text_hint.html_safe do %> diff --git a/spec/requests/organization_requests_spec.rb b/spec/requests/organization_requests_spec.rb index 1c31a53f1e..70c057429b 100644 --- a/spec/requests/organization_requests_spec.rb +++ b/spec/requests/organization_requests_spec.rb @@ -348,6 +348,19 @@ end end + context "toggles the reminder email settings" do + let(:update_param) do + { organization: { deadline_reminders_enabled: true, distribution_reminders_enabled: false } } + end + + it "persists both flags" do + subject + organization.reload + expect(organization.deadline_reminders_enabled).to be true + expect(organization.distribution_reminders_enabled).to be false + end + end + context "updates repackage essentials setting" do let(:update_param) { { organization: { repackage_essentials: true } } } it "works" do diff --git a/spec/system/organization_system_spec.rb b/spec/system/organization_system_spec.rb index d3c351e1c9..e76c4fe671 100644 --- a/spec/system/organization_system_spec.rb +++ b/spec/system/organization_system_spec.rb @@ -125,6 +125,16 @@ def post_form_submit expect(page).to have_content("No") end + it 'can toggle the monthly deadline and day-before distribution reminder emails' do + choose('organization[deadline_reminders_enabled]', option: true) + choose('organization[distribution_reminders_enabled]', option: true) + + click_on "Save" + expect(page).to have_content("Updated your organization!") + expect(organization.reload.deadline_reminders_enabled).to be true + expect(organization.distribution_reminders_enabled).to be true + end + it 'can set a default storage location on the organization' do select(storage_location.name, from: 'Default Storage Location') From 4314008101fafb5b973e7ddd8ee2352b22077c36 Mon Sep 17 00:00:00 2001 From: Elizabeth Prescott Date: Sat, 29 Aug 2026 14:22:48 -0400 Subject: [PATCH 3/8] Enforce organization reminder toggles in the email paths Suppress reminder emails when the organization has turned them off: - Monthly deadline reminders: FetchPartnersToRemindNowService now filters both the partner-group and organization-schedule branches by organizations.deadline_reminders_enabled. - Day-before distribution reminders: DistributionsController#schedule_reminder_email skips scheduling, and DistributionMailer#reminder_email refuses to send, when organizations.distribution_reminders_enabled is false (the mailer guard also covers jobs enqueued before the toggle was flipped). Specs that exercise reminder delivery opt their organization in explicitly (the column defaults to false); organization_system_spec's deadline form examples move under a "with monthly deadline reminders enabled" context. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01L9a171otfu6xuQgU7XYjN1 --- app/controllers/distributions_controller.rb | 2 +- app/mailers/distribution_mailer.rb | 1 + .../fetch_partners_to_remind_now_service.rb | 4 +- .../distributions_controller_spec.rb | 14 +++++ spec/mailers/distribution_mailer_spec.rb | 15 +++++ ...tch_partners_to_remind_now_service_spec.rb | 24 ++++++++ spec/system/distribution_system_spec.rb | 1 + spec/system/organization_system_spec.rb | 57 +++++++++++-------- spec/system/partner_system_spec.rb | 1 + 9 files changed, 94 insertions(+), 25 deletions(-) diff --git a/app/controllers/distributions_controller.rb b/app/controllers/distributions_controller.rb index afe636a89e..6328d0b80b 100644 --- a/app/controllers/distributions_controller.rb +++ b/app/controllers/distributions_controller.rb @@ -293,7 +293,7 @@ def send_notification(org, dist, subject: 'Your Distribution', distribution_chan end def schedule_reminder_email(distribution) - return if distribution.past? || !distribution.partner.send_reminders + return if distribution.past? || !distribution.partner.send_reminders || !distribution.organization.distribution_reminders_enabled DistributionMailer.reminder_email(distribution.id).deliver_later(wait_until: distribution.issued_at - 1.day) end diff --git a/app/mailers/distribution_mailer.rb b/app/mailers/distribution_mailer.rb index d1afad34f0..c3148495ad 100644 --- a/app/mailers/distribution_mailer.rb +++ b/app/mailers/distribution_mailer.rb @@ -45,6 +45,7 @@ def reminder_email(distribution_id) requester_email = distribution.request ? distribution.request.requester.email : @partner.email return if @distribution.past? || !@partner.send_reminders || @partner.deactivated? + return unless @distribution.organization.distribution_reminders_enabled mail(to: requester_email, cc: @partner.email, subject: "#{@partner.name} Distribution Reminder") end diff --git a/app/services/partners/fetch_partners_to_remind_now_service.rb b/app/services/partners/fetch_partners_to_remind_now_service.rb index ed96f1f851..8bffd579c2 100644 --- a/app/services/partners/fetch_partners_to_remind_now_service.rb +++ b/app/services/partners/fetch_partners_to_remind_now_service.rb @@ -4,9 +4,10 @@ def fetch current_day = Time.current deactivated_status = ::Partner.statuses[:deactivated] - partners_with_group_reminders = ::Partner.left_joins(:partner_group) + partners_with_group_reminders = ::Partner.left_joins(:partner_group, :organization) .where.not(partner_groups: {reminder_schedule_definition: nil}) .where.not(partner_groups: {deadline_day: nil}) + .where(organizations: {deadline_reminders_enabled: true}) .where.not(status: deactivated_status) # where partner groups have reminder schedule match @@ -17,6 +18,7 @@ def fetch partners_with_only_organization_reminders = ::Partner.left_joins(:partner_group, :organization) .where(partner_groups: {reminder_schedule_definition: nil}) .where(send_reminders: true) + .where(organizations: {deadline_reminders_enabled: true}) .where.not(organizations: {deadline_day: nil}) .where.not(organizations: {reminder_schedule_definition: nil}) .where.not(status: deactivated_status) diff --git a/spec/controllers/distributions_controller_spec.rb b/spec/controllers/distributions_controller_spec.rb index 4a6ae7723e..2e6afafd49 100644 --- a/spec/controllers/distributions_controller_spec.rb +++ b/spec/controllers/distributions_controller_spec.rb @@ -240,6 +240,7 @@ context "when partner has enabled send_reminders" do before(:each) do partner.send_reminders = true + organization.update!(distribution_reminders_enabled: true) end it "should schedule the reminder email" do subject @@ -261,6 +262,18 @@ expect(enqueued_jobs.size).to eq(0) end end + + context "when the partner has send_reminders enabled but the organization has disabled distribution reminders" do + before do + partner.update!(send_reminders: true) + organization.update!(distribution_reminders_enabled: false) + end + + it "should not schedule an email reminder" do + subject + expect(enqueued_jobs.map { |job| job["arguments"][1] }).not_to include("reminder_email") + end + end end end @@ -416,6 +429,7 @@ context "when partner has enabled send_reminders" do before(:each) do partner.send_reminders = true + organization.update!(distribution_reminders_enabled: true) end it "should schedule the reminder email" do subject diff --git a/spec/mailers/distribution_mailer_spec.rb b/spec/mailers/distribution_mailer_spec.rb index 12e7ac147a..7e15fd9ad2 100644 --- a/spec/mailers/distribution_mailer_spec.rb +++ b/spec/mailers/distribution_mailer_spec.rb @@ -143,6 +143,9 @@ describe "#reminder_email" do let(:mail) { DistributionMailer.reminder_email(distribution.id) } + # New organizations have reminders disabled by default; opt in for these specs. + before { organization.update!(distribution_reminders_enabled: true) } + context 'HTML format' do it "renders the body with organization's email text" do html = html_body(mail) @@ -180,5 +183,17 @@ expect(mail.body.encoded).to match("delivery") end end + + context "when the organization has disabled distribution reminders" do + before do + partner.update!(send_reminders: true) + organization.update!(distribution_reminders_enabled: false) + end + + it "does not send the reminder even though the partner has send_reminders enabled" do + expect(mail.body).to be_blank + expect(mail.to).to be_nil + end + end end end diff --git a/spec/services/partners/fetch_partners_to_remind_now_service_spec.rb b/spec/services/partners/fetch_partners_to_remind_now_service_spec.rb index cba44f2bfc..34b387eaee 100644 --- a/spec/services/partners/fetch_partners_to_remind_now_service_spec.rb +++ b/spec/services/partners/fetch_partners_to_remind_now_service_spec.rb @@ -6,6 +6,9 @@ context "when there is a partner" do let!(:partner) { create(:partner) } + # New organizations have reminders disabled by default; these specs exercise + # the scheduling logic, so opt the partner's organization in. + before { partner.organization.update(deadline_reminders_enabled: true) } context "that has an organization with a global reminder & deadline" do context "that is for today" do before do @@ -57,6 +60,17 @@ expect(subject).not_to include(partner) end end + + context "but the organization has disabled deadline reminders" do + before do + partner.update!(send_reminders: true) + partner.organization.update(deadline_reminders_enabled: false) + end + + it "should NOT include that partner even though the partner has send_reminders enabled" do + expect(subject).not_to include(partner) + end + end end context "that is not for today" do @@ -154,6 +168,16 @@ expect(subject).to include(partner) end end + + context "but the organization has disabled deadline reminders" do + before do + partner.organization.update(deadline_reminders_enabled: false) + end + + it "should NOT include that partner" do + expect(subject).not_to include(partner) + end + end end context "that is not for today" do diff --git a/spec/system/distribution_system_spec.rb b/spec/system/distribution_system_spec.rb index b88bb87828..4964a1eb69 100644 --- a/spec/system/distribution_system_spec.rb +++ b/spec/system/distribution_system_spec.rb @@ -365,6 +365,7 @@ end it "sends an email if reminders are enabled" do + user.organization.update!(distribution_reminders_enabled: true) job = double('fake_job') allow(DistributionMailer).to receive(:reminder_email).and_return(job) allow(job).to receive(:deliver_later) diff --git a/spec/system/organization_system_spec.rb b/spec/system/organization_system_spec.rb index e76c4fe671..4c6eb141b8 100644 --- a/spec/system/organization_system_spec.rb +++ b/spec/system/organization_system_spec.rb @@ -71,37 +71,48 @@ def post_form_submit expect(page.find(".alert")).to have_content "Updated your organization!" end - it_behaves_like "deadline and reminder form", "organization", "Save", :post_form_submit + # Monthly deadline reminders are off by default; opt in before exercising + # the reminder schedule. A page refresh resets the radio, so re-select Yes. + def choose_deadline_reminders_yes + choose('organization[deadline_reminders_enabled]', option: true) + end - it "the deadline day form's reminder and deadline dates are consistent with the dates calculated by the FetchPartnersToRemindNowService and DeadlineService" do - travel_to Time.zone.local(2025, 9, 30) - refresh - choose "Day of Month" - fill_in "organization_reminder_schedule_service_day_of_month", with: safe_add_days(Time.zone.now, 1).day - fill_in "Deadline day in reminder email", with: safe_add_days(Time.zone.now, 2).day + context "with monthly deadline reminders enabled" do + before { choose_deadline_reminders_yes } - reminder_text = find('small[data-deadline-day-target="reminderText"]').text - reminder_text.slice!("Your next reminder date is ") - reminder_text.slice!(".") - shown_recurrence_date = Time.zone.strptime(reminder_text, "%a %b %d %Y") + it_behaves_like "deadline and reminder form", "organization", "Save", :post_form_submit, :choose_deadline_reminders_yes - deadline_text = find('small[data-deadline-day-target="deadlineText"]').text - deadline_text.slice!("The deadline on your next reminder email will be ") - deadline_text.slice!(".") - shown_deadline_date = Time.zone.strptime(deadline_text, "%a %b %d %Y") + it "the deadline day form's reminder and deadline dates are consistent with the dates calculated by the FetchPartnersToRemindNowService and DeadlineService" do + travel_to Time.zone.local(2025, 9, 30) + refresh + choose_deadline_reminders_yes + choose "Day of Month" + fill_in "organization_reminder_schedule_service_day_of_month", with: safe_add_days(Time.zone.now, 1).day + fill_in "Deadline day in reminder email", with: safe_add_days(Time.zone.now, 2).day - click_on "Save" - organization.reload + reminder_text = find('small[data-deadline-day-target="reminderText"]').text + reminder_text.slice!("Your next reminder date is ") + reminder_text.slice!(".") + shown_recurrence_date = Time.zone.strptime(reminder_text, "%a %b %d %Y") + + deadline_text = find('small[data-deadline-day-target="deadlineText"]').text + deadline_text.slice!("The deadline on your next reminder email will be ") + deadline_text.slice!(".") + shown_deadline_date = Time.zone.strptime(deadline_text, "%a %b %d %Y") + + click_on "Save" + organization.reload - expect(Partners::FetchPartnersToRemindNowService.new.fetch).to_not include(partner) + expect(Partners::FetchPartnersToRemindNowService.new.fetch).to_not include(partner) - travel_to shown_recurrence_date + travel_to shown_recurrence_date - expect(Partners::FetchPartnersToRemindNowService.new.fetch).to include(partner) - expect(DeadlineService.new(deadline_day: DeadlineService.get_deadline_for_partner(partner)).next_deadline.in_time_zone(Time.zone)).to be_within(1.second).of shown_deadline_date + expect(Partners::FetchPartnersToRemindNowService.new.fetch).to include(partner) + expect(DeadlineService.new(deadline_day: DeadlineService.get_deadline_for_partner(partner)).next_deadline.in_time_zone(Time.zone)).to be_within(1.second).of shown_deadline_date - expect(page).to have_content("Your next reminder date is #{reminder_text}.") - expect(page).to have_content("The deadline on your next reminder email will be #{deadline_text}.") + expect(page).to have_content("Your next reminder date is #{reminder_text}.") + expect(page).to have_content("The deadline on your next reminder email will be #{deadline_text}.") + end end it 'can select if the org repackages essentials' do diff --git a/spec/system/partner_system_spec.rb b/spec/system/partner_system_spec.rb index d4c9d1d9fe..e6bdf738f6 100644 --- a/spec/system/partner_system_spec.rb +++ b/spec/system/partner_system_spec.rb @@ -776,6 +776,7 @@ def post_refresh it_behaves_like "deadline and reminder form", "partner_group", "Update Partner Group", nil, :post_refresh it "the deadline day form's reminder and deadline dates are consistent with the dates calculated by the FetchPartnersToRemindNowService and DeadlineService" do + partner.organization.update!(deadline_reminders_enabled: true) travel_to Time.zone.local(2025, 9, 30) refresh post_refresh From d229040105987f9733bc4ade485467dbfa8e900a Mon Sep 17 00:00:00 2001 From: Elizabeth Prescott Date: Sat, 29 Aug 2026 14:25:36 -0400 Subject: [PATCH 4/8] Hide reminder-schedule fields when monthly deadline reminders are off There is no reason to configure a reminder schedule when the organization has turned monthly deadline reminders off. - Edit form: new reminder-toggle Stimulus controller shows/hides the shared/_deadline_day_fields partial and the "Additional text for reminder email" box as the Yes/No radio changes. - Read-only details page: the same blocks render only when deadline_reminders_enabled is true. "Distribution email content" and "Receive email when Partner makes a Request?" are not reminder-specific and stay visible. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01L9a171otfu6xuQgU7XYjN1 --- .../controllers/reminder_toggle_controller.js | 23 +++++++ app/views/organizations/_details.html.erb | 60 ++++++++++--------- app/views/organizations/edit.html.erb | 18 +++--- spec/requests/organization_requests_spec.rb | 15 ++++- spec/system/organization_system_spec.rb | 18 +++++- 5 files changed, 95 insertions(+), 39 deletions(-) create mode 100644 app/javascript/controllers/reminder_toggle_controller.js diff --git a/app/javascript/controllers/reminder_toggle_controller.js b/app/javascript/controllers/reminder_toggle_controller.js new file mode 100644 index 0000000000..54085ebd56 --- /dev/null +++ b/app/javascript/controllers/reminder_toggle_controller.js @@ -0,0 +1,23 @@ +import { Controller } from "@hotwired/stimulus" + +/* + * ReminderToggleController shows/hides dependent reminder-schedule fields based + * on the selected value of a Yes/No radio-button group. Used on the organization + * settings form so the reminder schedule and reminder email text are only shown + * when "Send monthly deadline reminder emails?" is set to Yes. + */ +export default class extends Controller { + static targets = ["source", "dependentField"] + + connect() { + this.toggle() + } + + toggle() { + const selected = this.sourceTargets.find((input) => input.checked) + const show = selected?.value === "true" + this.dependentFieldTargets.forEach((field) => { + field.classList.toggle("d-none", !show) + }) + } +} diff --git a/app/views/organizations/_details.html.erb b/app/views/organizations/_details.html.erb index 66ca93c52e..e1a8793549 100644 --- a/app/views/organizations/_details.html.erb +++ b/app/views/organizations/_details.html.erb @@ -187,38 +187,40 @@ <%= humanize_boolean(@organization.distribution_reminders_enabled) %>

-
-
Reminder emails are sent
-

- <%= fa_icon "calendar" %> - <%= @organization.reminder_schedule&.show_description.blank? ? 'Not defined' : @organization.reminder_schedule&.show_description %> - <% if @organization.reminder_schedule.valid? %> + <% if @organization.deadline_reminders_enabled %> +

+
Reminder emails are sent
+

+ <%= fa_icon "calendar" %> + <%= @organization.reminder_schedule&.show_description.blank? ? 'Not defined' : @organization.reminder_schedule&.show_description %> + <% if @organization.reminder_schedule.valid? %> + + <%= "Your next reminder date is #{@organization.reminder_schedule.next_occurrence&.strftime('%a %b %d %Y')}." %> + + <% end %> +

+
+
+
Deadline day in reminder email
+

+ <%= fa_icon "calendar" %> + <%= @organization.deadline_day.blank? ? 'Not defined' : "The #{@organization.deadline_day.ordinalize} after the reminder." %> - <%= "Your next reminder date is #{@organization.reminder_schedule.next_occurrence&.strftime('%a %b %d %Y')}." %> + <% if @organization.deadline_day && @organization.reminder_schedule.valid? %> + <%= "The deadline on your next reminder email will be #{DeadlineService.new( + deadline_day: @organization.deadline_day, + today: @organization.reminder_schedule.next_occurrence).next_deadline&.strftime('%a %b %d %Y')}." %> + <% end %> - <% end %> -

-
-
-
Deadline day in reminder email
-

- <%= fa_icon "calendar" %> - <%= @organization.deadline_day.blank? ? 'Not defined' : "The #{@organization.deadline_day.ordinalize} after the reminder." %> - - <% if @organization.deadline_day && @organization.reminder_schedule.valid? %> - <%= "The deadline on your next reminder email will be #{DeadlineService.new( - deadline_day: @organization.deadline_day, - today: @organization.reminder_schedule.next_occurrence).next_deadline&.strftime('%a %b %d %Y')}." %> - <% end %> - -

-
-
-
Additional text for reminder email
-
- <%= @organization.reminder_email_text.presence || 'Not defined' %> +

-
+
+
Additional text for reminder email
+
+ <%= @organization.reminder_email_text.presence || 'Not defined' %> +
+
+ <% end %>
Distribution email content
diff --git a/app/views/organizations/edit.html.erb b/app/views/organizations/edit.html.erb index 9318a851d5..98f39651c2 100644 --- a/app/views/organizations/edit.html.erb +++ b/app/views/organizations/edit.html.erb @@ -151,13 +151,17 @@

Other emails

- <%= f.input :deadline_reminders_enabled, label: 'Send monthly deadline reminder emails to partners?', as: :radio_buttons, collection: [[true, 'Yes'], [false, 'No']], label_method: :second, value_method: :first %> - <%= f.input :distribution_reminders_enabled, label: 'Send day-before distribution reminder emails to partners?', as: :radio_buttons, collection: [[true, 'Yes'], [false, 'No']], label_method: :second, value_method: :first %> - <%= render 'shared/deadline_day_fields', parent_form: f, parent_object: current_organization %> - <% default_reminder_email_text_hint = "You can use the variable %{partner_name} to include the partner's name in the message." %> - <%= f.input :reminder_email_text, label: "Additional text for reminder email", hint: default_reminder_email_text_hint.html_safe do %> - <%= f.rich_text_area :reminder_email_text, placeholder: 'Enter reminder email content...' %> - <% end %> +
+ <%= f.input :deadline_reminders_enabled, label: 'Send monthly deadline reminder emails to partners?', as: :radio_buttons, collection: [[true, 'Yes'], [false, 'No']], label_method: :second, value_method: :first, input_html: { data: { 'reminder-toggle-target': 'source', action: 'change->reminder-toggle#toggle' } } %> + <%= f.input :distribution_reminders_enabled, label: 'Send day-before distribution reminder emails to partners?', as: :radio_buttons, collection: [[true, 'Yes'], [false, 'No']], label_method: :second, value_method: :first %> +
+ <%= render 'shared/deadline_day_fields', parent_form: f, parent_object: current_organization %> + <% default_reminder_email_text_hint = "You can use the variable %{partner_name} to include the partner's name in the message." %> + <%= f.input :reminder_email_text, label: "Additional text for reminder email", hint: default_reminder_email_text_hint.html_safe do %> + <%= f.rich_text_area :reminder_email_text, placeholder: 'Enter reminder email content...' %> + <% end %> +
+
<% default_email_text_hint = "You can use the variables %{partner_name}, %{delivery_method}, %{distribution_date}, and %{comment} to include the partner's name, delivery method, distribution date, and comments sent in the request." %> <%= f.input :default_email_text, label: "Distribution email content", hint: default_email_text_hint.html_safe do %> <%= f.rich_text_area :default_email_text, placeholder: 'Enter distribution email content...' %> diff --git a/spec/requests/organization_requests_spec.rb b/spec/requests/organization_requests_spec.rb index 70c057429b..6599a9e32d 100644 --- a/spec/requests/organization_requests_spec.rb +++ b/spec/requests/organization_requests_spec.rb @@ -163,7 +163,7 @@ every_nth_month: 1, day_of_month: 20 }).to_ical - organization.update(reminder_schedule_definition: valid_reminder_schedule) + organization.update(reminder_schedule_definition: valid_reminder_schedule, deadline_reminders_enabled: true) end it "reports the next date a reminder email will be sent" do @@ -178,6 +178,19 @@ expect(response.body).to include "Your next reminder date is Tue Oct 20 2020." expect(response.body).to include "The deadline on your next reminder email will be Sun Oct 25 2020." end + + context "but monthly deadline reminders are disabled" do + before do + organization.update!(deadline_day: 25, deadline_reminders_enabled: false) + get organization_path + end + + it "hides the reminder schedule details" do + expect(response.body).not_to include "Reminder emails are sent" + expect(response.body).not_to include "Deadline day in reminder email" + expect(response.body).not_to include "Additional text for reminder email" + end + end end it "cannot see 'Demote to User' button for admins" do diff --git a/spec/system/organization_system_spec.rb b/spec/system/organization_system_spec.rb index 4c6eb141b8..18eded1311 100644 --- a/spec/system/organization_system_spec.rb +++ b/spec/system/organization_system_spec.rb @@ -71,12 +71,26 @@ def post_form_submit expect(page.find(".alert")).to have_content "Updated your organization!" end - # Monthly deadline reminders are off by default; opt in before exercising - # the reminder schedule. A page refresh resets the radio, so re-select Yes. + # The reminder-schedule fields only render when monthly deadline reminders + # are enabled, and the page re-hides them after a refresh, so re-select Yes. def choose_deadline_reminders_yes choose('organization[deadline_reminders_enabled]', option: true) end + it "shows the reminder schedule fields only when monthly deadline reminders are enabled" do + expect(page).to have_content("Send monthly deadline reminder emails to partners?") + expect(page).not_to have_field("Deadline day in reminder email", visible: :visible) + expect(page).not_to have_content("Additional text for reminder email") + + choose_deadline_reminders_yes + expect(page).to have_field("Deadline day in reminder email", visible: :visible) + expect(page).to have_content("Additional text for reminder email") + + choose('organization[deadline_reminders_enabled]', option: false) + expect(page).not_to have_field("Deadline day in reminder email", visible: :visible) + expect(page).not_to have_content("Additional text for reminder email") + end + context "with monthly deadline reminders enabled" do before { choose_deadline_reminders_yes } From b4b8a15157fb997832cc05f1a53cee76aaff16f0 Mon Sep 17 00:00:00 2001 From: Elizabeth Prescott Date: Sat, 29 Aug 2026 14:58:42 -0400 Subject: [PATCH 5/8] Add reminder toggles to the super-admin new organization form A super admin creating an organization can now choose whether to enable the monthly deadline and day-before distribution reminder emails, matching the choice org admins have on their own settings page. The params were already permitted in Admin::OrganizationsController. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01L9a171otfu6xuQgU7XYjN1 --- app/views/admin/organizations/new.html.erb | 2 ++ .../system/admin/organizations_system_spec.rb | 21 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/app/views/admin/organizations/new.html.erb b/app/views/admin/organizations/new.html.erb index c6157177d6..9ef67e148e 100644 --- a/app/views/admin/organizations/new.html.erb +++ b/app/views/admin/organizations/new.html.erb @@ -47,6 +47,8 @@ <%= f.input :city %> <%= f.input :state, collection: us_states, class: "form-control", placeholder: "state" %> <%= f.input :zipcode %> + <%= f.input :deadline_reminders_enabled, label: 'Send monthly deadline reminder emails to partners?', as: :radio_buttons, collection: [[true, 'Yes'], [false, 'No']], label_method: :second, value_method: :first %> + <%= f.input :distribution_reminders_enabled, label: 'Send day-before distribution reminder emails to partners?', as: :radio_buttons, collection: [[true, 'Yes'], [false, 'No']], label_method: :second, value_method: :first %> <%= render 'shared/deadline_day_fields', parent_form: f, parent_object: @organization %> <%= f.simple_fields_for :account_request do |account_request| %> <%= account_request.input :ndbn_member, label: 'NDBN Membership', wrapper: :input_group do %> diff --git a/spec/system/admin/organizations_system_spec.rb b/spec/system/admin/organizations_system_spec.rb index e6797eb84e..44f95ed47a 100644 --- a/spec/system/admin/organizations_system_spec.rb +++ b/spec/system/admin/organizations_system_spec.rb @@ -138,6 +138,26 @@ expect(page).to have_content("invited") end + it "can create an organization with reminders left disabled" do + visit new_admin_organization_path + admin_user_params = attributes_for(:organization_admin) + within "form#new_organization" do + fill_in "organization_name", with: "No Reminders Org" + fill_in "organization_email", with: "no-reminders@example.com" + fill_in "organization_user_name", with: admin_user_params[:name] + fill_in "organization_user_email", with: admin_user_params[:email] + + choose('organization[deadline_reminders_enabled]', option: false) + choose('organization[distribution_reminders_enabled]', option: false) + click_on "Save" + end + + expect(page).to have_content("All Human Essentials Organizations") + org = Organization.find_by(name: "No Reminders Org") + expect(org.deadline_reminders_enabled).to be false + expect(org.distribution_reminders_enabled).to be false + end + it "can view organization details", :aggregate_failures do visit admin_organizations_path @@ -160,6 +180,7 @@ visit new_admin_organization_path within "form#new_organization" do fill_in "organization_name", with: "aaa" # So the new org will be on the first page + choose('organization[deadline_reminders_enabled]', option: true) end end From ae383be4f02c7fed21f07f6c85e67bc2e60e5979 Mon Sep 17 00:00:00 2001 From: Elizabeth Prescott Date: Sat, 29 Aug 2026 14:52:40 -0400 Subject: [PATCH 6/8] Show a "reminders are disabled" notice in reminder-config forms When an organization has turned a reminder type off, the forms that otherwise ask a bank user to configure it now show a notice instead: - Partner group form: replaces the deadline reminder schedule fields. - New/edit distribution form: replaces the "Send email reminder the day before?" checkbox. - Partner form: adds a note beside the "receive emails" checkbox when both reminder types are off. The notice links to the organization settings page for users who can administrate the organization, and otherwise tells them to contact an administrator. New shared partial: shared/_reminders_disabled_notice. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01L9a171otfu6xuQgU7XYjN1 --- app/views/distributions/_form.html.erb | 6 ++++- app/views/partner_groups/_form.html.erb | 24 ++++++++++------- app/views/partners/_form.html.erb | 3 +++ .../_reminders_disabled_notice.html.erb | 27 +++++++++++++++++++ spec/system/distribution_system_spec.rb | 21 +++++++++++++++ spec/system/partner_system_spec.rb | 25 ++++++++++++++++- 6 files changed, 95 insertions(+), 11 deletions(-) create mode 100644 app/views/shared/_reminders_disabled_notice.html.erb diff --git a/app/views/distributions/_form.html.erb b/app/views/distributions/_form.html.erb index 669e2de9b5..ea43d69faa 100644 --- a/app/views/distributions/_form.html.erb +++ b/app/views/distributions/_form.html.erb @@ -23,7 +23,11 @@
<%= f.input :issued_at, as: :datetime, ampm: true, minute_step: 15, label: "Distribution date and time", html5: true, :input_html => { :value => date_place_holder&.strftime("%Y-%m-%dT%0k:%M")} %>
- <%= f.input :reminder_email_enabled, as: :boolean, checked_value: true, unchecked_value: false, label: "Send email reminder the day before?" %> + <% if current_organization.distribution_reminders_enabled %> + <%= f.input :reminder_email_enabled, as: :boolean, checked_value: true, unchecked_value: false, label: "Send email reminder the day before?" %> + <% else %> + <%= render 'shared/reminders_disabled_notice', reminder_type: :distribution %> + <% end %> <%= f.input :agency_rep, label: "Agency representative" %>
diff --git a/app/views/partner_groups/_form.html.erb b/app/views/partner_groups/_form.html.erb index 57ec911265..1163ffdc33 100644 --- a/app/views/partner_groups/_form.html.erb +++ b/app/views/partner_groups/_form.html.erb @@ -20,18 +20,24 @@ <%= f.association :item_categories, collection: @item_categories, as: :check_boxes, label: '' %>
-
+

Do you want to send deadline reminders to them every month?

- <%= f.input :send_reminders, as: :boolean, label: "Yes", input_html: { data: { action: 'click->checkbox-with-nested-element#toggleNestedElementVisibility', 'checkbox-with-nested-element-target': 'checkbox' } } %> + <% if current_organization.deadline_reminders_enabled %> +
+ <%= f.input :send_reminders, as: :boolean, label: "Yes", input_html: { data: { action: 'click->checkbox-with-nested-element#toggleNestedElementVisibility', 'checkbox-with-nested-element-target': 'checkbox' } } %> -
-
-
That's great!
-

You must fill out the details below to send reminders.

-
+
+
+
That's great!
+

You must fill out the details below to send reminders.

+
- <%= render 'shared/deadline_day_fields', parent_form: f, parent_object: @partner_group %> -
+ <%= render 'shared/deadline_day_fields', parent_form: f, parent_object: @partner_group %> +
+
+ <% else %> + <%= render 'shared/reminders_disabled_notice', reminder_type: :deadline %> + <% end %>
diff --git a/app/views/partners/_form.html.erb b/app/views/partners/_form.html.erb index fe8ef9efa1..f6529c2883 100644 --- a/app/views/partners/_form.html.erb +++ b/app/views/partners/_form.html.erb @@ -41,6 +41,9 @@
Reminder

Please note that reminders will be sent out according to the settings of their partner group OR organization. This won't work unless you've set up at least one.

+ <% unless current_organization.deadline_reminders_enabled || current_organization.distribution_reminders_enabled %> + <%= render 'shared/reminders_disabled_notice', reminder_type: :all %> + <% end %>
<%= f.input :quota, label: "Quota", wrapper: :input_group do %> diff --git a/app/views/shared/_reminders_disabled_notice.html.erb b/app/views/shared/_reminders_disabled_notice.html.erb new file mode 100644 index 0000000000..114b41fa18 --- /dev/null +++ b/app/views/shared/_reminders_disabled_notice.html.erb @@ -0,0 +1,27 @@ +<%# + Shown in place of reminder-configuration fields when the organization has + turned the relevant reminder emails off on its settings page. + + Locals: + reminder_type - :deadline, :distribution, or :all +%> +
+
+ <% case reminder_type %> + <% when :distribution %> + Day-before distribution reminder emails are turned off + <% when :all %> + Reminder emails are turned off for your organization + <% else %> + Monthly deadline reminder emails are turned off + <% end %> +
+

+ Your organization has turned this off, so these emails will not be sent. + <% if can_administrate? %> + <%= link_to "Change this in your organization settings", edit_organization_path %>. + <% else %> + Contact your organization administrator to change this. + <% end %> +

+
diff --git a/spec/system/distribution_system_spec.rb b/spec/system/distribution_system_spec.rb index 4964a1eb69..76b2ff589b 100644 --- a/spec/system/distribution_system_spec.rb +++ b/spec/system/distribution_system_spec.rb @@ -320,6 +320,27 @@ visit new_distribution_path expect(page).to have_no_content "Inactive R Us" end + + context "when the organization has disabled day-before distribution reminders" do + before { organization.update!(distribution_reminders_enabled: false) } + + it "replaces the reminder checkbox with a notice, linking an admin to settings" do + sign_in(organization_admin) + visit new_distribution_path + + expect(page).not_to have_field("Send email reminder the day before?") + expect(page).to have_content("Day-before distribution reminder emails are turned off") + expect(page).to have_link("Change this in your organization settings", href: edit_organization_path) + end + + it "tells a non-admin user to contact their administrator" do + visit new_distribution_path + + expect(page).not_to have_field("Send email reminder the day before?") + expect(page).to have_content("Contact your organization administrator") + expect(page).not_to have_link("Change this in your organization settings") + end + end end it "errors if user does not fill storage_location" do diff --git a/spec/system/partner_system_spec.rb b/spec/system/partner_system_spec.rb index e6bdf738f6..1f318b4cfc 100644 --- a/spec/system/partner_system_spec.rb +++ b/spec/system/partner_system_spec.rb @@ -701,6 +701,7 @@ describe 'creating a new partner group' do it 'should allow creating a new partner group with item categories' do + organization.update!(deadline_reminders_enabled: true) travel_to Time.zone.local(2020, 10, 10) visit partners_path @@ -727,6 +728,28 @@ end end + describe 'when the organization has disabled monthly deadline reminders' do + before { organization.update!(deadline_reminders_enabled: false) } + + it 'replaces the reminder schedule fields with a notice linking an admin to settings' do + sign_in(organization_admin) + visit new_partner_group_path + + expect(page).to have_content('Do you want to send deadline reminders to them every month?') + expect(page).not_to have_field('partner_group_reminder_schedule_service_day_of_month') + expect(page).to have_content('Monthly deadline reminder emails are turned off') + expect(page).to have_link('Change this in your organization settings', href: edit_organization_path) + end + + it 'tells a non-admin user to contact their administrator' do + visit new_partner_group_path + + expect(page).to have_content('Monthly deadline reminder emails are turned off') + expect(page).to have_content('Contact your organization administrator') + expect(page).not_to have_link('Change this in your organization settings') + end + end + describe 'editing a existing partner group' do let!(:existing_partner_group) { create(:partner_group, organization: organization) } before do @@ -762,6 +785,7 @@ def post_refresh end before do + organization.update!(deadline_reminders_enabled: true) partner.update!(partner_group: existing_partner_group) visit partners_path @@ -776,7 +800,6 @@ def post_refresh it_behaves_like "deadline and reminder form", "partner_group", "Update Partner Group", nil, :post_refresh it "the deadline day form's reminder and deadline dates are consistent with the dates calculated by the FetchPartnersToRemindNowService and DeadlineService" do - partner.organization.update!(deadline_reminders_enabled: true) travel_to Time.zone.local(2025, 9, 30) refresh post_refresh From e75dd8506676a7dbe66dcd504ca57e9910588a24 Mon Sep 17 00:00:00 2001 From: Elizabeth Prescott Date: Sat, 29 Aug 2026 15:11:49 -0400 Subject: [PATCH 7/8] Backfill reminder toggles to true for all existing organizations Simpler than filtering to only organizations that already have reminder configuration: every organization that exists at migration time keeps reminders on, and only organizations created afterward default to off. Reminder emails still only go out when the org has a schedule configured, so enabling the flag for orgs without one is a no-op. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01L9a171otfu6xuQgU7XYjN1 --- ...12930_add_reminder_toggles_to_organizations.rb | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/db/migrate/20260829112930_add_reminder_toggles_to_organizations.rb b/db/migrate/20260829112930_add_reminder_toggles_to_organizations.rb index 5240ebfabd..0d028c9ed9 100644 --- a/db/migrate/20260829112930_add_reminder_toggles_to_organizations.rb +++ b/db/migrate/20260829112930_add_reminder_toggles_to_organizations.rb @@ -3,18 +3,9 @@ def up add_column :organizations, :deadline_reminders_enabled, :boolean, null: false, default: false add_column :organizations, :distribution_reminders_enabled, :boolean, null: false, default: false - # Preserve current behavior for organizations that already have any reminder - # configuration. New organizations opt in explicitly via their settings. - configured_ids = Set.new - configured_ids.merge Organization.where.not(reminder_schedule_definition: nil).ids - configured_ids.merge Organization.where.not(deadline_day: nil).ids - configured_ids.merge Organization.where.not(reminder_day: nil).ids - configured_ids.merge Organization.joins(:partners).where(partners: {send_reminders: true}).distinct.ids - configured_ids.merge Organization.joins(:partner_groups).where(partner_groups: {send_reminders: true}).distinct.ids - configured_ids.merge Organization.joins(:distributions).where(distributions: {reminder_email_enabled: true}).distinct.ids - - Organization.where(id: configured_ids.to_a) - .update_all(deadline_reminders_enabled: true, distribution_reminders_enabled: true) + # Set the existing orgs value to true. + # This preserves current behavior since emails only get sent if the org already has reminder settings. + Organization.update_all(deadline_reminders_enabled: true, distribution_reminders_enabled: true) end def down From cb85aa5f421ff8257f80287224775e91debc8146 Mon Sep 17 00:00:00 2001 From: Elizabeth Prescott Date: Sat, 29 Aug 2026 15:35:54 -0400 Subject: [PATCH 8/8] Adding guard clause to reminder email when org-level disabled --- app/mailers/reminder_deadline_mailer.rb | 5 +++++ db/schema.rb | 2 +- spec/mailers/reminder_deadline_mailer_spec.rb | 14 +++++++++++++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/app/mailers/reminder_deadline_mailer.rb b/app/mailers/reminder_deadline_mailer.rb index 5df6f382af..009f9bfdcf 100644 --- a/app/mailers/reminder_deadline_mailer.rb +++ b/app/mailers/reminder_deadline_mailer.rb @@ -3,6 +3,11 @@ class ReminderDeadlineMailer < ApplicationMailer def notify_deadline(partner) @partner = partner @organization = partner.organization + + # Do not send even if the partner (or its group) has reminders on when the + # organization has turned monthly deadline reminders off. + return unless @organization.deadline_reminders_enabled + @deadline = deadline_date(partner) reminder_email_text = @organization.reminder_email_text @reminder_email_text_interpolated = TextInterpolatorService.new(reminder_email_text.body.to_s, { diff --git a/db/schema.rb b/db/schema.rb index 881c139e8a..60e9900e35 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.1].define(version: 2026_08_28_150820) do +ActiveRecord::Schema[8.1].define(version: 2026_08_29_112930) do # These are extensions that must be enabled in order to support this database enable_extension "pg_catalog.plpgsql" diff --git a/spec/mailers/reminder_deadline_mailer_spec.rb b/spec/mailers/reminder_deadline_mailer_spec.rb index 5752407de2..d4f2c01d59 100644 --- a/spec/mailers/reminder_deadline_mailer_spec.rb +++ b/spec/mailers/reminder_deadline_mailer_spec.rb @@ -6,11 +6,23 @@ let(:partner) { create(:partner, organization: organization) } before(:each) do organization.reminder_email_text = "Custom reminder message" - organization.update!(deadline_day: 1) + organization.update!(deadline_day: 1, deadline_reminders_enabled: true) end subject { described_class.notify_deadline(partner) } + context 'when the organization has disabled monthly deadline reminders' do + before do + partner.update!(send_reminders: true) + organization.update!(deadline_reminders_enabled: false) + end + + it 'does not send even though the partner has reminders enabled' do + expect(subject.body).to be_blank + expect(subject.to).to be_nil + end + end + it 'renders the subject' do expect(subject.subject).to eq("#{organization.name} Deadline Reminder") end