diff --git a/lib/user_segments.rb b/lib/user_segments.rb index 47cd36d13..5ee5bfe49 100644 --- a/lib/user_segments.rb +++ b/lib/user_segments.rb @@ -8,11 +8,11 @@ class UserSegments feasible_and_undecided_investment_authors selected_investment_authors winner_investment_authors - not_supported_on_current_budget].freeze + not_supported_on_current_budget] + geozones.keys end def self.segment_name(segment) - I18n.t("admin.segment_recipient.#{segment}") if segments.include?(segment.to_s) + geozones[segment.to_s]&.name || I18n.t("admin.segment_recipient.#{segment}") if valid_segment?(segment) end def self.all_users @@ -58,11 +58,15 @@ class UserSegments end def self.valid_segment?(segment) - segment && respond_to?(segment) + segments.include?(segment.to_s) end def self.recipients(segment) - send(segment) + if geozones[segment.to_s] + all_users.where(geozone: geozones[segment.to_s]) + else + send(segment) + end end def self.user_segment_emails(segment) @@ -78,4 +82,8 @@ class UserSegments def self.author_ids(author_ids) all_users.where(id: author_ids) end + + def self.geozones + Geozone.order(:name).map { |geozone| [geozone.name.parameterize.underscore, geozone] }.to_h + end end diff --git a/spec/lib/user_segments_spec.rb b/spec/lib/user_segments_spec.rb index 906827d7e..4aa454cbe 100644 --- a/spec/lib/user_segments_spec.rb +++ b/spec/lib/user_segments_spec.rb @@ -19,6 +19,26 @@ describe UserSegments do it "returns nil for invalid segments" do expect(UserSegments.segment_name("invalid")).to be nil end + + context "with geozones in the database" do + before do + create(:geozone, name: "Lands and Borderlands") + create(:geozone, name: "Lowlands and Highlands") + end + + it "returns geozone names when the geozone exists" do + expect(UserSegments.segment_name("lands_and_borderlands")).to eq "Lands and Borderlands" + expect(UserSegments.segment_name("lowlands_and_highlands")).to eq "Lowlands and Highlands" + end + + it "returns regular segments when the geozone doesn't exist" do + expect(UserSegments.segment_name("all_users")).to eq "All users" + end + + it "returns nil for invalid segments" do + expect(UserSegments.segment_name("invalid")).to be nil + end + end end describe ".valid_segment?" do @@ -41,6 +61,30 @@ describe UserSegments do it "is falsey when nil is passed" do expect(UserSegments.valid_segment?(nil)).to be_falsey end + + context "with geozones in the database" do + before do + create(:geozone, name: "Lands and Borderlands") + create(:geozone, name: "Lowlands and Highlands") + end + + it "returns true when the geozone exists" do + expect(UserSegments.valid_segment?("lands_and_borderlands")).to be true + expect(UserSegments.valid_segment?("lowlands_and_highlands")).to be true + end + + it "returns true when the segment exists" do + expect(UserSegments.valid_segment?("all_users")).to be true + end + + it "is falsey when the segment doesn't exist" do + expect(UserSegments.valid_segment?("imaginary_segment")).to be_falsey + end + + it "is falsey when nil is passed" do + expect(UserSegments.valid_segment?(nil)).to be_falsey + end + end end describe ".all_users" do @@ -256,4 +300,40 @@ describe UserSegments do expect(emails).to eq ["first@email.com", "last@email.com"] end end + + context "Geozones" do + let!(:new_york) { create(:geozone, name: "New York") } + let!(:california) { create(:geozone, name: "California") } + let!(:user1) { create(:user, geozone: new_york) } + let!(:user2) { create(:user, geozone: new_york) } + let!(:user3) { create(:user, geozone: california) } + + before do + create(:geozone, name: "Mars") + create(:user, geozone: nil) + end + + it "includes geozones in available segments" do + expect(UserSegments.segments).to include("new_york") + expect(UserSegments.segments).to include("california") + expect(UserSegments.segments).to include("mars") + expect(UserSegments.segments).not_to include("jupiter") + end + + it "returns users of a geozone" do + expect(UserSegments.recipients("new_york")).to match_array [user1, user2] + expect(UserSegments.recipients("california")).to eq [user3] + end + + it "accepts symbols as parameters" do + expect(UserSegments.recipients(:new_york)).to match_array [user1, user2] + expect(UserSegments.recipients(:california)).to eq [user3] + end + + it "only returns active users of a geozone" do + user2.update!(erased_at: Time.current) + + expect(UserSegments.recipients("new_york")).to eq [user1] + end + end end diff --git a/spec/system/admin/emails/newsletters_spec.rb b/spec/system/admin/emails/newsletters_spec.rb index 3af4f19d1..1dcbaf4c5 100644 --- a/spec/system/admin/emails/newsletters_spec.rb +++ b/spec/system/admin/emails/newsletters_spec.rb @@ -160,16 +160,29 @@ describe "Admin newsletter emails", :admin do end end - scenario "Select list of users to send newsletter" do - UserSegments.segments.each do |segment| - segment_recipient = UserSegments.segment_name(segment) + describe "Select list of users to send newsletter" do + scenario "Custom user segments" do + UserSegments.segments.each do |segment| + segment_recipient = UserSegments.segment_name(segment) + + visit new_admin_newsletter_path + + fill_in_newsletter_form(segment_recipient: segment_recipient) + click_button "Create Newsletter" + + expect(page).to have_content segment_recipient + end + end + + scenario "Geozone segments" do + create(:geozone, name: "Queens and Brooklyn") visit new_admin_newsletter_path - fill_in_newsletter_form(segment_recipient: segment_recipient) + fill_in_newsletter_form(segment_recipient: "Queens and Brooklyn") click_button "Create Newsletter" - expect(page).to have_content segment_recipient + expect(page).to have_content "Queens and Brooklyn" end end end