// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/media/media_engagement_score.h"

#include <utility>

#include "base/macros.h"
#include "base/metrics/field_trial_param_associator.h"
#include "base/metrics/field_trial_params.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_clock.h"
#include "base/values.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/engagement/site_engagement_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/testing_profile.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "media/base/media_switches.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

namespace {

base::Time GetReferenceTime() {
  base::Time::Exploded exploded_reference_time;
  exploded_reference_time.year = 2015;
  exploded_reference_time.month = 1;
  exploded_reference_time.day_of_month = 30;
  exploded_reference_time.day_of_week = 5;
  exploded_reference_time.hour = 11;
  exploded_reference_time.minute = 0;
  exploded_reference_time.second = 0;
  exploded_reference_time.millisecond = 0;

  base::Time out_time;
  EXPECT_TRUE(
      base::Time::FromLocalExploded(exploded_reference_time, &out_time));
  return out_time;
}

}  // namespace

class MediaEngagementScoreTest : public ChromeRenderViewHostTestHarness {
 public:
  void SetUp() override {
    ChromeRenderViewHostTestHarness::SetUp();
    test_clock.SetNow(GetReferenceTime());
    score_ = new MediaEngagementScore(&test_clock, GURL(), nullptr);
  }

  void TearDown() override {
    delete score_;
    ChromeRenderViewHostTestHarness::TearDown();
  }

  base::SimpleTestClock test_clock;

 protected:
  MediaEngagementScore* score_;

  void VerifyScore(MediaEngagementScore* score,
                   int expected_visits,
                   int expected_media_playbacks,
                   base::Time expected_last_media_playback_time,
                   bool has_high_score,
                   int audible_playbacks,
                   int significant_playbacks,
                   int visits_with_media_tag,
                   int high_score_changes,
                   int media_element_playbacks,
                   int audio_context_playbacks) {
    EXPECT_EQ(expected_visits, score->visits());
    EXPECT_EQ(expected_media_playbacks, score->media_playbacks());
    EXPECT_EQ(expected_last_media_playback_time,
              score->last_media_playback_time());
    EXPECT_EQ(has_high_score, score->high_score());
    EXPECT_EQ(audible_playbacks, score->audible_playbacks());
    EXPECT_EQ(significant_playbacks, score->significant_playbacks());
    EXPECT_EQ(visits_with_media_tag, score->visits_with_media_tag());
    EXPECT_EQ(high_score_changes, score->high_score_changes());
    EXPECT_EQ(media_element_playbacks, score->media_element_playbacks());
    EXPECT_EQ(audio_context_playbacks, score->audio_context_playbacks());
  }

  void UpdateScore(MediaEngagementScore* score) {
    test_clock.SetNow(test_clock.Now() + base::TimeDelta::FromHours(1));

    score->IncrementVisits();
    score->IncrementMediaPlaybacks();
    score->IncrementAudiblePlaybacks(1);
    score->IncrementSignificantPlaybacks(1);
    score->IncrementVisitsWithMediaTag();
    score->IncrementMediaElementPlaybacks();
    score->IncrementAudioContextPlaybacks();
  }

  void TestScoreInitializesAndUpdates(
      std::unique_ptr<base::DictionaryValue> score_dict,
      int expected_visits,
      int expected_media_playbacks,
      base::Time expected_last_media_playback_time,
      bool has_high_score,
      int audible_playbacks,
      int significant_playbacks,
      int visits_with_media_tag,
      int high_score_changes,
      int media_element_playbacks,
      int audio_context_playbacks) {
    MediaEngagementScore* initial_score = new MediaEngagementScore(
        &test_clock, GURL(), std::move(score_dict), nullptr /* settings */);
    VerifyScore(initial_score, expected_visits, expected_media_playbacks,
                expected_last_media_playback_time, has_high_score,
                audible_playbacks, significant_playbacks, visits_with_media_tag,
                high_score_changes, media_element_playbacks,
                audio_context_playbacks);

    // Updating the score dict should return false, as the score shouldn't
    // have changed at this point.
    EXPECT_FALSE(initial_score->UpdateScoreDict());

    // Increment the scores and check that the values were stored correctly.
    UpdateScore(initial_score);
    EXPECT_TRUE(initial_score->UpdateScoreDict());
    delete initial_score;
  }

