blob: c5bf5083eec3039f05a335e09a9dd1df46c41f70 [file] [log] [blame]
// 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/safe_browsing/settings_reset_prompt/settings_reset_prompt_config.h"
#include <map>
#include <set>
#include "base/strings/stringprintf.h"
#include "base/test/scoped_feature_list.h"
#include "base/time/time.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
namespace safe_browsing {
// A SHA256 hash for "mydomain.com".
const char kDomainHash[] =
"0a79eaf6adb7b1e60d3fa548aa63105f525a00448efbb59ee965b9351a90ac31";
bool IsPromptEnabled() {
return base::FeatureList::IsEnabled(kSettingsResetPrompt);
}
// Test class that initializes a ScopedFeatureList so that all tests
// start off with all features disabled.
class SettingsResetPromptConfigTest : public ::testing::Test {
protected:
typedef base::FieldTrialParams Parameters;
// Sets the settings reset prompt feature parameters, which has the
// side-effect of also enabling the feature.
void SetFeatureParams(const Parameters& params) {
scoped_feature_list_.Reset();
scoped_feature_list_.InitAndEnableFeatureWithParameters(
kSettingsResetPrompt, params);
}
Parameters GetDefaultFeatureParams() {
return {
{"domain_hashes", base::StringPrintf("{\"%s\": \"1\"}", kDomainHash)},
{"delay_before_prompt_seconds", "42"},
{"prompt_wave", "20170101"},
{"time_between_prompts_seconds", "3600"}};
}
base::test::ScopedFeatureList scoped_feature_list_;
};
TEST_F(SettingsResetPromptConfigTest, Create) {
ASSERT_FALSE(IsPromptEnabled());
// |Create()| should return nullptr when feature is not enabled.
EXPECT_FALSE(SettingsResetPromptConfig::Create());
// |Create()| should return false when feature is enabled, but parameters are
// |missing.
scoped_feature_list_.InitAndEnableFeature(kSettingsResetPrompt);
ASSERT_TRUE(IsPromptEnabled());
EXPECT_FALSE(SettingsResetPromptConfig::Create());
SetFeatureParams(Parameters());
EXPECT_FALSE(SettingsResetPromptConfig::Create());
// |Create()| should return a config when parameters are all present.
// Individual parameters are tested separately.
SetFeatureParams(GetDefaultFeatureParams());
EXPECT_TRUE(SettingsResetPromptConfig::Create());
}
TEST_F(SettingsResetPromptConfigTest, DomainHashesParam) {
Parameters params = GetDefaultFeatureParams();
// First, test bad values for the "domain_hashes" parameter.
// Parameter is missing.
ASSERT_EQ(params.erase("domain_hashes"), 1U);
SetFeatureParams(params);
EXPECT_FALSE(SettingsResetPromptConfig::Create());
// Parameter is an empty string.
params["domain_hashes"] = "";
SetFeatureParams(params);
EXPECT_FALSE(SettingsResetPromptConfig::Create());
// Invalid JSON.
params["domain_hashes"] = "bad json";
SetFeatureParams(params);
EXPECT_FALSE(SettingsResetPromptConfig::Create());
// Parameter is not a JSON dictionary.
params["domain_hashes"] = "[3]";
SetFeatureParams(params);
EXPECT_FALSE(SettingsResetPromptConfig::Create());
// Bad dictionary key.
params["domain_hashes"] = "\"bad key\": \"1\"";
SetFeatureParams(params);
EXPECT_FALSE(SettingsResetPromptConfig::Create());
// Dictionary key is too short.
params["domain_hashes"] = "\"1234abc\": \"1\"";
SetFeatureParams(params);
EXPECT_FALSE(SettingsResetPromptConfig::Create());
// Dictionary key has correct length, but is not a hex string.
std::string non_hex_key(64, 'x');
params["domain_hashes"] =
base::StringPrintf("{\"%s\": \"1\"}", non_hex_key.c_str());
SetFeatureParams(params);
EXPECT_FALSE(SettingsResetPromptConfig::Create());
// Correct key but non-integer value.
params["domain_hashes"] =
base::StringPrintf("{\"%s\": \"not integer\"}", kDomainHash);
SetFeatureParams(params);
EXPECT_FALSE(SettingsResetPromptConfig::Create());
// Correct key but integer value that is too big.
std::string too_big_int(99, '1');
params["domain_hashes"] =
base::StringPrintf("{\"%s\": \"%s\"}", kDomainHash, too_big_int.c_str());
SetFeatureParams(params);
EXPECT_FALSE(SettingsResetPromptConfig::Create());
// Correct key but negative integer value.
params["domain_hashes"] = base::StringPrintf("{\"%s\": \"-2\"}", kDomainHash);
SetFeatureParams(params);
EXPECT_FALSE(SettingsResetPromptConfig::Create());
// Should return non-nullptr with a correct set of parameters.
SetFeatureParams(GetDefaultFeatureParams());
EXPECT_TRUE(SettingsResetPromptConfig::Create());
}
TEST_F(SettingsResetPromptConfigTest, UrlToResetDomainId) {
SetFeatureParams(GetDefaultFeatureParams());
auto config = SettingsResetPromptConfig::Create();
ASSERT_TRUE(config);
// Should return negative value for URL with no match in the config.
EXPECT_LT(config->UrlToResetDomainId(GURL("http://www.hello.com")), 0);
// Should return 1, which is "mydomain.com"'s ID.
EXPECT_EQ(config->UrlToResetDomainId(GURL("http://www.sub.mydomain.com")), 1);
EXPECT_EQ(config->UrlToResetDomainId(GURL("http://www.mydomain.com")), 1);
EXPECT_EQ(config->UrlToResetDomainId(GURL("http://mydomain.com")), 1);
// These URLs should not match "mydomain.com".
EXPECT_LT(config->UrlToResetDomainId(GURL("http://mydomain")), 0);
EXPECT_LT(config->UrlToResetDomainId(GURL("http://mydomain.org")), 0);
EXPECT_LT(config->UrlToResetDomainId(GURL("http://prefixmydomain.com")), 0);
EXPECT_LT(config->UrlToResetDomainId(GURL("http://mydomain.com.com")), 0);
EXPECT_LT(config->UrlToResetDomainId(GURL("http://www.mydomain.com.com")), 0);
// Should return negative value for invalid URLs.
EXPECT_LT(config->UrlToResetDomainId(GURL("htp://mydomain.com")), 0);
EXPECT_LT(config->UrlToResetDomainId(GURL("http://mydomain com")), 0);
}
TEST_F(SettingsResetPromptConfigTest, UrlToResetDomainIdTLDs) {
// Ensure that we do not match top level or registry domains even in the
// presence of faulty config data that would match those.
// Hash for "com".
const char kTLDHash1[] =
"71b4f3a3748cd6843c01e293e701fce769f52381821e21daf2ff4fe9ea57a6f3";
// Hash for "co.uk".
const char kTLDHash2[] =
"ad4fad2f5e5fb480ff7f9f648c6b20bbd5e44362d86821e29d30e65e626299b0";
// Hash for "uk".
const char kTLDHash3[] =
"83116acf18e4dc4414762f584ff43d9979ff2c2b0e9e48fbc97b21e23d7004ec";
// Hash for "com.br".
const char kTLDHash4[] =
"1d9c4ffc5429a9b4529abf6fbe9f20b52b7401c8f0fed46c7ed67b1e3153932c";
// Hash for private registry domain "appspot.com".
const char kTLDHash5[] =
"bffd48c8162466106a84f42945bfbbcfe501c9f0931219e02ce46e275f05ba51";
Parameters params = GetDefaultFeatureParams();
params["domain_hashes"] = base::StringPrintf(
"{\"%s\": \"1\", \"%s\": \"2\", \"%s\": \"3\", \"%s\": \"4\", "
"\"%s\": \"5\"}",
kTLDHash1, kTLDHash2, kTLDHash3, kTLDHash4, kTLDHash5);
SetFeatureParams(params);
auto config = SettingsResetPromptConfig::Create();
ASSERT_TRUE(config);
EXPECT_LT(config->UrlToResetDomainId(GURL("http://something.com")), 0);
EXPECT_LT(config->UrlToResetDomainId(GURL("http://something.co.uk")), 0);
EXPECT_LT(config->UrlToResetDomainId(GURL("http://something.uk")), 0);
EXPECT_LT(config->UrlToResetDomainId(GURL("http://something.com.br")), 0);
EXPECT_LT(config->UrlToResetDomainId(GURL("http://something.appspot.com")),
0);
EXPECT_LT(config->UrlToResetDomainId(GURL("http://com")), 0);
EXPECT_LT(config->UrlToResetDomainId(GURL("http://co.uk")), 0);
EXPECT_LT(config->UrlToResetDomainId(GURL("http://uk")), 0);
EXPECT_LT(config->UrlToResetDomainId(GURL("http://com.br")), 0);
EXPECT_LT(config->UrlToResetDomainId(GURL("http://appspot.com")), 0);
}
TEST_F(SettingsResetPromptConfigTest, DelayBeforePromptSecondsParam) {
constexpr const char kDelayParam[] = "delay_before_prompt_seconds";
Parameters params = GetDefaultFeatureParams();
// Missing parameter.
ASSERT_EQ(params.erase(kDelayParam), 1U);
SetFeatureParams(params);
EXPECT_FALSE(SettingsResetPromptConfig::Create());
// Empty parameter.
params[kDelayParam] = "";
SetFeatureParams(params);
EXPECT_FALSE(SettingsResetPromptConfig::Create());
// Bad parameter value.
params[kDelayParam] = "not-a-number";
SetFeatureParams(params);
EXPECT_FALSE(SettingsResetPromptConfig::Create());
// Negative parameter value.
params[kDelayParam] = "-3";
SetFeatureParams(params);
EXPECT_FALSE(SettingsResetPromptConfig::Create());
// Correct parameter value.
params[kDelayParam] = "12";
SetFeatureParams(params);
{
auto config = SettingsResetPromptConfig::Create();
ASSERT_TRUE(config);
EXPECT_EQ(config->delay_before_prompt(), base::TimeDelta::FromSeconds(12));
}
// Correct edge case parameter value.
params["delay_before_prompt_seconds"] = "0";
SetFeatureParams(params);
{
auto config = SettingsResetPromptConfig::Create();
ASSERT_TRUE(config);
EXPECT_EQ(config->delay_before_prompt(), base::TimeDelta::FromSeconds(0));
}
}
TEST_F(SettingsResetPromptConfigTest, PromptWaveParam) {
constexpr const char kPromptWaveParam[] = "prompt_wave";
Parameters params = GetDefaultFeatureParams();
// Missing parameter.
ASSERT_EQ(params.erase(kPromptWaveParam), 1U);
SetFeatureParams(params);
EXPECT_FALSE(SettingsResetPromptConfig::Create());
// Empty parameter.
params[kPromptWaveParam] = "";
SetFeatureParams(params);
EXPECT_FALSE(SettingsResetPromptConfig::Create());
// Bad parameter value.
params[kPromptWaveParam] = "not-a-number";
SetFeatureParams(params);
EXPECT_FALSE(SettingsResetPromptConfig::Create());
// Negative parameter value.
params[kPromptWaveParam] = "-3";
SetFeatureParams(params);
EXPECT_FALSE(SettingsResetPromptConfig::Create());
// Correct parameter value.
params[kPromptWaveParam] = "20170202";
SetFeatureParams(params);
{
auto config = SettingsResetPromptConfig::Create();
ASSERT_TRUE(config);
EXPECT_EQ(config->prompt_wave(), 20170202);
}
}
TEST_F(SettingsResetPromptConfigTest, TimeBetweenPromptsParam) {
constexpr const char kParamName[] = "time_between_prompts_seconds";
Parameters params = GetDefaultFeatureParams();
// Missing parameter.
ASSERT_EQ(params.erase(kParamName), 1U);
SetFeatureParams(params);
EXPECT_FALSE(SettingsResetPromptConfig::Create());
// Empty parameter.
params[kParamName] = "";
SetFeatureParams(params);
EXPECT_FALSE(SettingsResetPromptConfig::Create());
// Bad parameter value.
params[kParamName] = "not-a-number";
SetFeatureParams(params);
EXPECT_FALSE(SettingsResetPromptConfig::Create());
// Negative parameter value.
params[kParamName] = "-3";
SetFeatureParams(params);
EXPECT_FALSE(SettingsResetPromptConfig::Create());
// Correct parameter value.
params[kParamName] = "3600";
SetFeatureParams(params);
{
auto config = SettingsResetPromptConfig::Create();
ASSERT_TRUE(config);
EXPECT_EQ(config->time_between_prompts(),
base::TimeDelta::FromSeconds(3600));
}
}
} // namespace safe_browsing