1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <set>
6 #include <string>
7
8 #include "base/memory/ref_counted.h"
9 #include "base/test/metrics/histogram_tester.h"
10 #include "base/values.h"
11 #include "chrome/browser/supervised_user/supervised_user_constants.h"
12 #include "chrome/browser/supervised_user/supervised_user_pref_store.h"
13 #include "chrome/browser/supervised_user/supervised_user_settings_service.h"
14 #include "chrome/common/net/safe_search_util.h"
15 #include "chrome/common/pref_names.h"
16 #include "components/prefs/testing_pref_store.h"
17 #include "extensions/buildflags/buildflags.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 using base::DictionaryValue;
21 using base::Value;
22
23 namespace {
24
25 class SupervisedUserPrefStoreFixture : public PrefStore::Observer {
26 public:
27 explicit SupervisedUserPrefStoreFixture(
28 SupervisedUserSettingsService* settings_service);
29 ~SupervisedUserPrefStoreFixture() override;
30
changed_prefs()31 base::DictionaryValue* changed_prefs() {
32 return &changed_prefs_;
33 }
34
initialization_completed() const35 bool initialization_completed() const {
36 return initialization_completed_;
37 }
38
39 // PrefStore::Observer implementation:
40 void OnPrefValueChanged(const std::string& key) override;
41 void OnInitializationCompleted(bool succeeded) override;
42
43 private:
44 scoped_refptr<SupervisedUserPrefStore> pref_store_;
45 base::DictionaryValue changed_prefs_;
46 bool initialization_completed_;
47 };
48
SupervisedUserPrefStoreFixture(SupervisedUserSettingsService * settings_service)49 SupervisedUserPrefStoreFixture::SupervisedUserPrefStoreFixture(
50 SupervisedUserSettingsService* settings_service)
51 : pref_store_(new SupervisedUserPrefStore(settings_service)),
52 initialization_completed_(pref_store_->IsInitializationComplete()) {
53 pref_store_->AddObserver(this);
54 }
55
~SupervisedUserPrefStoreFixture()56 SupervisedUserPrefStoreFixture::~SupervisedUserPrefStoreFixture() {
57 pref_store_->RemoveObserver(this);
58 }
59
OnPrefValueChanged(const std::string & key)60 void SupervisedUserPrefStoreFixture::OnPrefValueChanged(
61 const std::string& key) {
62 const base::Value* value = nullptr;
63 ASSERT_TRUE(pref_store_->GetValue(key, &value));
64 changed_prefs_.Set(key, std::make_unique<base::Value>(value->Clone()));
65 }
66
OnInitializationCompleted(bool succeeded)67 void SupervisedUserPrefStoreFixture::OnInitializationCompleted(bool succeeded) {
68 EXPECT_FALSE(initialization_completed_);
69 EXPECT_TRUE(succeeded);
70 EXPECT_TRUE(pref_store_->IsInitializationComplete());
71 initialization_completed_ = true;
72 }
73
74 } // namespace
75
76 class SupervisedUserPrefStoreTest : public ::testing::Test {
77 public:
SupervisedUserPrefStoreTest()78 SupervisedUserPrefStoreTest() {}
79 void SetUp() override;
80 void TearDown() override;
81
82 protected:
83 SupervisedUserSettingsService service_;
84 scoped_refptr<TestingPrefStore> pref_store_;
85 };
86
SetUp()87 void SupervisedUserPrefStoreTest::SetUp() {
88 pref_store_ = new TestingPrefStore();
89 service_.Init(pref_store_);
90 }
91
TearDown()92 void SupervisedUserPrefStoreTest::TearDown() {
93 service_.Shutdown();
94 }
95
TEST_F(SupervisedUserPrefStoreTest,ConfigureSettings)96 TEST_F(SupervisedUserPrefStoreTest, ConfigureSettings) {
97 SupervisedUserPrefStoreFixture fixture(&service_);
98 EXPECT_FALSE(fixture.initialization_completed());
99
100 // Prefs should not change yet when the service is ready, but not
101 // activated yet.
102 pref_store_->SetInitializationCompleted();
103 EXPECT_TRUE(fixture.initialization_completed());
104 EXPECT_EQ(0u, fixture.changed_prefs()->size());
105
106 service_.SetActive(true);
107
108 // kAllowDeletingBrowserHistory is hardcoded to false for supervised users.
109 bool allow_deleting_browser_history = true;
110 EXPECT_TRUE(fixture.changed_prefs()->GetBoolean(
111 prefs::kAllowDeletingBrowserHistory, &allow_deleting_browser_history));
112 EXPECT_FALSE(allow_deleting_browser_history);
113
114 // kSupervisedModeManualHosts does not have a hardcoded value.
115 base::DictionaryValue* manual_hosts = nullptr;
116 EXPECT_FALSE(fixture.changed_prefs()->GetDictionary(
117 prefs::kSupervisedUserManualHosts, &manual_hosts));
118
119 // kForceGoogleSafeSearch defaults to true and kForceYouTubeRestrict defaults
120 // to Moderate for supervised users.
121 bool force_google_safesearch = false;
122 int force_youtube_restrict = safe_search_util::YOUTUBE_RESTRICT_OFF;
123 EXPECT_TRUE(fixture.changed_prefs()->GetBoolean(prefs::kForceGoogleSafeSearch,
124 &force_google_safesearch));
125 EXPECT_TRUE(fixture.changed_prefs()->GetInteger(prefs::kForceYouTubeRestrict,
126 &force_youtube_restrict));
127 EXPECT_TRUE(force_google_safesearch);
128 EXPECT_EQ(force_youtube_restrict,
129 safe_search_util::YOUTUBE_RESTRICT_MODERATE);
130
131 #if BUILDFLAG(ENABLE_EXTENSIONS)
132 // Permissions requests default to disallowed.
133 bool extensions_may_request_permissions = false;
134 EXPECT_TRUE(fixture.changed_prefs()->GetBoolean(
135 prefs::kSupervisedUserExtensionsMayRequestPermissions,
136 &extensions_may_request_permissions));
137 EXPECT_FALSE(extensions_may_request_permissions);
138 #endif
139
140 // Activating the service again should not change anything.
141 fixture.changed_prefs()->Clear();
142 service_.SetActive(true);
143 EXPECT_EQ(0u, fixture.changed_prefs()->size());
144
145 // kSupervisedModeManualHosts can be configured by the custodian.
146 base::Value hosts(base::Value::Type::DICTIONARY);
147 hosts.SetBoolKey("example.com", true);
148 hosts.SetBoolKey("moose.org", false);
149 service_.SetLocalSetting(supervised_users::kContentPackManualBehaviorHosts,
150 std::make_unique<base::Value>(hosts.Clone()));
151 EXPECT_EQ(1u, fixture.changed_prefs()->size());
152 ASSERT_TRUE(fixture.changed_prefs()->GetDictionary(
153 prefs::kSupervisedUserManualHosts, &manual_hosts));
154 EXPECT_TRUE(*manual_hosts == hosts);
155
156 // kForceGoogleSafeSearch and kForceYouTubeRestrict can be configured by the
157 // custodian, overriding the hardcoded default.
158 fixture.changed_prefs()->Clear();
159 service_.SetLocalSetting(supervised_users::kForceSafeSearch,
160 std::make_unique<base::Value>(false));
161 EXPECT_EQ(1u, fixture.changed_prefs()->size());
162 EXPECT_TRUE(fixture.changed_prefs()->GetBoolean(prefs::kForceGoogleSafeSearch,
163 &force_google_safesearch));
164 EXPECT_TRUE(fixture.changed_prefs()->GetInteger(prefs::kForceYouTubeRestrict,
165 &force_youtube_restrict));
166 EXPECT_FALSE(force_google_safesearch);
167 EXPECT_EQ(force_youtube_restrict, safe_search_util::YOUTUBE_RESTRICT_OFF);
168
169 #if BUILDFLAG(ENABLE_EXTENSIONS)
170 // The custodian can allow sites and apps to request permissions.
171 // Currently tested indirectly by enabling geolocation requests.
172 // TODO(crbug/1024646): Update Kids Management server to set a new bit for
173 // extension permissions and update this test.
174
175 base::HistogramTester histogram_tester;
176 histogram_tester.ExpectTotalCount(
177 "SupervisedUsers.ExtensionsMayRequestPermissions", 0);
178
179 fixture.changed_prefs()->Clear();
180 service_.SetLocalSetting(supervised_users::kGeolocationDisabled,
181 std::make_unique<base::Value>(false));
182 EXPECT_EQ(1u, fixture.changed_prefs()->size());
183 EXPECT_TRUE(fixture.changed_prefs()->GetBoolean(
184 prefs::kSupervisedUserExtensionsMayRequestPermissions,
185 &extensions_may_request_permissions));
186 EXPECT_TRUE(extensions_may_request_permissions);
187
188 histogram_tester.ExpectUniqueSample(
189 "SupervisedUsers.ExtensionsMayRequestPermissions", /*enabled=*/true, 1);
190 histogram_tester.ExpectTotalCount(
191 "SupervisedUsers.ExtensionsMayRequestPermissions", 1);
192
193 fixture.changed_prefs()->Clear();
194 service_.SetLocalSetting(supervised_users::kGeolocationDisabled,
195 std::make_unique<base::Value>(true));
196 EXPECT_EQ(1u, fixture.changed_prefs()->size());
197 EXPECT_TRUE(fixture.changed_prefs()->GetBoolean(
198 prefs::kSupervisedUserExtensionsMayRequestPermissions,
199 &extensions_may_request_permissions));
200 EXPECT_FALSE(extensions_may_request_permissions);
201
202 histogram_tester.ExpectBucketCount(
203 "SupervisedUsers.ExtensionsMayRequestPermissions", /*enabled=*/false, 1);
204 histogram_tester.ExpectTotalCount(
205 "SupervisedUsers.ExtensionsMayRequestPermissions", 2);
206
207 #endif
208 }
209
TEST_F(SupervisedUserPrefStoreTest,ActivateSettingsBeforeInitialization)210 TEST_F(SupervisedUserPrefStoreTest, ActivateSettingsBeforeInitialization) {
211 SupervisedUserPrefStoreFixture fixture(&service_);
212 EXPECT_FALSE(fixture.initialization_completed());
213
214 service_.SetActive(true);
215 EXPECT_FALSE(fixture.initialization_completed());
216 EXPECT_EQ(0u, fixture.changed_prefs()->size());
217
218 pref_store_->SetInitializationCompleted();
219 EXPECT_TRUE(fixture.initialization_completed());
220 EXPECT_EQ(0u, fixture.changed_prefs()->size());
221 }
222
TEST_F(SupervisedUserPrefStoreTest,CreatePrefStoreAfterInitialization)223 TEST_F(SupervisedUserPrefStoreTest, CreatePrefStoreAfterInitialization) {
224 pref_store_->SetInitializationCompleted();
225 service_.SetActive(true);
226
227 SupervisedUserPrefStoreFixture fixture(&service_);
228 EXPECT_TRUE(fixture.initialization_completed());
229 EXPECT_EQ(0u, fixture.changed_prefs()->size());
230 }
231