  static void SetScore(MediaEngagementScore* score,
                       int visits,
                       int media_playbacks) {
    score->SetVisits(visits);
    score->SetMediaPlaybacks(media_playbacks);
  }

  void SetScore(int visits, int media_playbacks) {
    SetScore(score_, visits, media_playbacks);
  }

  void VerifyGetScoreDetails(MediaEngagementScore* score) {
    media::mojom::MediaEngagementScoreDetailsPtr details =
        score->GetScoreDetails();
    EXPECT_EQ(details->origin, score->origin_);
    EXPECT_EQ(details->total_score, score->actual_score());
    EXPECT_EQ(details->visits, score->visits());
    EXPECT_EQ(details->media_playbacks, score->media_playbacks());
    EXPECT_EQ(details->last_media_playback_time,
              score->last_media_playback_time().ToJsTime());
    EXPECT_EQ(details->audible_playbacks, score->audible_playbacks());
    EXPECT_EQ(details->significant_playbacks, score->significant_playbacks());
    EXPECT_EQ(details->high_score_changes, score->high_score_changes());
    EXPECT_EQ(details->audio_context_playbacks,
              score->audio_context_playbacks());
    EXPECT_EQ(details->media_element_playbacks,
              score->media_element_playbacks());
  }

  void OverrideFieldTrial(int min_visits,
                          double lower_threshold,
                          double upper_threshold) {
    field_trial_list_.reset();
    field_trial_list_ = std::make_unique<base::FieldTrialList>(nullptr);
    base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting();

    std::map<std::string, std::string> params;
    params[MediaEngagementScore::kScoreMinVisitsParamName] =
        std::to_string(min_visits);
    params[MediaEngagementScore::kHighScoreLowerThresholdParamName] =
        std::to_string(lower_threshold);
    params[MediaEngagementScore::kHighScoreUpperThresholdParamName] =
        std::to_string(upper_threshold);

    scoped_feature_list_ = std::make_unique<base::test::ScopedFeatureList>();
    scoped_feature_list_->InitAndEnableFeatureWithParameters(
        media::kMediaEngagementBypassAutoplayPolicies, params);

    std::map<std::string, std::string> actual_params;
    EXPECT_TRUE(base::GetFieldTrialParamsByFeature(
        media::kMediaEngagementBypassAutoplayPolicies, &actual_params));
    EXPECT_EQ(params, actual_params);

    score_->Recalculate();
  }

 private:
  std::unique_ptr<base::test::ScopedFeatureList> scoped_feature_list_;
  std::unique_ptr<base::FieldTrialList> field_trial_list_;
};

// Test Mojo serialization.
TEST_F(MediaEngagementScoreTest, MojoSerialization) {
  VerifyGetScoreDetails(score_);
  UpdateScore(score_);
  VerifyGetScoreDetails(score_);
}

// Test that scores are read / written correctly from / to empty score
// dictionaries.
TEST_F(MediaEngagementScoreTest, EmptyDictionary) {
  std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
  TestScoreInitializesAndUpdates(std::move(dict), 0, 0, base::Time(), false, 0,
                                 0, 0, 0, 0, 0);
}

// Test that scores are read / written correctly from / to partially empty
// score dictionaries.
TEST_F(MediaEngagementScoreTest, PartiallyEmptyDictionary) {
  std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
  dict->SetInteger(MediaEngagementScore::kVisitsKey, 2);

  TestScoreInitializesAndUpdates(std::move(dict), 2, 0, base::Time(), false, 0,
                                 0, 0, 0, 0, 0);
}

// Test that scores are read / written correctly from / to populated score
// dictionaries.
TEST_F(MediaEngagementScoreTest, PopulatedDictionary) {
  std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
  dict->SetInteger(MediaEngagementScore::kVisitsKey, 20);
  dict->SetInteger(MediaEngagementScore::kMediaPlaybacksKey, 12);
  dict->SetDouble(MediaEngagementScore::kLastMediaPlaybackTimeKey,
                  test_clock.Now().ToInternalValue());
  dict->SetBoolean(MediaEngagementScore::kHasHighScoreKey, true);
  dict->SetInteger(MediaEngagementScore::kAudiblePlaybacksKey, 2);
  dict->SetInteger(MediaEngagementScore::kSignificantPlaybacksKey, 4);
  dict->SetInteger(MediaEngagementScore::kVisitsWithMediaTagKey, 6);
  dict->SetInteger(MediaEngagementScore::kHighScoreChanges, 3);
  dict->SetInteger(MediaEngagementScore::kSignificantMediaPlaybacksKey, 1);
  dict->SetInteger(MediaEngagementScore::kSignificantAudioContextPlaybacksKey,
                   2);

  TestScoreInitializesAndUpdates(std::move(dict), 20, 12, test_clock.Now(),
                                 true, 2, 4, 6, 3, 1, 2);
}

