blob: af38c78edf89ffdfdbcbd0a3e82f0d401c64e405 [file] [log] [blame]
// Copyright 2016 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 <string>
#include <vector>
#include "base/command_line.h"
#include "base/strings/string_util.h"
#include "base/test/scoped_feature_list.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
#include "components/safe_browsing_db/safe_browsing_prefs.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace safe_browsing {
class SafeBrowsingPrefsTest : public ::testing::Test {
protected:
void SetUp() override {
prefs_.registry()->RegisterBooleanPref(
prefs::kSafeBrowsingExtendedReportingEnabled, false);
prefs_.registry()->RegisterBooleanPref(
prefs::kSafeBrowsingScoutReportingEnabled, false);
prefs_.registry()->RegisterBooleanPref(
prefs::kSafeBrowsingScoutGroupSelected, false);
ResetExperiments(/*can_show_scout=*/false, /*only_show_scout=*/false);
}
void ResetPrefs(bool sber_reporting, bool scout_reporting, bool scout_group) {
prefs_.SetBoolean(prefs::kSafeBrowsingExtendedReportingEnabled,
sber_reporting);
prefs_.SetBoolean(prefs::kSafeBrowsingScoutReportingEnabled,
scout_reporting);
prefs_.SetBoolean(prefs::kSafeBrowsingScoutGroupSelected, scout_group);
}
void ResetExperiments(bool can_show_scout, bool only_show_scout) {
std::vector<std::string> enabled_features;
std::vector<std::string> disabled_features;
auto* target_vector =
can_show_scout ? &enabled_features : &disabled_features;
target_vector->push_back(kCanShowScoutOptIn.name);
target_vector = only_show_scout ? &enabled_features : &disabled_features;
target_vector->push_back(kOnlyShowScoutOptIn.name);
feature_list_.reset(new base::test::ScopedFeatureList);
feature_list_->InitFromCommandLine(
base::JoinString(enabled_features, ","),
base::JoinString(disabled_features, ","));
}
std::string GetActivePref() { return GetExtendedReportingPrefName(prefs_); }
// Convenience method for explicitly setting up all combinations of prefs and
// experiments.
void TestGetPrefName(bool sber_reporting,
bool scout_reporting,
bool scout_group,
bool can_show_scout,
bool only_show_scout,
const std::string& expected_pref) {
ResetPrefs(sber_reporting, scout_reporting, scout_group);
ResetExperiments(can_show_scout, only_show_scout);
EXPECT_EQ(expected_pref, GetActivePref())
<< "sber=" << sber_reporting << " scout=" << scout_reporting
<< " scout_group=" << scout_group
<< " can_show_scout=" << can_show_scout
<< " only_show_scout=" << only_show_scout;
}
void InitPrefs() { InitializeSafeBrowsingPrefs(&prefs_); }
bool IsScoutGroupSelected() {
return prefs_.GetBoolean(prefs::kSafeBrowsingScoutGroupSelected);
}
void ExpectPrefs(bool sber_reporting,
bool scout_reporting,
bool scout_group) {
LOG(INFO) << "Pref values: sber=" << sber_reporting
<< " scout=" << scout_reporting << " scout_group=" << scout_group;
EXPECT_EQ(sber_reporting,
prefs_.GetBoolean(prefs::kSafeBrowsingExtendedReportingEnabled));
EXPECT_EQ(scout_reporting,
prefs_.GetBoolean(prefs::kSafeBrowsingScoutReportingEnabled));
EXPECT_EQ(scout_group,
prefs_.GetBoolean(prefs::kSafeBrowsingScoutGroupSelected));
}
void ExpectPrefsExist(bool sber_reporting,
bool scout_reporting,
bool scout_group) {
LOG(INFO) << "Prefs exist: sber=" << sber_reporting
<< " scout=" << scout_reporting << " scout_group=" << scout_group;
EXPECT_EQ(sber_reporting,
prefs_.HasPrefPath(prefs::kSafeBrowsingExtendedReportingEnabled));
EXPECT_EQ(scout_reporting,
prefs_.HasPrefPath(prefs::kSafeBrowsingScoutReportingEnabled));
EXPECT_EQ(scout_group,
prefs_.HasPrefPath(prefs::kSafeBrowsingScoutGroupSelected));
}
TestingPrefServiceSimple prefs_;
private:
std::unique_ptr<base::test::ScopedFeatureList> feature_list_;
};
// This test ensures that we correctly select between SBER and Scout as the
// active preference in a number of common scenarios.
TEST_F(SafeBrowsingPrefsTest, GetExtendedReportingPrefName_Common) {
const std::string& sber = prefs::kSafeBrowsingExtendedReportingEnabled;
const std::string& scout = prefs::kSafeBrowsingScoutReportingEnabled;
// By default (all prefs and experiment features disabled), SBER pref is used.
TestGetPrefName(false, false, false, false, false, sber);
// Changing any prefs (including ScoutGroupSelected) keeps SBER as the active
// pref because the experiment remains in the Control group.
TestGetPrefName(/*sber=*/true, false, false, false, false, sber);
TestGetPrefName(false, /*scout=*/true, false, false, false, sber);
TestGetPrefName(false, false, /*scout_group=*/true, false, false, sber);
// Being in either experiment group with ScoutGroup selected makes Scout the
// active pref.
TestGetPrefName(false, false, /*scout_group=*/true, /*can_show_scout=*/true,
false, scout);
TestGetPrefName(false, false, /*scout_group=*/true, false,
/*only_show_scout=*/true, scout);
// When ScoutGroup is not selected then SBER remains the active pref,
// regardless which experiment is enabled.
TestGetPrefName(false, false, false, /*can_show_scout=*/true, false, sber);
TestGetPrefName(false, false, false, false, /*only_show_scout=*/true, sber);
}
// Here we exhaustively check all combinations of pref and experiment states.
// This should help catch regressions.
TEST_F(SafeBrowsingPrefsTest, GetExtendedReportingPrefName_Exhaustive) {
const std::string& sber = prefs::kSafeBrowsingExtendedReportingEnabled;
const std::string& scout = prefs::kSafeBrowsingScoutReportingEnabled;
TestGetPrefName(false, false, false, false, false, sber);
TestGetPrefName(false, false, false, false, true, sber);
TestGetPrefName(false, false, false, true, false, sber);
TestGetPrefName(false, false, false, true, true, sber);
TestGetPrefName(false, false, true, false, false, sber);
TestGetPrefName(false, false, true, false, true, scout);
TestGetPrefName(false, false, true, true, false, scout);
TestGetPrefName(false, false, true, true, true, scout);
TestGetPrefName(false, true, false, false, false, sber);
TestGetPrefName(false, true, false, false, true, sber);
TestGetPrefName(false, true, false, true, false, sber);
TestGetPrefName(false, true, false, true, true, sber);
TestGetPrefName(false, true, true, false, false, sber);
TestGetPrefName(false, true, true, false, true, scout);
TestGetPrefName(false, true, true, true, false, scout);
TestGetPrefName(false, true, true, true, true, scout);
TestGetPrefName(true, false, false, false, false, sber);
TestGetPrefName(true, false, false, false, true, sber);
TestGetPrefName(true, false, false, true, false, sber);
TestGetPrefName(true, false, false, true, true, sber);
TestGetPrefName(true, false, true, false, false, sber);
TestGetPrefName(true, false, true, false, true, scout);
TestGetPrefName(true, false, true, true, false, scout);
TestGetPrefName(true, false, true, true, true, scout);
TestGetPrefName(true, true, false, false, false, sber);
TestGetPrefName(true, true, false, false, true, sber);
TestGetPrefName(true, true, false, true, false, sber);
TestGetPrefName(true, true, false, true, true, sber);
TestGetPrefName(true, true, true, false, false, sber);
TestGetPrefName(true, true, true, false, true, scout);
TestGetPrefName(true, true, true, true, false, scout);
TestGetPrefName(true, true, true, true, true, scout);
}
// Basic test that command-line flags can force the ScoutGroupSelected pref on
// or off.
TEST_F(SafeBrowsingPrefsTest, InitPrefs_ForceScoutGroupOnOff) {
// By default ScoutGroupSelected is off.
EXPECT_FALSE(IsScoutGroupSelected());
// Command-line flag can force it on during initialization.
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
kSwitchForceScoutGroup, "true");
InitPrefs();
EXPECT_TRUE(IsScoutGroupSelected());
// ScoutGroup remains on if switches are cleared, but only if an experiment
// is active (since being in the Control group automatically clears the
// Scout prefs).
base::CommandLine::StringVector empty;
base::CommandLine::ForCurrentProcess()->InitFromArgv(empty);
ResetExperiments(/*can_show_scout=*/true, /*only_show_scout=*/false);
EXPECT_TRUE(IsScoutGroupSelected());
// Nonsense values are ignored and ScoutGroup is unchanged.
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
kSwitchForceScoutGroup, "foo");
InitPrefs();
EXPECT_TRUE(IsScoutGroupSelected());
// ScoutGroup can also be forced off during initialization.
base::CommandLine::ForCurrentProcess()->InitFromArgv(empty);
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
kSwitchForceScoutGroup, "false");
InitPrefs();
EXPECT_FALSE(IsScoutGroupSelected());
}
// Test all combinations of prefs during initialization when neither experiment
// is on (ie: control group). In all cases the Scout prefs should be cleared,
// and the SBER pref may get switched.
TEST_F(SafeBrowsingPrefsTest, InitPrefs_Control) {
// Turn both experiments off.
ResetExperiments(/*can_show_scout=*/false, /*only_show_scout=*/false);
// Default case (everything off) - no change on init.
ResetPrefs(false, false, false);
InitPrefs();
ExpectPrefs(false, false, false);
// SBER pref exists because it was set to false above.
ExpectPrefsExist(true, false, false);
// ScoutGroup on - SBER cleared since Scout opt-in was shown but Scout pref
// was not chosen. Scout prefs cleared.
ResetPrefs(false, false, true);
InitPrefs();
ExpectPrefs(false, false, false);
ExpectPrefsExist(true, false, false);
// ScoutReporting on without ScoutGroup - SBER turns on since user opted-in to
// broader Scout reporting, we can continue collecting the SBER subset. Scout
// prefs cleared.
ResetPrefs(false, true, false);
InitPrefs();
ExpectPrefs(true, false, false);
ExpectPrefsExist(true, false, false);
// ScoutReporting and ScoutGroup on - SBER turns on since user opted-in to
// broader Scout reporting, we can continue collecting the SBER subset. Scout
// prefs cleared.
ResetPrefs(false, true, true);
InitPrefs();
ExpectPrefs(true, false, false);
ExpectPrefsExist(true, false, false);
// SBER on - no change on init since ScoutGroup is off implying that user
// never saw Scout opt-in text. Scout prefs remain cleared.
ResetPrefs(true, false, false);
InitPrefs();
ExpectPrefs(true, false, false);
ExpectPrefsExist(true, false, false);
// SBER and ScoutGroup on - SBER cleared. User previously opted-in to SBER
// and they saw Scout opt-in text (ie. ScoutGroup on), but chose not to opt-in
// to Scout reporting. We want them to re-evaluate their choice of SBER since
// the lack of Scout opt-in was a conscious choice. Scout cleared.
ResetPrefs(true, false, true);
InitPrefs();
ExpectPrefs(false, false, false);
ExpectPrefsExist(true, false, false);
// SBER and ScoutReporting on. User has opted-in to broader level of reporting
// so SBER stays on. Scout prefs cleared.
ResetPrefs(true, true, false);
InitPrefs();
ExpectPrefs(true, false, false);
ExpectPrefsExist(true, false, false);
// Everything on. User has opted-in to broader level of reporting so SBER
// stays on. Scout prefs cleared.
ResetPrefs(true, true, true);
InitPrefs();
ExpectPrefs(true, false, false);
ExpectPrefs(true, false, false);
}
// Tests a unique case where the Extended Reporting pref will be Cleared instead
// of set to False in order to mimic the state of the Scout reporting pref.
// This happens when a user is in the OnlyShowScoutOptIn experiment but never
// encounters a security issue so never sees the Scout opt-in. This user then
// returns to the Control group having never seen the Scout opt-in, so their
// Scout Reporting pref is un-set. We want to return their SBER pref to the
// unset state as well.
TEST_F(SafeBrowsingPrefsTest, InitPrefs_Control_SberPrefCleared) {
// Turn both experiments off.
ResetExperiments(/*can_show_scout=*/false, /*only_show_scout=*/false);
// Set the user's old SBER pref to on to be explicit.
prefs_.SetBoolean(prefs::kSafeBrowsingExtendedReportingEnabled, true);
// User is in the OnlyShowScoutOptIn experiment so they go directly to the
// Scout Group.
prefs_.SetBoolean(prefs::kSafeBrowsingScoutGroupSelected, true);
// But they never see a security popup or change the setting manually so the
// Scout pref remains unset.
prefs_.ClearPref(prefs::kSafeBrowsingScoutReportingEnabled);
InitPrefs();
// All pref values should be false and unset.
ExpectPrefs(false, false, false);
ExpectPrefsExist(false, false, false);
}
// Test all combinations of prefs during initialization when the CanShowScout
// experiment is on.
TEST_F(SafeBrowsingPrefsTest, InitPrefs_CanShowScout) {
// Turn the CanShowScout experiment on.
ResetExperiments(/*can_show_scout=*/true, /*only_show_scout=*/false);
// Default case (everything off) - ScoutGroup turns on because SBER is off.
ResetPrefs(false, false, false);
InitPrefs();
ExpectPrefs(false, false, true);
// ScoutGroup on - no change on init since ScoutGroup is already on.
ResetPrefs(false, false, true);
InitPrefs();
ExpectPrefs(false, false, true);
// ScoutReporting on without ScoutGroup - ScoutGroup turns on because SBER is
// off.
ResetPrefs(false, true, false);
InitPrefs();
ExpectPrefs(false, true, true);
// ScoutReporting and ScoutGroup on - no change on init since ScoutGroup is
// already on.
ResetPrefs(false, true, true);
InitPrefs();
ExpectPrefs(false, true, true);
// SBER on - no change on init. Will wait for first security incident before
// turning on ScoutGroup and displaying the Scout opt-in.
ResetPrefs(true, false, false);
InitPrefs();
ExpectPrefs(true, false, false);
// SBER and ScoutGroup on - no change on init since ScoutGroup is already on.
ResetPrefs(true, false, true);
InitPrefs();
ExpectPrefs(true, false, true);
// SBER and ScoutReporting on - no change on init because SBER is on.
// ScoutGroup will turn on on next security incident.
ResetPrefs(true, true, false);
InitPrefs();
ExpectPrefs(true, true, false);
// Everything on - no change on init since ScoutGroup is already on.
ResetPrefs(true, true, true);
InitPrefs();
ExpectPrefs(true, true, true);
}
// Test all combinations of prefs during initialization when the OnlyShowScout
// experiment is on.
TEST_F(SafeBrowsingPrefsTest, InitPrefs_OnlyShowScout) {
// Turn the OnlyShowScout experiment on.
ResetExperiments(/*can_show_scout=*/false, /*only_show_scout=*/true);
// Default case (everything off) - ScoutGroup turns on.
ResetPrefs(false, false, false);
InitPrefs();
ExpectPrefs(false, false, true);
// ScoutGroup on - no change on init since ScoutGroup is already on.
ResetPrefs(false, false, true);
InitPrefs();
ExpectPrefs(false, false, true);
// ScoutReporting on without ScoutGroup - ScoutGroup turns on.
ResetPrefs(false, true, false);
InitPrefs();
ExpectPrefs(false, true, true);
// ScoutReporting and ScoutGroup on - no change on init since ScoutGroup is
// already on.
ResetPrefs(false, true, true);
InitPrefs();
ExpectPrefs(false, true, true);
// SBER on - ScoutGroup turns on immediately, not waiting for first security
// incident.
ResetPrefs(true, false, false);
InitPrefs();
ExpectPrefs(true, false, true);
// SBER and ScoutGroup on - no change on init since ScoutGroup is already on.
ResetPrefs(true, false, true);
InitPrefs();
ExpectPrefs(true, false, true);
// SBER and ScoutReporting on - ScoutGroup turns on immediately, not waiting
// for first security incident.
ResetPrefs(true, true, false);
InitPrefs();
ExpectPrefs(true, true, true);
// Everything on - no change on init since ScoutGroup is already on.
ResetPrefs(true, true, true);
InitPrefs();
ExpectPrefs(true, true, true);
}
TEST_F(SafeBrowsingPrefsTest, ChooseOptInText) {
const int kSberResource = 100;
const int kScoutResource = 500;
// By default, SBER opt-in is used
EXPECT_EQ(kSberResource,
ChooseOptInTextResource(prefs_, kSberResource, kScoutResource));
// Enabling Scout switches to the Scout opt-in text.
ResetExperiments(/*can_show_scout=*/false, /*only_show_scout=*/true);
ResetPrefs(/*sber=*/false, /*scout=*/false, /*scout_group=*/true);
EXPECT_EQ(kScoutResource,
ChooseOptInTextResource(prefs_, kSberResource, kScoutResource));
}
TEST_F(SafeBrowsingPrefsTest, GetSafeBrowsingExtendedReportingLevel) {
// By Default, SBER is off
EXPECT_EQ(SBER_LEVEL_OFF, GetExtendedReportingLevel(prefs_));
// Opt-in to Legacy SBER gives Legacy reporting leve.
ResetPrefs(/*sber=*/true, /*scout_reporting=*/false, /*scout_group=*/false);
EXPECT_EQ(SBER_LEVEL_LEGACY, GetExtendedReportingLevel(prefs_));
// The value of the Scout pref doesn't change the reporting level if the user
// is outside of the Scout Group and/or no experiment is running.
// No scout group.
ResetPrefs(/*sber=*/true, /*scout_reporting=*/true, /*scout_group=*/false);
EXPECT_EQ(SBER_LEVEL_LEGACY, GetExtendedReportingLevel(prefs_));
// Scout group but no experiment.
ResetPrefs(/*sber=*/true, /*scout_reporting=*/true, /*scout_group=*/true);
EXPECT_EQ(SBER_LEVEL_LEGACY, GetExtendedReportingLevel(prefs_));
// Remaining in the Scout Group and adding an experiment will switch to the
// Scout pref to determine reporting level.
ResetExperiments(/*can_show_scout=*/false, /*only_show_scout=*/true);
// Both reporting prefs off, so reporting is off.
ResetPrefs(/*sber=*/false, /*scout_reporting=*/false, /*scout_group=*/true);
EXPECT_EQ(SBER_LEVEL_OFF, GetExtendedReportingLevel(prefs_));
// Legacy pref on when we're using Scout - reporting remains off.
ResetPrefs(/*sber=*/true, /*scout_reporting=*/false, /*scout_group=*/true);
EXPECT_EQ(SBER_LEVEL_OFF, GetExtendedReportingLevel(prefs_));
// Turning on Scout gives us Scout level reporting
ResetPrefs(/*sber=*/false, /*scout_reporting=*/true, /*scout_group=*/true);
EXPECT_EQ(SBER_LEVEL_SCOUT, GetExtendedReportingLevel(prefs_));
// .. and the legacy pref doesn't affect this.
ResetPrefs(/*sber=*/true, /*scout_reporting=*/true, /*scout_group=*/true);
EXPECT_EQ(SBER_LEVEL_SCOUT, GetExtendedReportingLevel(prefs_));
}
} // namespace safe_browsing