diff --git a/app/models/ab_experiment.rb b/app/models/ab_experiment.rb index f9bede301..aa7e3fba9 100644 --- a/app/models/ab_experiment.rb +++ b/app/models/ab_experiment.rb @@ -14,8 +14,10 @@ class AbExperiment < SimpleDelegator # @see ./config/feed-variants/README.md ORIGINAL_VARIANT = "original".freeze - CURRENT_FEED_STRATEGY_EXPERIMENT = FieldTest.config["experiments"]&.keys - &.detect { |e| e.start_with? "feed_strategy" }.freeze + # @note a present assumption is that we will have a feed_strategy oriented experiment. + CURRENT_FEED_STRATEGY_EXPERIMENT = FieldTest.config["experiments"].select do |key, value| + key.start_with?("feed_strategy") && !value["winner"] + end.keys.first # Sometimes we might want to repurpose the same AbExperiment logic # for different experiments. This provides the tooling for that diff --git a/config/field_test.yml b/config/field_test.yml index f3f351000..0195d76e8 100644 --- a/config/field_test.yml +++ b/config/field_test.yml @@ -26,9 +26,77 @@ experiments: - user_views_pages_on_at_least_nine_different_days_within_two_weeks - user_publishes_post_at_least_two_times_within_week - user_publishes_post_at_least_two_times_within_two_weeks -exclude: - bots: true - + feed_strategy_starting_20220518: + winner: 20220518-variant + # NOTE: Required as we want only want to consider for conversion events that + # occurred on or after the given start_date. + start_date: 2022-05-09 + variants: + - 20220422-variant + - 20220518-variant + weights: + - 80 + - 20 + goals: + - user_creates_pageview + - user_creates_article_reaction + - user_creates_comment + - user_publishes_post + - user_views_pages_on_at_least_four_different_days_within_a_week + - user_creates_article_reaction_on_four_different_days_within_a_week + - user_creates_comment_on_at_least_four_different_days_within_a_week + - user_publishes_post_on_four_different_days_within_a_week + # These are historical and may be userful + - user_views_pages_on_at_least_four_different_hours_within_a_day + - user_views_pages_on_at_least_twelve_different_hours_within_five_days + - user_views_pages_on_at_least_nine_different_days_within_two_weeks + - user_publishes_post_at_least_two_times_within_week + feed_strategy_starting_20220509: + winner: 20220422-variant + # NOTE: Required as we want only want to consider for conversion events that + # occurred on or after the given start_date. + start_date: 2022-05-09 + variants: + - 20220422-variant + - 20220509-variant + weights: + - 80 + - 20 + goals: + - user_creates_pageview + - user_creates_article_reaction + - user_creates_comment + - user_publishes_post + - user_views_pages_on_at_least_four_different_days_within_a_week + - user_creates_article_reaction_on_four_different_days_within_a_week + - user_creates_comment_on_at_least_four_different_days_within_a_week + - user_publishes_post_on_four_different_days_within_a_week + # These are historical and may be userful + - user_views_pages_on_at_least_four_different_hours_within_a_day + - user_views_pages_on_at_least_twelve_different_hours_within_five_days + - user_views_pages_on_at_least_nine_different_days_within_two_weeks + - user_publishes_post_at_least_two_times_within_week + feed_strategy_starting_20220422: + winner: 20220422-variant + # NOTE: Required as we want only want to consider for conversion events that + # occurred on or after the given start_date. + start_date: 2022-04-22 + variants: + - 20220415-incumbent + - 20220422-jennie-variant + weights: + - 80 + - 20 + goals: + - user_creates_comment + - user_creates_comment_on_at_least_four_different_days_within_a_week + - user_views_pages_on_at_least_four_different_days_within_a_week + - user_views_pages_on_at_least_four_different_hours_within_a_day + - user_views_pages_on_at_least_nine_different_days_within_two_weeks + - user_views_pages_on_at_least_twelve_different_hours_within_five_days + - user_publishes_post + - user_publishes_post_at_least_two_times_within_week + - user_publishes_post_at_least_two_times_within_two_weeks # Dashboard performance cache: true precision: 2 diff --git a/spec/models/ab_experiment_spec.rb b/spec/models/ab_experiment_spec.rb index efbb6cef2..c9818b562 100644 --- a/spec/models/ab_experiment_spec.rb +++ b/spec/models/ab_experiment_spec.rb @@ -4,6 +4,27 @@ RSpec.describe AbExperiment do let(:controller) { ApplicationController.new } let(:user) { double } + describe "CURRENT_FEED_STRATEGY_EXPERIMENT" do + subject(:variant) { described_class::CURRENT_FEED_STRATEGY_EXPERIMENT } + + it { is_expected.to be_a String } + + it "is a key in the FieldTest.config['experiments']" do + expect(FieldTest.config["experiments"].keys).to include(variant) + end + end + + describe "validate field test experiment configuration" do + it "only allow at most one active feed_strategy (e.g. an experiment without a winner)" do + field_tests = Psych.load(Rails.root.join("config/field_test.yml").read) + active_field_tests = field_tests.fetch("experiments", {}) + .select { |key, values| key.start_with?("feed_strategy") && !values["winner"] } + + # We are only going to allow + expect(active_field_tests.size).to be <= 1 + end + end + describe ".register_conversions_for" do it "forwards delegates to Converter.call" do allow(described_class::GoalConversionHandler).to receive(:call)