// Test getting and commiting the score works correctly with different
// origins.
TEST_F(MediaEngagementScoreTest, ContentSettingsMultiOrigin) {
  GURL url("https://www.google.com");

  // Replace |score_| with one with an actual URL, and with a settings map.
  HostContentSettingsMap* settings_map =
      HostContentSettingsMapFactory::GetForProfile(profile());
  MediaEngagementScore* score =
      new MediaEngagementScore(&test_clock, url, settings_map);

  // Verify the score is originally zero, try incrementing and storing
  // the score.
  VerifyScore(score, 0, 0, base::Time(), false, 0, 0, 0, 0, 0, 0);
  score->IncrementVisits();
  UpdateScore(score);
  score->Commit();

  // Now confirm the correct score is present on the same origin,
  // but zero for a different origin.
  GURL same_origin("https://www.google.com");
  GURL different_origin("https://www.google.co.uk");
  MediaEngagementScore* new_score =
      new MediaEngagementScore(&test_clock, url, settings_map);
  MediaEngagementScore* same_origin_score =
      new MediaEngagementScore(&test_clock, same_origin, settings_map);
  MediaEngagementScore* different_origin_score =
      new MediaEngagementScore(&test_clock, different_origin, settings_map);
  VerifyScore(new_score, 2, 1, test_clock.Now(), false, 1, 1, 1, 0, 1, 1);
  VerifyScore(same_origin_score, 2, 1, test_clock.Now(), false, 1, 1, 1, 0, 1,
              1);
  VerifyScore(different_origin_score, 0, 0, base::Time(), false, 0, 0, 0, 0, 0,
              0);

  delete score;
  delete new_score;
  delete same_origin_score;
  delete different_origin_score;
}

