diff --git a/app/lib/campaigns/send.rb b/app/lib/campaigns/send.rb index 679b1a18..bb974301 100644 --- a/app/lib/campaigns/send.rb +++ b/app/lib/campaigns/send.rb @@ -12,7 +12,7 @@ def initialize(campaign) def call return if campaign.delivered_at.present? - Membership.current.each do |membership| + memberships.each do |membership| delivery = delivery_for membership next if delivery.delivered_at.present? @@ -38,6 +38,10 @@ def delivery_for(membership) ) end + def memberships + Membership.current + end + def ics return nil if rsvp_event.nil? diff --git a/app/lib/campaigns/test.rb b/app/lib/campaigns/test.rb new file mode 100644 index 00000000..334cbe7b --- /dev/null +++ b/app/lib/campaigns/test.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class Campaigns::Test < Campaigns::Send + private + + def memberships + Membership.where(user: User.committee) + end +end diff --git a/app/models/user.rb b/app/models/user.rb index c468fc51..a2ae274b 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -15,6 +15,7 @@ class User < ApplicationRecord end.join(" OR ") ) } + scope :committee, -> { where(committee: true) } attr_accessor :skip_subscriptions diff --git a/lib/tasks/campaigns.rake b/lib/tasks/campaigns.rake index 616a0644..2787a762 100644 --- a/lib/tasks/campaigns.rake +++ b/lib/tasks/campaigns.rake @@ -5,4 +5,9 @@ namespace :campaigns do task send: :environment do Campaigns::Send.call Campaign.find(ENV["CAMPAIGN_ID"]) end + + desc "Only send emails to committee users for a given campaign" + task test: :environment do + Campaigns::Test.call Campaign.find(ENV["CAMPAIGN_ID"]) + end end diff --git a/spec/factories/campaign_deliveries.rb b/spec/factories/campaign_deliveries.rb new file mode 100644 index 00000000..b09f1040 --- /dev/null +++ b/spec/factories/campaign_deliveries.rb @@ -0,0 +1,7 @@ +FactoryBot.define do + factory :campaign_delivery do + association :campaign + association :membership + delivered_at { Time.current } + end +end diff --git a/spec/factories/user.rb b/spec/factories/user.rb index 6b295cf6..c29cd672 100644 --- a/spec/factories/user.rb +++ b/spec/factories/user.rb @@ -20,6 +20,10 @@ visible { false } end + trait :committee do + committee { true } + end + after(:create) do |user, _evaluator| if user.confirmed_at user.memberships.create( diff --git a/spec/lib/campaigns/send_spec.rb b/spec/lib/campaigns/send_spec.rb new file mode 100644 index 00000000..24c4757f --- /dev/null +++ b/spec/lib/campaigns/send_spec.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Campaigns::Send do + let(:user) { create(:user) } + let(:campaign) { create(:campaign) } + let(:membership) { user.memberships.first } + let(:campaign_delivery) { create(:campaign_delivery, campaign: campaign, membership: membership) } + + before do + membership + allow(CampaignsMailer).to receive_message_chain(:campaign_email, :deliver_now) + end + + describe '.call' do + subject { described_class.call(campaign) } + + context 'when campaign has already been delivered' do + before do + campaign_delivery + campaign.update!(delivered_at: Time.current) + end + + it 'does not send any emails' do + expect(CampaignsMailer).not_to receive(:campaign_email) + subject + end + end + + context 'when campaign has not been delivered' do + before { campaign.update(delivered_at: nil) } + + context 'and memberships exist' do + it 'sends emails to all memberships' do + expect(CampaignsMailer).to receive(:campaign_email).with(campaign, membership, anything).and_call_original + subject + end + + it 'generate the delivery' do + expect { subject }.to change { CampaignDelivery.count }.by(1) + end + + it 'updates the campaign delivery time' do + subject + expect(CampaignDelivery.first.delivered_at).to be_present + end + end + + context 'and no memberships exist' do + before do + membership.update!(left_at: Time.current) + end + + it 'does not send any emails' do + expect(CampaignsMailer).not_to receive(:campaign_email) + subject + end + end + end + end +end diff --git a/spec/lib/campaigns/test_spec.rb b/spec/lib/campaigns/test_spec.rb new file mode 100644 index 00000000..c2fdb80e --- /dev/null +++ b/spec/lib/campaigns/test_spec.rb @@ -0,0 +1,30 @@ +require 'rails_helper' + +RSpec.describe Campaigns::Test do + subject { described_class } + + let(:committee_users) { create_list(:user, 3, :committee) } + let(:non_committee_user) { create(:user) } + let(:committee_memberships) { Membership.where(user: committee_users) } + let(:non_committee_membership) { Membership.where(user: non_committee_user) } + let(:campaign) { create(:campaign) } + + before do + committee_memberships + non_committee_membership + allow(CampaignsMailer).to receive_message_chain(:campaign_email, :deliver_now) + end + describe '.call' do + it 'delivers campaign delivery for committee users' do + expect do + subject.call(campaign) + end.to change { CampaignDelivery.where(membership: committee_memberships).count }.by(3) + end + + it 'does not deliver campaign delivery for non-committee users' do + expect do + subject.call(campaign) + end.to change { CampaignDelivery.where(membership: non_committee_membership).count }.by(0) + end + end +end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index bd832225..8aec0c88 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1,4 +1,17 @@ require 'rails_helper' -RSpec.describe User do +RSpec.describe User, type: :model do + let(:unconfirmed_user) { create(:user, confirmed_at: nil) } + let(:committee_user) { create(:user, committee: true) } + + describe '.committee' do + before do + committee_user + unconfirmed_user + end + it 'returns users who are part of the committee' do + expect(User.committee).to include(committee_user) + expect(User.committee).not_to include(unconfirmed_user) + end + end end