docbrown/spec/models/ab_experiment/goal_conversion_handler_spec.rb
Anna Buianova 20e242af0d
Rubocop fixes (#20254)
* Fixed redundant alls for rubocop

* Fixed rubocop violations in spec/requests

* Fixed rubocop violations in spec/models

* Fixed Performance/MapMethodChain

* Fixed rubocop violations in spec/requests

* Revert changes to FastlyConfig::Update spec
2023-10-18 17:24:28 -04:00

301 lines
12 KiB
Ruby

require "rails_helper"
RSpec.describe AbExperiment::GoalConversionHandler do
include FieldTest::Helpers
describe ".call" do
subject(:handler) do
described_class.new(user: user, goal: goal, experiments: experiments, start_date: start_date)
end
let(:user) { create(:user) }
let(:start_date) { 16.days.ago }
let(:goal) { "non_sense" }
let(:experiments) { FieldTest.config["experiments"] }
context "with no experiments" do
let(:experiments) { nil }
it "gracefully handles a case where there are no tests" do
handler.call
expect(FieldTest::Event.all.size).to be(0)
end
end
context "with experiment that started to soon for some results" do
let(:goal) { described_class::USER_CREATES_COMMENT_GOAL }
let(:experiment_name) { AbExperiment::CURRENT_FEED_STRATEGY_EXPERIMENT }
let(:start_date) { 8.days.from_now }
before do
field_test(experiment_name, participant: user)
end
it "registers some events but not others", :aggregate_failures do
7.times do |n|
create(:comment, user_id: user.id, created_at: n.days.ago)
end
handler.call
# Only the comment registered; the other one would've registered had the events happened
# after the experiment start date.
expect(FieldTest::Event.where(name: goal).count).to eq(1)
expect(FieldTest::Event
.where(name: "user_creates_comment_on_at_least_four_different_days_within_a_week")
.count).to eq(0)
end
end
context "with user who is part of field test and user_publishes_post goal" do
let(:goal) { described_class::USER_PUBLISHES_POST_GOAL }
before do
field_test(AbExperiment::CURRENT_FEED_STRATEGY_EXPERIMENT, participant: user)
end
it "records a conversion", :aggregate_failures do
create(:article, :past, past_published_at: 2.days.ago, user_id: user.id)
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)
end
it "records weekly post publishing conversions", :aggregate_failures do
create(:article, :past, past_published_at: 2.days.ago, user_id: user.id)
create(:article, :past, past_published_at: 3.days.ago, user_id: user.id)
create(:article, :past, past_published_at: 13.days.ago, user_id: user.id)
handler.call
expect(FieldTest::Event.last.field_test_membership.participant_id).to eq(user.id.to_s)
expect(FieldTest::Event.pluck(:name).sort)
.to match_array([
goal,
"user_publishes_post_at_least_two_times_within_two_weeks",
"user_publishes_post_at_least_two_times_within_week",
].sort)
end
it "records a conversion when they post 4 within a week" do
create(:article, :past, past_published_at: 25.hours.ago, user_id: user.id)
create(:article, :past, past_published_at: 49.hours.ago, user_id: user.id)
create(:article, :past, past_published_at: 73.hours.ago, user_id: user.id)
create(:article, :past, past_published_at: 97.hours.ago, user_id: user.id)
handler.call
expect(FieldTest::Event.last.field_test_membership.participant_id).to eq(user.id.to_s)
expect(FieldTest::Event.pluck(:name).sort)
.to match_array([
goal,
"user_publishes_post_at_least_two_times_within_two_weeks",
"user_publishes_post_at_least_two_times_within_week",
"user_publishes_post_on_four_different_days_within_a_week",
].sort)
end
end
context "with user who is part of field test and user_creates_comment goal" do
let(:goal) { described_class::USER_CREATES_COMMENT_GOAL }
before do
field_test(AbExperiment::CURRENT_FEED_STRATEGY_EXPERIMENT, participant: user)
end
it "records a conversion", :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)
end
it "records user_creates_comment_on_at_least_four_different_days_within_a_week field test conversion",
:aggregate_failures do
7.times do |n|
create(:comment, user_id: user.id, created_at: n.days.ago)
end
handler.call
expect(FieldTest::Event.last.field_test_membership.participant_id).to eq(user.id.to_s)
expect(FieldTest::Event.last.name)
.to eq("user_creates_comment_on_at_least_four_different_days_within_a_week")
end
end
context "with user who is part of field test and user_creates_pageview goal" do
let(:goal) { described_class::USER_CREATES_PAGEVIEW_GOAL }
before do
field_test(AbExperiment::CURRENT_FEED_STRATEGY_EXPERIMENT, participant: user)
Timecop.freeze(Time.current.utc.at_noon)
end
after { Timecop.return }
it "records a field test when user views a page", :aggregate_failures do
create(:page_view, user_id: user.id)
handler.call
expect(FieldTest::Event.last.field_test_membership.participant_id).to eq(user.id.to_s)
expect(FieldTest::Event.pluck(:name))
.to include(goal)
end
it "records user_views_pages_on_at_least_two_different_days_within_a_week field test conversion",
:aggregate_failures do
3.times do |n|
create(:page_view, user_id: user.id, created_at: n.days.ago)
end
handler.call
expect(FieldTest::Event.last.field_test_membership.participant_id).to eq(user.id.to_s)
expect(FieldTest::Event.pluck(:name))
.to include("user_views_pages_on_at_least_two_different_days_within_a_week")
end
it "records user_views_pages_on_at_least_four_different_days_within_a_week field test conversion",
:aggregate_failures do
7.times do |n|
create(:page_view, user_id: user.id, created_at: n.days.ago)
end
handler.call
expect(FieldTest::Event.last.field_test_membership.participant_id).to eq(user.id.to_s)
expect(FieldTest::Event.pluck(:name))
.to include("user_views_pages_on_at_least_four_different_days_within_a_week")
end
it "records user_views_pages_on_at_least_nine_different_days_within_two_weeks field test conversionn",
:aggregate_failures do
10.times do |n|
create(:page_view, user_id: user.id, created_at: n.days.ago)
end
handler.call
expect(FieldTest::Event.last.field_test_membership.participant_id).to eq(user.id.to_s)
expect(FieldTest::Event.pluck(:name))
.to include("user_views_pages_on_at_least_nine_different_days_within_two_weeks")
end
it "records user_views_pages_on_at_least_twelve_different_hours_within_five_days field test conversion",
:aggregate_failures do
15.times do |n|
create(:page_view, user_id: user.id, created_at: n.hours.ago)
end
handler.call
expect(FieldTest::Event.last.field_test_membership.participant_id).to eq(user.id.to_s)
expect(FieldTest::Event.pluck(:name))
.to include("user_views_pages_on_at_least_twelve_different_hours_within_five_days")
end
it "does not record field test conversion if not qualifying" do
2.times do |n|
create(:page_view, user_id: user.id, created_at: n.days.ago)
end
handler.call
expect(FieldTest::Event.pluck(:name))
.not_to include("user_views_pages_on_at_least_twelve_different_hours_within_five_days")
end
it "records user_views_pages_on_at_least_three_different_hours_within_a_day field test conversionn",
:aggregate_failures do
3.times do |n|
create(:page_view, user_id: user.id, created_at: n.hours.ago)
end
handler.call
expect(FieldTest::Event.last.field_test_membership.participant_id).to eq(user.id.to_s)
expect(FieldTest::Event.pluck(:name))
.to eq([goal, "user_views_pages_on_at_least_three_different_hours_within_a_day"])
end
it "records user_views_pages_on_at_least_four_different_hours_within_a_day field test conversionn",
:aggregate_failures do
7.times do |n|
create(:page_view, user_id: user.id, created_at: n.hours.ago)
end
handler.call
expect(FieldTest::Event.last.field_test_membership.participant_id).to eq(user.id.to_s)
expect(FieldTest::Event.pluck(:name))
.to eq([goal, "user_views_pages_on_at_least_three_different_hours_within_a_day",
"user_views_pages_on_at_least_four_different_hours_within_a_day"])
end
it "does not record user_views_article_four_hours_in_day field test conversion for non-qualifying activity" do
2.times do |n|
create(:page_view, user_id: user.id, created_at: n.hours.ago)
end
handler.call
expect(FieldTest::Event.pluck(:name))
.not_to include("user_views_pages_on_at_least_four_different_hours_within_a_day")
end
end
context "with user who is part of field test and user_creates_article_reaction goal" do
let(:goal) { described_class::USER_CREATES_ARTICLE_REACTION_GOAL }
let(:user) { create(:user, :trusted) } # Because we want to test handling of privileged reactions
before do
field_test(AbExperiment::CURRENT_FEED_STRATEGY_EXPERIMENT, participant: user)
end
it "records a conversion", :aggregate_failures do
create(:reaction, user_id: user.id)
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)
end
it "records a conversion when they react 4 times within a week", :aggregate_failures do
create(:reaction, user_id: user.id, created_at: 25.hours.ago)
create(:reaction, user_id: user.id, created_at: 49.hours.ago)
create(:reaction, user_id: user.id, created_at: 73.hours.ago)
create(:reaction, user_id: user.id, created_at: 97.hours.ago)
handler.call
expect(FieldTest::Event.last.field_test_membership.participant_id).to eq(user.id.to_s)
expect(FieldTest::Event.pluck(:name).sort)
.to match_array([
goal,
"user_creates_article_reaction_on_four_different_days_within_a_week",
].sort)
end
it "does not record the conversion when they react to non-articles or non-public reactions" do
create(:reaction, user_id: user.id, created_at: 25.hours.ago)
create(:reaction, user_id: user.id, created_at: 49.hours.ago)
create(:reaction, user_id: user.id, created_at: 73.hours.ago, category: "vomit")
create(:reaction, user_id: user.id, created_at: 97.hours.ago, reactable: create(:comment))
create(:reaction, user_id: user.id, created_at: 121.hours.ago)
handler.call
expect(FieldTest::Event.last.field_test_membership.participant_id).to eq(user.id.to_s)
expect(FieldTest::Event.pluck(:name))
.to contain_exactly(goal)
end
it "does not record the conversion when their 4 reactions are not within a week" do
create(:reaction, user_id: user.id, created_at: 25.hours.ago)
create(:reaction, user_id: user.id, created_at: 49.hours.ago)
create(:reaction, user_id: user.id, created_at: 73.hours.ago)
create(:reaction, user_id: user.id, created_at: 217.hours.ago) # 9 days ago
handler.call
expect(FieldTest::Event.last.field_test_membership.participant_id).to eq(user.id.to_s)
expect(FieldTest::Event.pluck(:name))
.to contain_exactly(goal)
end
end
context "with user who is not part of field test" do
let(:goal) { described_class::USER_CREATES_COMMENT_GOAL }
it "does not register a conversion" do
handler.call
expect(FieldTest::Event.all.size).to be(0)
end
it "records user_views_article_four_days_in_week field test conversion" do
7.times do |n|
create(:page_view, user_id: user.id, created_at: n.days.ago)
end
handler.call
expect(FieldTest::Event.all.size).to be(0)
end
end
end
end