// Tests content settings read/write.
TEST_F(MediaEngagementScoreTest, ContentSettings) {
  HostContentSettingsMap* settings_map =
      HostContentSettingsMapFactory::GetForProfile(profile());
  int example_num_visits = 20;
  int example_media_playbacks = 5;
  int example_audible_playbacks = 3;
  int example_significant_playbacks = 5;
  int example_visits_with_media_tags = 20;
  int example_high_score_changes = 1;
  int example_media_element_playbacks = 1;
  int example_audio_context_playbacks = 3;

  // Store some example data in content settings.
  GURL origin("https://www.google.com");
  std::unique_ptr<base::DictionaryValue> score_dict =
      std::make_unique<base::DictionaryValue>();
  score_dict->SetInteger(MediaEngagementScore::kVisitsKey, example_num_visits);
  score_dict->SetInteger(MediaEngagementScore::kMediaPlaybacksKey,
                         example_media_playbacks);
  score_dict->SetDouble(MediaEngagementScore::kLastMediaPlaybackTimeKey,
                        test_clock.Now().ToInternalValue());
  score_dict->SetBoolean(MediaEngagementScore::kHasHighScoreKey, false);
  score_dict->SetInteger(MediaEngagementScore::kAudiblePlaybacksKey,
                         example_audible_playbacks);
  score_dict->SetInteger(MediaEngagementScore::kSignificantPlaybacksKey,
                         example_significant_playbacks);
  score_dict->SetInteger(MediaEngagementScore::kVisitsWithMediaTagKey,
                         example_visits_with_media_tags);
  score_dict->SetInteger(MediaEngagementScore::kHighScoreChanges,
                         example_high_score_changes);
  score_dict->SetInteger(MediaEngagementScore::kSignificantMediaPlaybacksKey,
                         example_media_element_playbacks);
  score_dict->SetInteger(
      MediaEngagementScore::kSignificantAudioContextPlaybacksKey,
      example_audio_context_playbacks);
  settings_map->SetWebsiteSettingDefaultScope(
      origin, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT,
      content_settings::ResourceIdentifier(), std::move(score_dict));

  // Make sure we read that data back correctly.
  MediaEngagementScore* score =
      new MediaEngagementScore(&test_clock, origin, settings_map);
  EXPECT_EQ(score->visits(), example_num_visits);
  EXPECT_EQ(score->media_playbacks(), example_media_playbacks);
  EXPECT_EQ(score->last_media_playback_time(), test_clock.Now());
  EXPECT_FALSE(score->high_score());
  EXPECT_EQ(score->audible_playbacks(), example_audible_playbacks);
  EXPECT_EQ(score->significant_playbacks(), example_significant_playbacks);
  EXPECT_EQ(score->visits_with_media_tag(), example_visits_with_media_tags);
  EXPECT_EQ(score->visits_with_media_tag(), example_visits_with_media_tags);
  EXPECT_EQ(score->high_score_changes(), example_high_score_changes);
  EXPECT_EQ(score->media_element_playbacks(), example_media_element_playbacks);
  EXPECT_EQ(score->audio_context_playbacks(), example_audio_context_playbacks);

  UpdateScore(score);
  score->IncrementMediaPlaybacks();
  EXPECT_TRUE(score->high_score());
  score->Commit();

  // Now read back content settings and make sure we have the right values.
  int stored_visits;
  int stored_media_playbacks;
  double stored_last_media_playback_time;
  bool stored_has_high_score;
  int stored_audible_playbacks;
  int stored_significant_playbacks;
  int stored_visits_with_media_tag;
  int stored_high_score_changes;
  int stored_media_element_playbacks;
  int stored_audio_context_playbacks;
  std::unique_ptr<base::DictionaryValue> values =
      base::DictionaryValue::From(settings_map->GetWebsiteSetting(
          origin, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT,
          content_settings::ResourceIdentifier(), nullptr));
  values->GetInteger(MediaEngagementScore::kVisitsKey, &stored_visits);
  values->GetInteger(MediaEngagementScore::kMediaPlaybacksKey,
                     &stored_media_playbacks);
  values->GetDouble(MediaEngagementScore::kLastMediaPlaybackTimeKey,
                    &stored_last_media_playback_time);
  values->GetBoolean(MediaEngagementScore::kHasHighScoreKey,
                     &stored_has_high_score);
  values->GetInteger(MediaEngagementScore::kAudiblePlaybacksKey,
                     &stored_audible_playbacks);
  values->GetInteger(MediaEngagementScore::kSignificantPlaybacksKey,
                     &stored_significant_playbacks);
  values->GetInteger(MediaEngagementScore::kVisitsWithMediaTagKey,
                     &stored_visits_with_media_tag);
  values->GetInteger(MediaEngagementScore::kHighScoreChanges,
                     &stored_high_score_changes);
  values->GetInteger(MediaEngagementScore::kSignificantMediaPlaybacksKey,
                     &stored_media_element_playbacks);
  values->GetInteger(MediaEngagementScore::kSignificantAudioContextPlaybacksKey,
                     &stored_audio_context_playbacks);
  EXPECT_EQ(stored_visits, example_num_visits + 1);
  EXPECT_EQ(stored_media_playbacks, example_media_playbacks + 2);
  EXPECT_EQ(stored_last_media_playback_time,
            test_clock.Now().ToInternalValue());
  EXPECT_EQ(stored_audible_playbacks, example_audible_playbacks + 1);
  EXPECT_EQ(stored_significant_playbacks, example_significant_playbacks + 1);
  EXPECT_EQ(stored_visits_with_media_tag, example_visits_with_media_tags + 1);
  EXPECT_TRUE(stored_has_high_score);
  EXPECT_EQ(stored_high_score_changes, example_high_score_changes + 1);
  EXPECT_EQ(stored_media_element_playbacks,
            example_media_element_playbacks + 1);
  EXPECT_EQ(stored_audio_context_playbacks,
            example_audio_context_playbacks + 1);

  delete score;
}

