Add geozones as user segments

This commit is contained in:
rgarcia
2018-07-24 20:29:09 +02:00
committed by Javi Martín
parent 7a028411ab
commit 25a8950330
3 changed files with 110 additions and 9 deletions

View File

@@ -8,11 +8,11 @@ class UserSegments
feasible_and_undecided_investment_authors feasible_and_undecided_investment_authors
selected_investment_authors selected_investment_authors
winner_investment_authors winner_investment_authors
not_supported_on_current_budget].freeze not_supported_on_current_budget] + geozones.keys
end end
def self.segment_name(segment) 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 end
def self.all_users def self.all_users
@@ -58,12 +58,16 @@ class UserSegments
end end
def self.valid_segment?(segment) def self.valid_segment?(segment)
segment && respond_to?(segment) segments.include?(segment.to_s)
end end
def self.recipients(segment) def self.recipients(segment)
if geozones[segment.to_s]
all_users.where(geozone: geozones[segment.to_s])
else
send(segment) send(segment)
end end
end
def self.user_segment_emails(segment) def self.user_segment_emails(segment)
recipients(segment).newsletter.order(:created_at).pluck(:email).compact recipients(segment).newsletter.order(:created_at).pluck(:email).compact
@@ -78,4 +82,8 @@ class UserSegments
def self.author_ids(author_ids) def self.author_ids(author_ids)
all_users.where(id: author_ids) all_users.where(id: author_ids)
end end
def self.geozones
Geozone.order(:name).map { |geozone| [geozone.name.parameterize.underscore, geozone] }.to_h
end
end end

View File

@@ -19,6 +19,26 @@ describe UserSegments do
it "returns nil for invalid segments" do it "returns nil for invalid segments" do
expect(UserSegments.segment_name("invalid")).to be nil expect(UserSegments.segment_name("invalid")).to be nil
end 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 end
describe ".valid_segment?" do describe ".valid_segment?" do
@@ -41,6 +61,30 @@ describe UserSegments do
it "is falsey when nil is passed" do it "is falsey when nil is passed" do
expect(UserSegments.valid_segment?(nil)).to be_falsey expect(UserSegments.valid_segment?(nil)).to be_falsey
end 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 end
describe ".all_users" do describe ".all_users" do
@@ -256,4 +300,40 @@ describe UserSegments do
expect(emails).to eq ["first@email.com", "last@email.com"] expect(emails).to eq ["first@email.com", "last@email.com"]
end end
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 end

View File

@@ -160,7 +160,8 @@ describe "Admin newsletter emails", :admin do
end end
end end
scenario "Select list of users to send newsletter" do describe "Select list of users to send newsletter" do
scenario "Custom user segments" do
UserSegments.segments.each do |segment| UserSegments.segments.each do |segment|
segment_recipient = UserSegments.segment_name(segment) segment_recipient = UserSegments.segment_name(segment)
@@ -172,4 +173,16 @@ describe "Admin newsletter emails", :admin do
expect(page).to have_content segment_recipient expect(page).to have_content segment_recipient
end end
end end
scenario "Geozone segments" do
create(:geozone, name: "Queens and Brooklyn")
visit new_admin_newsletter_path
fill_in_newsletter_form(segment_recipient: "Queens and Brooklyn")
click_button "Create Newsletter"
expect(page).to have_content "Queens and Brooklyn"
end
end
end end