Don't show supervised user as "already on this device" while they're being imported.
[chromium-blink-merge.git] / chrome / browser / supervised_user / supervised_user_service_unittest.cc
bloba2a19992ec3a16c47d5d70b4f8320641cb23ed12
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.
5 #include "base/memory/scoped_ptr.h"
6 #include "base/path_service.h"
7 #include "base/prefs/pref_service.h"
8 #include "base/prefs/scoped_user_pref_update.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
14 #include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
15 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
16 #include "chrome/browser/signin/signin_manager_factory.h"
17 #include "chrome/browser/supervised_user/legacy/custodian_profile_downloader_service.h"
18 #include "chrome/browser/supervised_user/legacy/custodian_profile_downloader_service_factory.h"
19 #include "chrome/browser/supervised_user/permission_request_creator.h"
20 #include "chrome/browser/supervised_user/supervised_user_service.h"
21 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
22 #include "chrome/browser/supervised_user/supervised_user_whitelist_service.h"
23 #include "chrome/browser/ui/browser_list.h"
24 #include "chrome/common/chrome_paths.h"
25 #include "chrome/common/pref_names.h"
26 #include "chrome/test/base/testing_profile.h"
27 #include "components/signin/core/browser/signin_manager.h"
28 #include "content/public/test/test_browser_thread_bundle.h"
29 #include "content/public/test/test_utils.h"
30 #include "testing/gtest/include/gtest/gtest.h"
32 #if defined(ENABLE_EXTENSIONS)
33 #include "chrome/browser/extensions/extension_service.h"
34 #include "chrome/browser/extensions/extension_service_test_base.h"
35 #include "chrome/browser/extensions/unpacked_installer.h"
36 #include "chrome/common/extensions/features/feature_channel.h"
37 #include "extensions/common/extension.h"
38 #include "extensions/common/extension_builder.h"
39 #include "extensions/common/manifest_constants.h"
40 #endif
42 using content::MessageLoopRunner;
44 namespace {
46 void OnProfileDownloadedFail(const base::string16& full_name) {
47 ASSERT_TRUE(false) << "Profile download should not have succeeded.";
50 // Base class for helper objects that wait for certain events to happen.
51 // This class will ensure that calls to QuitRunLoop() (triggered by a subclass)
52 // are balanced with Wait() calls.
53 class AsyncTestHelper {
54 public:
55 void Wait() {
56 run_loop_->Run();
57 Reset();
60 protected:
61 AsyncTestHelper() {
62 // |quit_called_| will be initialized in Reset().
63 Reset();
66 ~AsyncTestHelper() {
67 EXPECT_FALSE(quit_called_);
70 void QuitRunLoop() {
71 // QuitRunLoop() can not be called more than once between calls to Wait().
72 ASSERT_FALSE(quit_called_);
73 quit_called_ = true;
74 run_loop_->Quit();
77 private:
78 void Reset() {
79 quit_called_ = false;
80 run_loop_.reset(new base::RunLoop);
83 scoped_ptr<base::RunLoop> run_loop_;
84 bool quit_called_;
86 DISALLOW_COPY_AND_ASSIGN(AsyncTestHelper);
89 class SupervisedUserURLFilterObserver
90 : public AsyncTestHelper,
91 public SupervisedUserURLFilter::Observer {
92 public:
93 SupervisedUserURLFilterObserver() : scoped_observer_(this) {}
94 ~SupervisedUserURLFilterObserver() {}
96 void Init(SupervisedUserURLFilter* url_filter) {
97 scoped_observer_.Add(url_filter);
100 // SupervisedUserURLFilter::Observer
101 void OnSiteListUpdated() override {
102 QuitRunLoop();
105 private:
106 ScopedObserver<SupervisedUserURLFilter, SupervisedUserURLFilter::Observer>
107 scoped_observer_;
109 DISALLOW_COPY_AND_ASSIGN(SupervisedUserURLFilterObserver);
112 class SiteListObserver : public AsyncTestHelper {
113 public:
114 SiteListObserver() {}
115 ~SiteListObserver() {}
117 void Init(SupervisedUserWhitelistService* service) {
118 service->AddSiteListsChangedCallback(base::Bind(
119 &SiteListObserver::OnSiteListsChanged, base::Unretained(this)));
121 // The initial call to AddSiteListsChangedCallback will call
122 // OnSiteListsChanged(), so we balance it out by calling Wait().
123 Wait();
126 const std::vector<scoped_refptr<SupervisedUserSiteList>>& site_lists() {
127 return site_lists_;
130 const std::vector<SupervisedUserSiteList::Site>& sites() {
131 return sites_;
134 private:
135 void OnSiteListsChanged(
136 const std::vector<scoped_refptr<SupervisedUserSiteList>>& site_lists) {
137 site_lists_ = site_lists;
138 sites_.clear();
139 for (const scoped_refptr<SupervisedUserSiteList>& site_list : site_lists) {
140 const std::vector<SupervisedUserSiteList::Site>& sites =
141 site_list->sites();
142 sites_.insert(sites_.end(), sites.begin(), sites.end());
145 QuitRunLoop();
148 std::vector<scoped_refptr<SupervisedUserSiteList>> site_lists_;
149 std::vector<SupervisedUserSiteList::Site> sites_;
151 DISALLOW_COPY_AND_ASSIGN(SiteListObserver);
154 class AsyncResultHolder {
155 public:
156 AsyncResultHolder() : result_(false) {}
157 ~AsyncResultHolder() {}
159 void SetResult(bool result) {
160 result_ = result;
161 run_loop_.Quit();
164 bool GetResult() {
165 run_loop_.Run();
166 return result_;
169 private:
170 base::RunLoop run_loop_;
171 bool result_;
173 DISALLOW_COPY_AND_ASSIGN(AsyncResultHolder);
176 class SupervisedUserServiceTest : public ::testing::Test {
177 public:
178 SupervisedUserServiceTest() {}
180 void SetUp() override {
181 TestingProfile::Builder builder;
182 builder.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(),
183 BuildFakeProfileOAuth2TokenService);
184 profile_ = builder.Build();
185 supervised_user_service_ =
186 SupervisedUserServiceFactory::GetForProfile(profile_.get());
189 void TearDown() override { profile_.reset(); }
191 ~SupervisedUserServiceTest() override {}
193 protected:
194 void AddURLAccessRequest(const GURL& url, AsyncResultHolder* result_holder) {
195 supervised_user_service_->AddURLAccessRequest(
196 url, base::Bind(&AsyncResultHolder::SetResult,
197 base::Unretained(result_holder)));
200 content::TestBrowserThreadBundle thread_bundle_;
201 scoped_ptr<TestingProfile> profile_;
202 SupervisedUserService* supervised_user_service_;
205 } // namespace
207 TEST_F(SupervisedUserServiceTest, ChangesIncludedSessionOnChangedSettings) {
208 supervised_user_service_->Init();
209 EXPECT_TRUE(supervised_user_service_->IncludesSyncSessionsType());
210 profile_->GetPrefs()->SetBoolean(prefs::kRecordHistory, false);
211 EXPECT_FALSE(supervised_user_service_->IncludesSyncSessionsType());
214 // Ensure that the CustodianProfileDownloaderService shuts down cleanly. If no
215 // DCHECK is hit when the service is destroyed, this test passed.
216 TEST_F(SupervisedUserServiceTest, ShutDownCustodianProfileDownloader) {
217 CustodianProfileDownloaderService* downloader_service =
218 CustodianProfileDownloaderServiceFactory::GetForProfile(profile_.get());
220 // Emulate being logged in, then start to download a profile so a
221 // ProfileDownloader gets created.
222 SigninManagerFactory::GetForProfile(profile_.get())->
223 SetAuthenticatedAccountInfo("12345", "Logged In");
224 downloader_service->DownloadProfile(base::Bind(&OnProfileDownloadedFail));
227 namespace {
229 class MockPermissionRequestCreator : public PermissionRequestCreator {
230 public:
231 MockPermissionRequestCreator() : enabled_(false) {}
232 ~MockPermissionRequestCreator() override {}
234 void set_enabled(bool enabled) {
235 enabled_ = enabled;
238 const std::vector<GURL>& requested_urls() const {
239 return requested_urls_;
242 void AnswerRequest(size_t index, bool result) {
243 ASSERT_LT(index, requested_urls_.size());
244 callbacks_[index].Run(result);
245 callbacks_.erase(callbacks_.begin() + index);
246 requested_urls_.erase(requested_urls_.begin() + index);
249 private:
250 // PermissionRequestCreator:
251 bool IsEnabled() const override { return enabled_; }
253 void CreateURLAccessRequest(const GURL& url_requested,
254 const SuccessCallback& callback) override {
255 ASSERT_TRUE(enabled_);
256 requested_urls_.push_back(url_requested);
257 callbacks_.push_back(callback);
260 void CreateExtensionUpdateRequest(const std::string& id,
261 const SuccessCallback& callback) override {
262 FAIL();
265 bool enabled_;
266 std::vector<GURL> requested_urls_;
267 std::vector<SuccessCallback> callbacks_;
269 DISALLOW_COPY_AND_ASSIGN(MockPermissionRequestCreator);
272 } // namespace
274 TEST_F(SupervisedUserServiceTest, CreatePermissionRequest) {
275 GURL url("http://www.example.com");
277 // Without any permission request creators, it should be disabled, and any
278 // AddURLAccessRequest() calls should fail.
279 EXPECT_FALSE(supervised_user_service_->AccessRequestsEnabled());
281 AsyncResultHolder result_holder;
282 AddURLAccessRequest(url, &result_holder);
283 EXPECT_FALSE(result_holder.GetResult());
286 // Add a disabled permission request creator. This should not change anything.
287 MockPermissionRequestCreator* creator = new MockPermissionRequestCreator;
288 supervised_user_service_->AddPermissionRequestCreator(
289 make_scoped_ptr(creator));
291 EXPECT_FALSE(supervised_user_service_->AccessRequestsEnabled());
293 AsyncResultHolder result_holder;
294 AddURLAccessRequest(url, &result_holder);
295 EXPECT_FALSE(result_holder.GetResult());
298 // Enable the permission request creator. This should enable permission
299 // requests and queue them up.
300 creator->set_enabled(true);
301 EXPECT_TRUE(supervised_user_service_->AccessRequestsEnabled());
303 AsyncResultHolder result_holder;
304 AddURLAccessRequest(url, &result_holder);
305 ASSERT_EQ(1u, creator->requested_urls().size());
306 EXPECT_EQ(url.spec(), creator->requested_urls()[0].spec());
308 creator->AnswerRequest(0, true);
309 EXPECT_TRUE(result_holder.GetResult());
313 AsyncResultHolder result_holder;
314 AddURLAccessRequest(url, &result_holder);
315 ASSERT_EQ(1u, creator->requested_urls().size());
316 EXPECT_EQ(url.spec(), creator->requested_urls()[0].spec());
318 creator->AnswerRequest(0, false);
319 EXPECT_FALSE(result_holder.GetResult());
322 // Add a second permission request creator.
323 MockPermissionRequestCreator* creator_2 = new MockPermissionRequestCreator;
324 creator_2->set_enabled(true);
325 supervised_user_service_->AddPermissionRequestCreator(
326 make_scoped_ptr(creator_2));
329 AsyncResultHolder result_holder;
330 AddURLAccessRequest(url, &result_holder);
331 ASSERT_EQ(1u, creator->requested_urls().size());
332 EXPECT_EQ(url.spec(), creator->requested_urls()[0].spec());
334 // Make the first creator succeed. This should make the whole thing succeed.
335 creator->AnswerRequest(0, true);
336 EXPECT_TRUE(result_holder.GetResult());
340 AsyncResultHolder result_holder;
341 AddURLAccessRequest(url, &result_holder);
342 ASSERT_EQ(1u, creator->requested_urls().size());
343 EXPECT_EQ(url.spec(), creator->requested_urls()[0].spec());
345 // Make the first creator fail. This should fall back to the second one.
346 creator->AnswerRequest(0, false);
347 ASSERT_EQ(1u, creator_2->requested_urls().size());
348 EXPECT_EQ(url.spec(), creator_2->requested_urls()[0].spec());
350 // Make the second creator succeed, which will make the whole thing succeed.
351 creator_2->AnswerRequest(0, true);
352 EXPECT_TRUE(result_holder.GetResult());
356 #if defined(ENABLE_EXTENSIONS)
357 class SupervisedUserServiceExtensionTestBase
358 : public extensions::ExtensionServiceTestBase {
359 public:
360 explicit SupervisedUserServiceExtensionTestBase(bool is_supervised)
361 : is_supervised_(is_supervised),
362 channel_(chrome::VersionInfo::CHANNEL_DEV) {}
363 ~SupervisedUserServiceExtensionTestBase() override {}
365 void SetUp() override {
366 ExtensionServiceTestBase::SetUp();
367 ExtensionServiceTestBase::ExtensionServiceInitParams params =
368 CreateDefaultInitParams();
369 params.profile_is_supervised = is_supervised_;
370 InitializeExtensionService(params);
371 SupervisedUserService* service =
372 SupervisedUserServiceFactory::GetForProfile(profile_.get());
373 service->Init();
374 site_list_observer_.Init(service->GetWhitelistService());
376 SupervisedUserURLFilter* url_filter = service->GetURLFilterForUIThread();
377 url_filter->SetBlockingTaskRunnerForTesting(
378 base::ThreadTaskRunnerHandle::Get());
379 url_filter_observer_.Init(url_filter);
381 // Wait for the initial update to finish.
382 url_filter_observer_.Wait();
385 void TearDown() override {
386 // Flush the message loop, to ensure all posted tasks run.
387 base::RunLoop().RunUntilIdle();
390 protected:
391 scoped_refptr<extensions::Extension> MakeThemeExtension() {
392 scoped_ptr<base::DictionaryValue> source(new base::DictionaryValue());
393 source->SetString(extensions::manifest_keys::kName, "Theme");
394 source->Set(extensions::manifest_keys::kTheme, new base::DictionaryValue());
395 source->SetString(extensions::manifest_keys::kVersion, "1.0");
396 extensions::ExtensionBuilder builder;
397 scoped_refptr<extensions::Extension> extension =
398 builder.SetManifest(source.Pass()).Build();
399 return extension;
402 scoped_refptr<extensions::Extension> MakeExtension(bool by_custodian) {
403 scoped_ptr<base::DictionaryValue> manifest = extensions::DictionaryBuilder()
404 .Set(extensions::manifest_keys::kName, "Extension")
405 .Set(extensions::manifest_keys::kVersion, "1.0")
406 .Build();
407 int creation_flags = extensions::Extension::NO_FLAGS;
408 if (by_custodian)
409 creation_flags |= extensions::Extension::WAS_INSTALLED_BY_CUSTODIAN;
410 extensions::ExtensionBuilder builder;
411 scoped_refptr<extensions::Extension> extension =
412 builder.SetManifest(manifest.Pass()).AddFlags(creation_flags).Build();
413 return extension;
416 bool is_supervised_;
417 extensions::ScopedCurrentChannel channel_;
418 SiteListObserver site_list_observer_;
419 SupervisedUserURLFilterObserver url_filter_observer_;
422 class SupervisedUserServiceExtensionTestUnsupervised
423 : public SupervisedUserServiceExtensionTestBase {
424 public:
425 SupervisedUserServiceExtensionTestUnsupervised()
426 : SupervisedUserServiceExtensionTestBase(false) {}
429 class SupervisedUserServiceExtensionTest
430 : public SupervisedUserServiceExtensionTestBase {
431 public:
432 SupervisedUserServiceExtensionTest()
433 : SupervisedUserServiceExtensionTestBase(true) {}
436 TEST_F(SupervisedUserServiceExtensionTest, ExtensionManagementPolicyProvider) {
437 SupervisedUserService* supervised_user_service =
438 SupervisedUserServiceFactory::GetForProfile(profile_.get());
439 ASSERT_TRUE(profile_->IsSupervised());
441 // Check that a supervised user can install and uninstall a theme.
443 scoped_refptr<extensions::Extension> theme = MakeThemeExtension();
445 base::string16 error_1;
446 EXPECT_TRUE(supervised_user_service->UserMayLoad(theme.get(), &error_1));
447 EXPECT_TRUE(error_1.empty());
449 base::string16 error_2;
450 EXPECT_FALSE(
451 supervised_user_service->MustRemainInstalled(theme.get(), &error_2));
452 EXPECT_TRUE(error_2.empty());
455 // Now check a different kind of extension; the supervised user should not be
456 // able to load it.
458 scoped_refptr<extensions::Extension> extension = MakeExtension(false);
460 base::string16 error;
461 EXPECT_FALSE(supervised_user_service->UserMayLoad(extension.get(), &error));
462 EXPECT_FALSE(error.empty());
466 // Check that a custodian-installed extension may be loaded, but not
467 // uninstalled.
468 scoped_refptr<extensions::Extension> extension = MakeExtension(true);
470 base::string16 error_1;
471 EXPECT_TRUE(
472 supervised_user_service->UserMayLoad(extension.get(), &error_1));
473 EXPECT_TRUE(error_1.empty());
475 base::string16 error_2;
476 EXPECT_TRUE(
477 supervised_user_service->MustRemainInstalled(extension.get(),
478 &error_2));
479 EXPECT_FALSE(error_2.empty());
482 #ifndef NDEBUG
483 EXPECT_FALSE(supervised_user_service->GetDebugPolicyProviderName().empty());
484 #endif
487 TEST_F(SupervisedUserServiceExtensionTest, NoContentPacks) {
488 SupervisedUserService* supervised_user_service =
489 SupervisedUserServiceFactory::GetForProfile(profile_.get());
490 SupervisedUserURLFilter* url_filter =
491 supervised_user_service->GetURLFilterForUIThread();
493 // ASSERT_EQ instead of ASSERT_TRUE([...].empty()) so that the error
494 // message contains the size in case of failure.
495 ASSERT_EQ(0u, site_list_observer_.site_lists().size());
497 GURL url("http://youtube.com");
498 EXPECT_EQ(SupervisedUserURLFilter::ALLOW,
499 url_filter->GetFilteringBehaviorForURL(url));
502 TEST_F(SupervisedUserServiceExtensionTest, InstallContentPacks) {
503 SupervisedUserService* supervised_user_service =
504 SupervisedUserServiceFactory::GetForProfile(profile_.get());
505 SupervisedUserURLFilter* url_filter =
506 supervised_user_service->GetURLFilterForUIThread();
508 GURL example_url("http://example.com");
509 GURL moose_url("http://moose.org");
510 EXPECT_EQ(SupervisedUserURLFilter::ALLOW,
511 url_filter->GetFilteringBehaviorForURL(example_url));
513 profile_->GetPrefs()->SetInteger(
514 prefs::kDefaultSupervisedUserFilteringBehavior,
515 SupervisedUserURLFilter::BLOCK);
516 EXPECT_EQ(SupervisedUserURLFilter::BLOCK,
517 url_filter->GetFilteringBehaviorForURL(example_url));
519 profile_->GetPrefs()->SetInteger(
520 prefs::kDefaultSupervisedUserFilteringBehavior,
521 SupervisedUserURLFilter::WARN);
522 EXPECT_EQ(SupervisedUserURLFilter::WARN,
523 url_filter->GetFilteringBehaviorForURL(example_url));
525 // Load a whitelist.
526 base::FilePath test_data_dir;
527 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir));
528 SupervisedUserWhitelistService* whitelist_service =
529 supervised_user_service->GetWhitelistService();
530 base::FilePath whitelist_path =
531 test_data_dir.AppendASCII("whitelists/content_pack/site_list.json");
532 whitelist_service->LoadWhitelistForTesting("aaaa", whitelist_path);
533 site_list_observer_.Wait();
535 ASSERT_EQ(1u, site_list_observer_.site_lists().size());
536 ASSERT_EQ(3u, site_list_observer_.sites().size());
537 EXPECT_EQ(base::ASCIIToUTF16("YouTube"), site_list_observer_.sites()[0].name);
538 EXPECT_EQ(base::ASCIIToUTF16("Homestar Runner"),
539 site_list_observer_.sites()[1].name);
540 EXPECT_EQ(base::string16(), site_list_observer_.sites()[2].name);
542 url_filter_observer_.Wait();
543 EXPECT_EQ(SupervisedUserURLFilter::ALLOW,
544 url_filter->GetFilteringBehaviorForURL(example_url));
545 EXPECT_EQ(SupervisedUserURLFilter::WARN,
546 url_filter->GetFilteringBehaviorForURL(moose_url));
548 // Load a second whitelist.
549 whitelist_path =
550 test_data_dir.AppendASCII("whitelists/content_pack_2/site_list.json");
551 whitelist_service->LoadWhitelistForTesting("bbbb", whitelist_path);
552 site_list_observer_.Wait();
554 ASSERT_EQ(2u, site_list_observer_.site_lists().size());
555 ASSERT_EQ(4u, site_list_observer_.sites().size());
557 // The site lists might be returned in any order, so we put them into a set.
558 std::set<std::string> site_names;
559 for (const SupervisedUserSiteList::Site& site : site_list_observer_.sites())
560 site_names.insert(base::UTF16ToUTF8(site.name));
561 EXPECT_EQ(1u, site_names.count("YouTube"));
562 EXPECT_EQ(1u, site_names.count("Homestar Runner"));
563 EXPECT_EQ(1u, site_names.count(std::string()));
564 EXPECT_EQ(1u, site_names.count("Moose"));
566 url_filter_observer_.Wait();
567 EXPECT_EQ(SupervisedUserURLFilter::ALLOW,
568 url_filter->GetFilteringBehaviorForURL(example_url));
569 EXPECT_EQ(SupervisedUserURLFilter::ALLOW,
570 url_filter->GetFilteringBehaviorForURL(moose_url));
572 // Unload the first whitelist.
573 whitelist_service->UnloadWhitelist("aaaa");
574 site_list_observer_.Wait();
576 ASSERT_EQ(1u, site_list_observer_.site_lists().size());
577 ASSERT_EQ(1u, site_list_observer_.sites().size());
578 EXPECT_EQ(base::ASCIIToUTF16("Moose"), site_list_observer_.sites()[0].name);
580 url_filter_observer_.Wait();
581 EXPECT_EQ(SupervisedUserURLFilter::WARN,
582 url_filter->GetFilteringBehaviorForURL(example_url));
583 EXPECT_EQ(SupervisedUserURLFilter::ALLOW,
584 url_filter->GetFilteringBehaviorForURL(moose_url));
586 #endif // defined(ENABLE_EXTENSIONS)