// Test that the engagement score is calculated correctly.
TEST_F(MediaEngagementScoreTest, EngagementScoreCalculation) {
  EXPECT_EQ(0, score_->actual_score());
  UpdateScore(score_);

  // Check that the score increases when there is one visit.
  EXPECT_EQ(0.05, score_->actual_score());

  SetScore(20, 8);
  EXPECT_EQ(0.4, score_->actual_score());

  UpdateScore(score_);
  EXPECT_EQ(9.0 / 21.0, score_->actual_score());
}

// Test that a score without the high_score bit uses the correct bounds.
TEST_F(MediaEngagementScoreTest, HighScoreLegacy_High) {
  const GURL url("https://www.example.com");
  HostContentSettingsMap* settings_map =
      HostContentSettingsMapFactory::GetForProfile(profile());

  {
    std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
    dict->SetInteger(MediaEngagementScore::kVisitsKey, 20);
    dict->SetInteger(MediaEngagementScore::kMediaPlaybacksKey, 6);
    settings_map->SetWebsiteSettingDefaultScope(
        url, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT,
        content_settings::ResourceIdentifier(), std::move(dict));
  }

  {
    std::unique_ptr<MediaEngagementScore> score(
        new MediaEngagementScore(&test_clock, url, settings_map));
    VerifyScore(score.get(), 20, 6, base::Time(), true, 0, 0, 0, 1, 6, 0);
  }
}

// Test that a score without the high_score bit uses the correct bounds.
TEST_F(MediaEngagementScoreTest, HighScoreLegacy_Low) {
  const GURL url("https://www.example.com");
  HostContentSettingsMap* settings_map =
      HostContentSettingsMapFactory::GetForProfile(profile());

  {
    std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
    dict->SetInteger(MediaEngagementScore::kVisitsKey, 20);
    dict->SetInteger(MediaEngagementScore::kMediaPlaybacksKey, 4);
    settings_map->SetWebsiteSettingDefaultScope(
        url, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT,
        content_settings::ResourceIdentifier(), std::move(dict));
  }

  {
    std::unique_ptr<MediaEngagementScore> score(
        new MediaEngagementScore(&test_clock, url, settings_map));
    VerifyScore(score.get(), 20, 4, base::Time(), false, 0, 0, 0, 0, 4, 0);
  }
}

// Test that if we changed the boundaries the high_score bit is updated
// when the score is loaded.
TEST_F(MediaEngagementScoreTest, HighScoreUpdated) {
  const GURL url("https://www.example.com");
  HostContentSettingsMap* settings_map =
      HostContentSettingsMapFactory::GetForProfile(profile());

  {
    std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
    dict->SetInteger(MediaEngagementScore::kVisitsKey, 10);
    dict->SetInteger(MediaEngagementScore::kMediaPlaybacksKey, 1);
    dict->SetDouble(MediaEngagementScore::kLastMediaPlaybackTimeKey,
                    test_clock.Now().ToInternalValue());
    dict->SetBoolean(MediaEngagementScore::kHasHighScoreKey, true);

    settings_map->SetWebsiteSettingDefaultScope(
        url, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT,
        content_settings::ResourceIdentifier(), std::move(dict));
  }

  {
    std::unique_ptr<MediaEngagementScore> score(
        new MediaEngagementScore(&test_clock, url, settings_map));
    EXPECT_FALSE(score->high_score());
    base::RunLoop().RunUntilIdle();
  }

  {
    std::unique_ptr<base::DictionaryValue> dict =
        base::DictionaryValue::From(settings_map->GetWebsiteSetting(
            url, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT,
            content_settings::ResourceIdentifier(), nullptr));

    bool stored_high_score = false;
    dict->GetBoolean(MediaEngagementScore::kHasHighScoreKey,
                     &stored_high_score);
    EXPECT_FALSE(stored_high_score);
  }
}

// Test that the has high score upper and lower thresholds work.
TEST_F(MediaEngagementScoreTest, HighScoreThreshold) {
  EXPECT_FALSE(score_->high_score());

  // Test that a total score of 0.1 is not high.
  SetScore(20, 2);
  EXPECT_FALSE(score_->high_score());

  // Test that a total score of 0.25 is not high but above zero.
  SetScore(20, 5);
  EXPECT_FALSE(score_->high_score());

  // Test that a total score of 0.3 is high.
  SetScore(20, 6);
  EXPECT_TRUE(score_->high_score());

  // Test that a total score of 0.25 is high because of the lower boundary.
  SetScore(20, 5);
  EXPECT_TRUE(score_->high_score());

  // Test that a total score of 0.1 is not high.
  SetScore(20, 2);
  EXPECT_FALSE(score_->high_score());
}

