Skip to content

Commit

Permalink
Add new email feed event goal and new test (forem#21158)
Browse files Browse the repository at this point in the history
* Adjust field tests for sidebar active discussions

* Add new email feed event goal and ew test
  • Loading branch information
benhalpern authored Jun 25, 2024
1 parent 433b309 commit 547b0cf
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 13 deletions.
3 changes: 2 additions & 1 deletion app/models/ab_experiment/goal_conversion_handler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class GoalConversionHandler
USER_CREATES_PAGEVIEW_GOAL = "user_creates_pageview".freeze
USER_CREATES_COMMENT_GOAL = "user_creates_comment".freeze
USER_CREATES_ARTICLE_REACTION_GOAL = "user_creates_article_reaction".freeze
USER_CREATES_EMAIL_FEED_EVENT_GOAL = "user_creates_email_feed_event".freeze

def self.call(...)
new(...).call
Expand Down Expand Up @@ -56,7 +57,7 @@ def convert(experiment:, experiment_start_date:)
when USER_CREATES_ARTICLE_REACTION_GOAL
convert_reaction_goal(experiment: experiment, experiment_start_date: experiment_start_date)
else
field_test_converted(experiment, participant: user, goal: goal) # base single comment goal.
field_test_converted(experiment, participant: user, goal: goal) # When there is only a single goal.
end
end

Expand Down
12 changes: 12 additions & 0 deletions app/models/feed_event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class FeedEvent < ApplicationRecord
belongs_to :user, optional: true

after_save :update_article_counters_and_scores
after_create_commit :record_field_test_event

enum category: {
impression: 0,
Expand Down Expand Up @@ -103,4 +104,15 @@ def update_article_counters_and_scores

self.class.update_single_article_counters(article_id)
end

# @see AbExperiment::GoalConversionHandler
def record_field_test_event
return if FieldTest.config["experiments"].nil?
return if category.to_s == "impression"
return unless user_id
return unless context_type == CONTEXT_TYPE_EMAIL # We are only doing this for email at the moment

Users::RecordFieldTestEventWorker
.perform_async(user_id, AbExperiment::GoalConversionHandler::USER_CREATES_EMAIL_FEED_EVENT_GOAL)
end
end
21 changes: 10 additions & 11 deletions app/services/email_digest_article_collector.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,20 @@ def initialize(user)

def articles_to_send
# rubocop:disable Metrics/BlockLength
order_variant = field_test(:digest_article_ordering_06_17, participant: @user)
order_variant = field_test(:digest_article_ordering_06_25, participant: @user)
order = case order_variant
when "base"
Arel.sql("((score * ((feed_success_score * 10) + 0.1)) - (clickbait_score * 2)) DESC")
when "more_weight_on_feed_success_score"
Arel.sql("((score * ((feed_success_score * 12) + 0.1)) - (clickbait_score * 2)) DESC")
when "much_more_weight_on_feed_success_score"
Arel.sql("((score * ((feed_success_score * 15) + 0.1)) - (clickbait_score * 2)) DESC")
when "much_much_more_weight_on_feed_success_score"
Arel.sql("((score * ((feed_success_score * 20) + 0.1)) - (clickbait_score * 2)) DESC")
when "much_much_much_more_weight_on_feed_success_score"
Arel.sql("((score * ((feed_success_score * 25) + 0.1)) - (clickbait_score * 2)) DESC")
when "more_comment_score"
Arel.sql("((score * ((feed_success_score * 12) + 0.1)) - (clickbait_score * 2) + comment_score) DESC")
when "much_more_comment_score"
Arel.sql("((score * ((feed_success_score * 15) + 0.1)) - (clickbait_score * 2) + (comment_score * 5)) DESC") # rubocop:disable Layout/LineLength
when "much_much_more_comment_score"
Arel.sql("((score * ((feed_success_score * 20) + 0.1)) - (clickbait_score * 2) + (comment_score * 15)) DESC") # rubocop:disable Layout/LineLength
else
Arel.sql("((score * ((feed_success_score * 10) + 0.1)) - (clickbait_score * 2)) DESC")
Arel.sql("((score * ((feed_success_score * 12) + 0.1)) - (clickbait_score * 2)) DESC")
end
instrument ARTICLES_TO_SEND, tags: { user_id: @user.id } do
instrument ARTICLES_TO_SEND, tags: { user_id: @user.id } do
return [] unless should_receive_email?

articles = if @user.cached_followed_tag_names.any?
Expand Down Expand Up @@ -65,6 +63,7 @@ def articles_to_send
.published
.where("published_at > ?", cutoff_date)
.where(email_digest_eligible: true)
.where("score > ?", 11)
.not_authored_by(@user.id)
.order(order)
.limit(RESULTS_COUNT)
Expand Down
19 changes: 19 additions & 0 deletions config/field_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,23 @@
################################################################################

experiments:
digest_article_ordering_06_25:
started_at: 2024-06-25
variants:
- base
- more_comment_score
- much_more_comment_score
- much_much_more_comment_score
weights:
- 70
- 10
- 10
- 10
goals:
- user_creates_email_feed_event
- user_creates_comment
- user_views_pages_on_at_least_two_different_days_within_a_week
- user_views_pages_on_at_least_four_different_days_within_a_week
active_discussion_ordering_06_24:
started_at: 2024-06-24
variants:
Expand All @@ -50,6 +67,8 @@ experiments:
- user_views_pages_on_at_least_four_different_days_within_a_week
digest_article_ordering_06_17:
started_at: 2024-06-17
ended_at: 2024-06-24
winner: more_weight_on_feed_success_score
variants:
- base
- more_weight_on_feed_success_score
Expand Down
17 changes: 17 additions & 0 deletions spec/models/ab_experiment/goal_conversion_handler_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -297,5 +297,22 @@
expect(FieldTest::Event.all.size).to be(0)
end
end

context "with user who is part of field test and user_creates_email_feed_event goal" do
let(:goal) { described_class::USER_CREATES_EMAIL_FEED_EVENT_GOAL }
let(:article) { create(:article, :past, past_published_at: 2.days.ago, user_id: user.id) }

before do
field_test(AbExperiment::CURRENT_FEED_STRATEGY_EXPERIMENT, participant: user)
end

it "records a conversio for click", :aggregate_failures do
handler.call
expect(FieldTest::Event.last.field_test_membership.participant_id).to eq(user.id.to_s)
expect(FieldTest::Event.last.name).to eq(goal)
expect(FieldTest::Event.all.size).to be(1)
end

end
end
end
61 changes: 60 additions & 1 deletion spec/models/feed_event_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,65 @@
end
end

describe "after_create .record_field_test_event" do
let(:user) { create(:user) }
let(:category) { "click" }
let(:context_type) { "home" }
let(:goal) { AbExperiment::GoalConversionHandler::USER_CREATES_EMAIL_FEED_EVENT_GOAL }

before do
allow(Users::RecordFieldTestEventWorker).to receive(:perform_async)
allow(FieldTest).to receive(:config).and_return({ "experiments" => { "some_experiment" => true } })
end

it "records a field test event if the conditions are met" do
create(:feed_event, user: user, category: category, context_type: "email")

expect(Users::RecordFieldTestEventWorker).to have_received(:perform_async).with(
user.id,
goal,
)
end

it "does not record a field test event if experiments are nil" do
allow(FieldTest).to receive(:config).and_return({ "experiments" => nil })
create(:feed_event, user: user, category: category, context_type: "email")

expect(Users::RecordFieldTestEventWorker).not_to have_received(:perform_async).with(
user.id,
goal,
)

end

it "does not record a field test event if category is impression" do
create(:feed_event, user: user, category: "impression", context_type: "email")

expect(Users::RecordFieldTestEventWorker).not_to have_received(:perform_async).with(
user.id,
goal,
)
end

it "does not record a field test event if user_id is nil" do
create(:feed_event, user: nil, category: category, context_type: "email")

expect(Users::RecordFieldTestEventWorker).not_to have_received(:perform_async).with(
user.id,
goal,
)
end

it "does not record a field test event if context_type is not email" do
create(:feed_event, user: user, category: category, context_type: "home")

expect(Users::RecordFieldTestEventWorker).not_to have_received(:perform_async).with(
user.id,
goal,
)
end
end

describe "after_save .update_article_counters_and_scores" do
let!(:article) { create(:article) }
let!(:user1) { create(:user) }
Expand Down Expand Up @@ -193,4 +252,4 @@
expect(article2.feed_clicks_count).to eq(0)
end
end
end
end

0 comments on commit 547b0cf

Please sign in to comment.