TEST_F(MediaEngagementScoreTest, OverrideFieldTrial) {
  EXPECT_EQ(20, MediaEngagementScore::GetScoreMinVisits());
  EXPECT_EQ(0.2, MediaEngagementScore::GetHighScoreLowerThreshold());
  EXPECT_EQ(0.3, MediaEngagementScore::GetHighScoreUpperThreshold());

  SetScore(20, 16);
  EXPECT_EQ(0.8, score_->actual_score());
  EXPECT_TRUE(score_->high_score());

  // Raise the upper threshold, since the score was already considered high we
  // should still be high.
  OverrideFieldTrial(5, 0.7, 0.9);
  EXPECT_TRUE(score_->high_score());
  EXPECT_EQ(0.7, MediaEngagementScore::GetHighScoreLowerThreshold());
  EXPECT_EQ(0.9, MediaEngagementScore::GetHighScoreUpperThreshold());

  // Raise the lower threshold, the score will no longer be high.
  OverrideFieldTrial(5, 0.85, 0.9);
  EXPECT_FALSE(score_->high_score());
  EXPECT_EQ(0.85, MediaEngagementScore::GetHighScoreLowerThreshold());

  // Raise the minimum visits, the score will now be relative to this new
  // visits requirements.
  OverrideFieldTrial(25, 0.85, 0.9);
  EXPECT_EQ(0.64, score_->actual_score());
  EXPECT_EQ(25, MediaEngagementScore::GetScoreMinVisits());
}

TEST_F(MediaEngagementScoreTest, HighScoreChanges) {
  const GURL kUrl("https://www.example.com");
  HostContentSettingsMap* settings_map =
      HostContentSettingsMapFactory::GetForProfile(profile());

  {
    std::unique_ptr<MediaEngagementScore> score(
        new MediaEngagementScore(&test_clock, kUrl, settings_map));

    EXPECT_EQ(0, score->high_score_changes());
    // Perfect score, high_score bit has changed.
    SetScore(score.get(), 20, 20);
    score->Commit();
    EXPECT_EQ(1, score->high_score_changes());
  }

  {
    std::unique_ptr<MediaEngagementScore> score(
        new MediaEngagementScore(&test_clock, kUrl, settings_map));

    // Worse score, high_score bit has changed.
    SetScore(score.get(), 20, 0);
    score->Commit();
    EXPECT_EQ(2, score->high_score_changes());
  }

  // Bad score, high_score bit has not changed.
  {
    std::unique_ptr<MediaEngagementScore> score(
        new MediaEngagementScore(&test_clock, kUrl, settings_map));

    SetScore(score.get(), 20, 1);
    score->Commit();
    EXPECT_EQ(2, score->high_score_changes());
  }
}

// Test that we migrate the media playbacks value to media element playbacks.
TEST_F(MediaEngagementScoreTest, MigrateMediaElementPlaybacks) {
  const GURL url("https://www.example.com");
  HostContentSettingsMap* settings_map =
      HostContentSettingsMapFactory::GetForProfile(profile());
  int media_playbacks = 6;

  {
    std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
    dict->SetBoolean(MediaEngagementScore::kHasHighScoreKey, true);
    dict->SetInteger(MediaEngagementScore::kMediaPlaybacksKey, media_playbacks);

    settings_map->SetWebsiteSettingDefaultScope(
        url, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT,
        content_settings::ResourceIdentifier(), std::move(dict));
  }

  {
    std::unique_ptr<MediaEngagementScore> score(
        new MediaEngagementScore(&test_clock, url, settings_map));
    EXPECT_EQ(media_playbacks, score->media_playbacks());
    EXPECT_EQ(media_playbacks, score->media_element_playbacks());

    base::RunLoop().RunUntilIdle();
  }

  {
    std::unique_ptr<base::DictionaryValue> dict =
        base::DictionaryValue::From(settings_map->GetWebsiteSetting(
            url, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT,
            content_settings::ResourceIdentifier(), nullptr));

    int stored_media_playbacks = 0;
    int stored_media_element_playbacks = 0;

    dict->GetInteger(MediaEngagementScore::kMediaPlaybacksKey,
                     &stored_media_playbacks);
    dict->GetInteger(MediaEngagementScore::kSignificantMediaPlaybacksKey,
                     &stored_media_element_playbacks);

    EXPECT_EQ(media_playbacks, stored_media_playbacks);
    EXPECT_EQ(media_playbacks, stored_media_element_playbacks);
  }
}

// Test that we do not migrate media element playbacks if we have an audio
// context playback.
TEST_F(MediaEngagementScoreTest,
       NoMigrateMediaElementPlaybacks_AudioContextPresent) {
  const GURL url("https://www.example.com");
  HostContentSettingsMap* settings_map =
      HostContentSettingsMapFactory::GetForProfile(profile());
  int media_playbacks = 6;
  int audio_context_playbacks = 3;

  {
    std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
    dict->SetBoolean(MediaEngagementScore::kHasHighScoreKey, true);
    dict->SetInteger(MediaEngagementScore::kMediaPlaybacksKey, media_playbacks);
    dict->SetInteger(MediaEngagementScore::kSignificantAudioContextPlaybacksKey,
                     audio_context_playbacks);

    settings_map->SetWebsiteSettingDefaultScope(
        url, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT,
        content_settings::ResourceIdentifier(), std::move(dict));
  }

  {
    std::unique_ptr<MediaEngagementScore> score(
        new MediaEngagementScore(&test_clock, url, settings_map));
    EXPECT_EQ(media_playbacks, score->media_playbacks());
    EXPECT_EQ(0, score->media_element_playbacks());
    EXPECT_EQ(audio_context_playbacks, score->audio_context_playbacks());

    base::RunLoop().RunUntilIdle();
  }

  {
    std::unique_ptr<base::DictionaryValue> dict =
        base::DictionaryValue::From(settings_map->GetWebsiteSetting(
            url, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT,
            content_settings::ResourceIdentifier(), nullptr));

    EXPECT_NE(nullptr, dict->FindKey(MediaEngagementScore::kMediaPlaybacksKey));
    EXPECT_EQ(
        nullptr,
        dict->FindKey(MediaEngagementScore::kSignificantMediaPlaybacksKey));
  }
}

// Test that we do not migrate media element playbacks if we have a media
// element playback.
TEST_F(MediaEngagementScoreTest,
       NoMigrateMediaElementPlaybacks_MediaElementPresent) {
  const GURL url("https://www.example.com");
  HostContentSettingsMap* settings_map =
      HostContentSettingsMapFactory::GetForProfile(profile());
  int media_playbacks = 6;
  int media_element_playbacks = 3;

  {
    std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
    dict->SetBoolean(MediaEngagementScore::kHasHighScoreKey, true);
    dict->SetInteger(MediaEngagementScore::kMediaPlaybacksKey, media_playbacks);
    dict->SetInteger(MediaEngagementScore::kSignificantMediaPlaybacksKey,
                     media_element_playbacks);

    settings_map->SetWebsiteSettingDefaultScope(
        url, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT,
        content_settings::ResourceIdentifier(), std::move(dict));
  }

  {
    std::unique_ptr<MediaEngagementScore> score(
        new MediaEngagementScore(&test_clock, url, settings_map));
    EXPECT_EQ(media_playbacks, score->media_playbacks());
    EXPECT_EQ(media_element_playbacks, score->media_element_playbacks());

    base::RunLoop().RunUntilIdle();
  }

  {
    std::unique_ptr<base::DictionaryValue> dict =
        base::DictionaryValue::From(settings_map->GetWebsiteSetting(
            url, GURL(), CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT,
            content_settings::ResourceIdentifier(), nullptr));

    int stored_media_playbacks = 0;
    int stored_media_element_playbacks = 0;

    dict->GetInteger(MediaEngagementScore::kMediaPlaybacksKey,
                     &stored_media_playbacks);
    dict->GetInteger(MediaEngagementScore::kSignificantMediaPlaybacksKey,
                     &stored_media_element_playbacks);

    EXPECT_EQ(media_playbacks, stored_media_playbacks);
    EXPECT_EQ(media_element_playbacks, stored_media_element_playbacks);
  }
}
