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 <utility>
6
7 #include "base/bind.h"
8 #include "base/callback_helpers.h"
9 #include "base/command_line.h"
10 #include "base/run_loop.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/test/bind.h"
13 #include "base/values.h"
14 #include "chrome/browser/chrome_notification_types.h"
15 #include "chrome/browser/history/history_service_factory.h"
16 #include "chrome/browser/infobars/infobar_service.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/profiles/profile_key.h"
19 #include "chrome/browser/supervised_user/logged_in_user_mixin.h"
20 #include "chrome/browser/supervised_user/supervised_user_constants.h"
21 #include "chrome/browser/supervised_user/supervised_user_interstitial.h"
22 #include "chrome/browser/supervised_user/supervised_user_navigation_observer.h"
23 #include "chrome/browser/supervised_user/supervised_user_service.h"
24 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
25 #include "chrome/browser/supervised_user/supervised_user_settings_service.h"
26 #include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h"
27 #include "chrome/browser/ui/browser.h"
28 #include "chrome/browser/ui/tabs/tab_strip_model.h"
29 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
30 #include "chrome/test/base/ui_test_utils.h"
31 #include "components/infobars/core/confirm_infobar_delegate.h"
32 #include "components/infobars/core/infobar.h"
33 #include "components/pref_registry/pref_registry_syncable.h"
34 #include "components/prefs/pref_service.h"
35 #include "content/public/browser/navigation_controller.h"
36 #include "content/public/browser/navigation_entry.h"
37 #include "content/public/browser/navigation_handle.h"
38 #include "content/public/browser/notification_service.h"
39 #include "content/public/browser/web_contents.h"
40 #include "content/public/browser/web_contents_observer.h"
41 #include "content/public/common/content_switches.h"
42 #include "content/public/test/browser_test.h"
43 #include "content/public/test/browser_test_utils.h"
44 #include "content/public/test/test_navigation_observer.h"
45 #include "content/public/test/test_utils.h"
46 #include "net/test/embedded_test_server/embedded_test_server.h"
47 #include "services/network/public/cpp/network_switches.h"
48
49 using content::NavigationController;
50 using content::NavigationEntry;
51 using content::WebContents;
52
53 namespace {
54
55 class InterstitialPageObserver : public content::WebContentsObserver {
56 public:
InterstitialPageObserver(WebContents * web_contents,const base::Closure & callback)57 InterstitialPageObserver(WebContents* web_contents,
58 const base::Closure& callback)
59 : content::WebContentsObserver(web_contents), callback_(callback) {}
~InterstitialPageObserver()60 ~InterstitialPageObserver() override {}
61
DidFinishNavigation(content::NavigationHandle * navigation_handle)62 void DidFinishNavigation(
63 content::NavigationHandle* navigation_handle) override {
64 // With committed interstitials, DidAttachInterstitialPage is not called, so
65 // call the callback from here if there was an error.
66 if (navigation_handle->IsErrorPage()) {
67 callback_.Run();
68 }
69 }
70
71 private:
72 base::Closure callback_;
73 };
74
75 // Tests filtering for supervised users.
76 class SupervisedUserURLFilterTest : public MixinBasedInProcessBrowserTest {
77 public:
78 // Indicates whether the interstitial should proceed or not.
79 enum InterstitialAction {
80 INTERSTITIAL_PROCEED,
81 INTERSTITIAL_DONTPROCEED,
82 };
83
84 SupervisedUserURLFilterTest() = default;
85 ~SupervisedUserURLFilterTest() override = default;
86
ShownPageIsInterstitial(Browser * browser)87 bool ShownPageIsInterstitial(Browser* browser) {
88 WebContents* tab = browser->tab_strip_model()->GetActiveWebContents();
89 EXPECT_FALSE(tab->IsCrashed());
90 base::string16 title;
91 ui_test_utils::GetCurrentTabTitle(browser, &title);
92 return tab->GetController().GetLastCommittedEntry()->GetPageType() ==
93 content::PAGE_TYPE_ERROR &&
94 title == base::ASCIIToUTF16("Site blocked");
95 }
96
SendAccessRequest(WebContents * tab)97 void SendAccessRequest(WebContents* tab) {
98 tab->GetMainFrame()->ExecuteJavaScriptForTests(
99 base::ASCIIToUTF16(
100 "supervisedUserErrorPageController.requestPermission()"),
101 base::NullCallback());
102 return;
103 }
104
GoBack(WebContents * tab)105 void GoBack(WebContents* tab) {
106 tab->GetMainFrame()->ExecuteJavaScriptForTests(
107 base::ASCIIToUTF16("supervisedUserErrorPageController.goBack()"),
108 base::NullCallback());
109 return;
110 }
111
GoBackAndWaitForNavigation(WebContents * tab)112 void GoBackAndWaitForNavigation(WebContents* tab) {
113 content::TestNavigationObserver observer(tab);
114 GoBack(tab);
115 observer.Wait();
116 }
117
118 protected:
SetUpCommandLine(base::CommandLine * command_line)119 void SetUpCommandLine(base::CommandLine* command_line) override {
120 // Remap all URLs to test server.
121 ASSERT_TRUE(embedded_test_server()->Started());
122 std::string host_port = embedded_test_server()->host_port_pair().ToString();
123 command_line->AppendSwitchASCII(network::switches::kHostResolverRules,
124 "MAP *.example.com " + host_port + "," +
125 "MAP *.new-example.com " + host_port +
126 "," + "MAP *.a.com " + host_port);
127 MixinBasedInProcessBrowserTest::SetUpCommandLine(command_line);
128 }
129
SetUpOnMainThread()130 void SetUpOnMainThread() override {
131 MixinBasedInProcessBrowserTest::SetUpOnMainThread();
132 logged_in_user_mixin_.LogInUser();
133
134 supervised_user_service_ =
135 SupervisedUserServiceFactory::GetForProfile(browser()->profile());
136 }
137
138 // Acts like a synchronous call to history's QueryHistory. Modified from
139 // history_querying_unittest.cc.
QueryHistory(history::HistoryService * history_service,const std::string & text_query,const history::QueryOptions & options,history::QueryResults * results)140 void QueryHistory(history::HistoryService* history_service,
141 const std::string& text_query,
142 const history::QueryOptions& options,
143 history::QueryResults* results) {
144 base::RunLoop run_loop;
145 base::CancelableTaskTracker history_task_tracker;
146 history_service->QueryHistory(
147 base::UTF8ToUTF16(text_query), options,
148 base::BindLambdaForTesting([&](history::QueryResults r) {
149 *results = std::move(r);
150 run_loop.Quit();
151 }),
152 &history_task_tracker);
153 run_loop.Run(); // Will go until ...Complete calls Quit.
154 }
155
156 SupervisedUserService* supervised_user_service_ = nullptr;
157
158 chromeos::LoggedInUserMixin logged_in_user_mixin_{
159 &mixin_host_, chromeos::LoggedInUserMixin::LogInType::kChild,
160 embedded_test_server(), this};
161 };
162
163 // Tests the filter mode in which all sites are blocked by default.
164 class SupervisedUserBlockModeTest : public SupervisedUserURLFilterTest {
165 public:
SetUpOnMainThread()166 void SetUpOnMainThread() override {
167 SupervisedUserURLFilterTest::SetUpOnMainThread();
168 Profile* profile = browser()->profile();
169 SupervisedUserSettingsService* supervised_user_settings_service =
170 SupervisedUserSettingsServiceFactory::GetForKey(
171 profile->GetProfileKey());
172 supervised_user_settings_service->SetLocalSetting(
173 supervised_users::kContentPackDefaultFilteringBehavior,
174 std::make_unique<base::Value>(SupervisedUserURLFilter::BLOCK));
175 }
176 };
177
178 class TabClosingObserver : public TabStripModelObserver {
179 public:
TabClosingObserver(TabStripModel * tab_strip,content::WebContents * contents)180 TabClosingObserver(TabStripModel* tab_strip, content::WebContents* contents)
181 : tab_strip_(tab_strip), contents_(contents) {
182 tab_strip_->AddObserver(this);
183 }
184
WaitForContentsClosing()185 void WaitForContentsClosing() {
186 if (!contents_)
187 return;
188
189 run_loop_.Run();
190 }
191
OnTabStripModelChanged(TabStripModel * tab_strip_model,const TabStripModelChange & change,const TabStripSelectionChange & selection)192 void OnTabStripModelChanged(
193 TabStripModel* tab_strip_model,
194 const TabStripModelChange& change,
195 const TabStripSelectionChange& selection) override {
196 if (change.type() != TabStripModelChange::kRemoved)
197 return;
198
199 auto* remove = change.GetRemove();
200 if (!remove->will_be_deleted)
201 return;
202
203 for (const auto& contents : remove->contents) {
204 if (contents_ == contents.contents) {
205 if (run_loop_.running())
206 run_loop_.Quit();
207 contents_ = nullptr;
208 return;
209 }
210 }
211 }
212
213 private:
214 TabStripModel* tab_strip_ = nullptr;
215
216 base::RunLoop run_loop_;
217
218 // Contents to wait for.
219 content::WebContents* contents_ = nullptr;
220
221 DISALLOW_COPY_AND_ASSIGN(TabClosingObserver);
222 };
223
224 // Navigates to a blocked URL.
IN_PROC_BROWSER_TEST_F(SupervisedUserBlockModeTest,SendAccessRequestOnBlockedURL)225 IN_PROC_BROWSER_TEST_F(SupervisedUserBlockModeTest,
226 SendAccessRequestOnBlockedURL) {
227 GURL test_url("http://www.example.com/simple.html");
228 ui_test_utils::NavigateToURL(browser(), test_url);
229
230 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
231
232 ASSERT_TRUE(ShownPageIsInterstitial(browser()));
233
234 SendAccessRequest(tab);
235
236 // TODO(sergiu): Properly check that the access request was sent here.
237
238 GoBackAndWaitForNavigation(tab);
239
240 // Make sure that the tab is still there.
241 EXPECT_EQ(tab, browser()->tab_strip_model()->GetActiveWebContents());
242
243 EXPECT_FALSE(ShownPageIsInterstitial(browser()));
244 }
245
246 // Navigates to a blocked URL in a new tab. We expect the tab to be closed
247 // automatically on pressing the "back" button on the interstitial.
IN_PROC_BROWSER_TEST_F(SupervisedUserBlockModeTest,OpenBlockedURLInNewTab)248 IN_PROC_BROWSER_TEST_F(SupervisedUserBlockModeTest, OpenBlockedURLInNewTab) {
249 TabStripModel* tab_strip = browser()->tab_strip_model();
250 WebContents* prev_tab = tab_strip->GetActiveWebContents();
251
252 // Open blocked URL in a new tab.
253 GURL test_url("http://www.example.com/simple.html");
254 ui_test_utils::NavigateToURLWithDisposition(
255 browser(), test_url, WindowOpenDisposition::NEW_FOREGROUND_TAB,
256 ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
257
258 // Check that we got the interstitial.
259 WebContents* tab = tab_strip->GetActiveWebContents();
260 ASSERT_TRUE(ShownPageIsInterstitial(browser()));
261
262 // On pressing the "back" button, the new tab should be closed, and we should
263 // get back to the previous active tab.
264 TabClosingObserver observer(tab_strip, tab);
265 GoBack(tab);
266 observer.WaitForContentsClosing();
267
268 EXPECT_EQ(prev_tab, tab_strip->GetActiveWebContents());
269 }
270
271 // Navigates to a page in a new tab, then blocks it (which makes the
272 // interstitial page behave differently from the preceding test, where the
273 // navigation is blocked before it commits). The expected behavior is the same
274 // though: the tab should be closed when going back.
IN_PROC_BROWSER_TEST_F(SupervisedUserURLFilterTest,BlockNewTabAfterLoading)275 IN_PROC_BROWSER_TEST_F(SupervisedUserURLFilterTest, BlockNewTabAfterLoading) {
276 TabStripModel* tab_strip = browser()->tab_strip_model();
277 WebContents* prev_tab = tab_strip->GetActiveWebContents();
278
279 // Open URL in a new tab.
280 GURL test_url("http://www.example.com/simple.html");
281 ui_test_utils::NavigateToURLWithDisposition(
282 browser(), test_url, WindowOpenDisposition::NEW_FOREGROUND_TAB,
283 ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
284
285 // Check that there is no interstitial.
286 WebContents* tab = tab_strip->GetActiveWebContents();
287 ASSERT_FALSE(ShownPageIsInterstitial(browser()));
288
289 {
290 // Block the current URL.
291 SupervisedUserSettingsService* supervised_user_settings_service =
292 SupervisedUserSettingsServiceFactory::GetForKey(
293 browser()->profile()->GetProfileKey());
294 supervised_user_settings_service->SetLocalSetting(
295 supervised_users::kContentPackDefaultFilteringBehavior,
296 std::make_unique<base::Value>(SupervisedUserURLFilter::BLOCK));
297
298 const SupervisedUserURLFilter* filter =
299 supervised_user_service_->GetURLFilter();
300 ASSERT_EQ(SupervisedUserURLFilter::BLOCK,
301 filter->GetFilteringBehaviorForURL(test_url));
302
303 content::TestNavigationObserver observer(tab);
304 observer.Wait();
305
306 // Check that we got the interstitial.
307 ASSERT_TRUE(ShownPageIsInterstitial(browser()));
308 }
309
310 {
311 // On pressing the "back" button, the new tab should be closed, and we
312 // should get back to the previous active tab.
313 TabClosingObserver observer(tab_strip, tab);
314 GoBack(tab);
315 observer.WaitForContentsClosing();
316 EXPECT_EQ(prev_tab, tab_strip->GetActiveWebContents());
317 }
318 }
319
320 // Tests that we don't end up canceling an interstitial (thereby closing the
321 // whole tab) by attempting to show a second one above it.
IN_PROC_BROWSER_TEST_F(SupervisedUserURLFilterTest,DontShowInterstitialTwice)322 IN_PROC_BROWSER_TEST_F(SupervisedUserURLFilterTest, DontShowInterstitialTwice) {
323 TabStripModel* tab_strip = browser()->tab_strip_model();
324
325 // Open URL in a new tab.
326 GURL test_url("http://www.example.com/simple.html");
327 ui_test_utils::NavigateToURLWithDisposition(
328 browser(), test_url, WindowOpenDisposition::NEW_FOREGROUND_TAB,
329 ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
330
331 // Check that there is no interstitial.
332 WebContents* tab = tab_strip->GetActiveWebContents();
333 ASSERT_FALSE(ShownPageIsInterstitial(browser()));
334
335 // Block the current URL.
336 SupervisedUserSettingsService* supervised_user_settings_service =
337 SupervisedUserSettingsServiceFactory::GetForKey(
338 browser()->profile()->GetProfileKey());
339 supervised_user_settings_service->SetLocalSetting(
340 supervised_users::kContentPackDefaultFilteringBehavior,
341 std::make_unique<base::Value>(SupervisedUserURLFilter::BLOCK));
342
343 const SupervisedUserURLFilter* filter =
344 supervised_user_service_->GetURLFilter();
345 ASSERT_EQ(SupervisedUserURLFilter::BLOCK,
346 filter->GetFilteringBehaviorForURL(test_url));
347
348 content::TestNavigationObserver observer(tab);
349 observer.Wait();
350
351 // Check that we got the interstitial.
352 ASSERT_TRUE(ShownPageIsInterstitial(browser()));
353
354 // Trigger a no-op change to the site lists, which will notify observers of
355 // the URL filter.
356 supervised_user_service_->OnSiteListUpdated();
357
358 EXPECT_EQ(tab, tab_strip->GetActiveWebContents());
359 }
360
361 // Tests that it's possible to navigate from a blocked page to another blocked
362 // page.
IN_PROC_BROWSER_TEST_F(SupervisedUserBlockModeTest,NavigateFromBlockedPageToBlockedPage)363 IN_PROC_BROWSER_TEST_F(SupervisedUserBlockModeTest,
364 NavigateFromBlockedPageToBlockedPage) {
365 GURL test_url("http://www.example.com/simple.html");
366 ui_test_utils::NavigateToURL(browser(), test_url);
367
368 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
369
370 ASSERT_TRUE(ShownPageIsInterstitial(browser()));
371
372 GURL test_url2("http://www.a.com/simple.html");
373 ui_test_utils::NavigateToURL(browser(), test_url2);
374
375 ASSERT_TRUE(ShownPageIsInterstitial(browser()));
376 EXPECT_EQ(test_url2, tab->GetVisibleURL());
377 }
378
379 // Tests whether a visit attempt adds a special history entry.
IN_PROC_BROWSER_TEST_F(SupervisedUserBlockModeTest,HistoryVisitRecorded)380 IN_PROC_BROWSER_TEST_F(SupervisedUserBlockModeTest, HistoryVisitRecorded) {
381 GURL allowed_url("http://www.example.com/simple.html");
382
383 const SupervisedUserURLFilter* filter =
384 supervised_user_service_->GetURLFilter();
385
386 // Set the host as allowed.
387 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
388 dict->SetKey(allowed_url.host(), base::Value(true));
389 SupervisedUserSettingsService* supervised_user_settings_service =
390 SupervisedUserSettingsServiceFactory::GetForKey(
391 browser()->profile()->GetProfileKey());
392 supervised_user_settings_service->SetLocalSetting(
393 supervised_users::kContentPackManualBehaviorHosts, std::move(dict));
394 EXPECT_EQ(SupervisedUserURLFilter::ALLOW,
395 filter->GetFilteringBehaviorForURL(allowed_url));
396 EXPECT_EQ(SupervisedUserURLFilter::ALLOW,
397 filter->GetFilteringBehaviorForURL(allowed_url.GetWithEmptyPath()));
398
399 ui_test_utils::NavigateToURL(browser(), allowed_url);
400
401 // Navigate to it and check that we don't get an interstitial.
402 ASSERT_FALSE(ShownPageIsInterstitial(browser()));
403
404 // Navigate to a blocked page and go back on the interstitial.
405 GURL blocked_url("http://www.new-example.com/simple.html");
406 ui_test_utils::NavigateToURL(browser(), blocked_url);
407
408 ASSERT_TRUE(ShownPageIsInterstitial(browser()));
409 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
410
411 GoBackAndWaitForNavigation(tab);
412
413 EXPECT_EQ(allowed_url.spec(), tab->GetURL().spec());
414 EXPECT_EQ(SupervisedUserURLFilter::ALLOW,
415 filter->GetFilteringBehaviorForURL(allowed_url.GetWithEmptyPath()));
416 EXPECT_EQ(SupervisedUserURLFilter::BLOCK,
417 filter->GetFilteringBehaviorForURL(blocked_url.GetWithEmptyPath()));
418
419 // Query the history entry.
420 history::HistoryService* history_service =
421 HistoryServiceFactory::GetForProfile(browser()->profile(),
422 ServiceAccessType::EXPLICIT_ACCESS);
423 history::QueryOptions options;
424 history::QueryResults results;
425 QueryHistory(history_service, "", options, &results);
426
427 // Check that the entries have the correct blocked_visit value.
428 ASSERT_EQ(2u, results.size());
429 EXPECT_EQ(blocked_url.spec(), results[1].url().spec());
430 EXPECT_TRUE(results[1].blocked_visit());
431 EXPECT_EQ(allowed_url.spec(), results[0].url().spec());
432 EXPECT_FALSE(results[0].blocked_visit());
433 }
434
IN_PROC_BROWSER_TEST_F(SupervisedUserURLFilterTest,GoBackOnDontProceed)435 IN_PROC_BROWSER_TEST_F(SupervisedUserURLFilterTest, GoBackOnDontProceed) {
436 WebContents* web_contents =
437 browser()->tab_strip_model()->GetActiveWebContents();
438 // Ensure navigation completes.
439 EXPECT_TRUE(WaitForLoadStop(web_contents));
440 // We start out at the initial navigation.
441 ASSERT_EQ(0, web_contents->GetController().GetCurrentEntryIndex());
442
443 GURL test_url("http://www.example.com/simple.html");
444 ui_test_utils::NavigateToURL(browser(), test_url);
445
446 ASSERT_FALSE(ShownPageIsInterstitial(browser()));
447
448 // Set the host as blocked and wait for the interstitial to appear.
449 auto dict = std::make_unique<base::DictionaryValue>();
450 dict->SetKey(test_url.host(), base::Value(false));
451 SupervisedUserSettingsService* supervised_user_settings_service =
452 SupervisedUserSettingsServiceFactory::GetForKey(
453 browser()->profile()->GetProfileKey());
454 supervised_user_settings_service->SetLocalSetting(
455 supervised_users::kContentPackManualBehaviorHosts, std::move(dict));
456
457 const SupervisedUserURLFilter* filter =
458 supervised_user_service_->GetURLFilter();
459 ASSERT_EQ(SupervisedUserURLFilter::BLOCK,
460 filter->GetFilteringBehaviorForURL(test_url));
461
462 content::TestNavigationObserver block_observer(web_contents);
463 block_observer.Wait();
464
465 content::WindowedNotificationObserver observer(
466 content::NOTIFICATION_LOAD_STOP,
467 content::NotificationService::AllSources());
468 GoBack(web_contents);
469 observer.Wait();
470
471 // We should have gone back to the initial navigation.
472 EXPECT_EQ(0, web_contents->GetController().GetCurrentEntryIndex());
473 }
474
IN_PROC_BROWSER_TEST_F(SupervisedUserURLFilterTest,ClosingBlockedTabDoesNotCrash)475 IN_PROC_BROWSER_TEST_F(SupervisedUserURLFilterTest,
476 ClosingBlockedTabDoesNotCrash) {
477 WebContents* web_contents =
478 browser()->tab_strip_model()->GetActiveWebContents();
479 // Ensure navigation completes.
480 EXPECT_TRUE(WaitForLoadStop(web_contents));
481 ASSERT_EQ(0, web_contents->GetController().GetCurrentEntryIndex());
482
483 GURL test_url("http://www.example.com/simple.html");
484 ui_test_utils::NavigateToURL(browser(), test_url);
485
486 ASSERT_FALSE(ShownPageIsInterstitial(browser()));
487
488 // Set the host as blocked and wait for the interstitial to appear.
489 auto dict = std::make_unique<base::DictionaryValue>();
490 dict->SetKey(test_url.host(), base::Value(false));
491 SupervisedUserSettingsService* supervised_user_settings_service =
492 SupervisedUserSettingsServiceFactory::GetForKey(
493 browser()->profile()->GetProfileKey());
494 supervised_user_settings_service->SetLocalSetting(
495 supervised_users::kContentPackManualBehaviorHosts, std::move(dict));
496
497 const SupervisedUserURLFilter* filter =
498 supervised_user_service_->GetURLFilter();
499 ASSERT_EQ(SupervisedUserURLFilter::BLOCK,
500 filter->GetFilteringBehaviorForURL(test_url));
501
502 // Verify that there is no crash when closing the blocked tab
503 // (https://crbug.com/719708).
504 browser()->tab_strip_model()->CloseWebContentsAt(
505 0, TabStripModel::CLOSE_USER_GESTURE);
506 }
507
IN_PROC_BROWSER_TEST_F(SupervisedUserURLFilterTest,BlockThenUnblock)508 IN_PROC_BROWSER_TEST_F(SupervisedUserURLFilterTest, BlockThenUnblock) {
509 GURL test_url("http://www.example.com/simple.html");
510 ui_test_utils::NavigateToURL(browser(), test_url);
511
512 WebContents* web_contents =
513 browser()->tab_strip_model()->GetActiveWebContents();
514
515 ASSERT_FALSE(ShownPageIsInterstitial(browser()));
516
517 // Set the host as blocked and wait for the interstitial to appear.
518 auto dict = std::make_unique<base::DictionaryValue>();
519 dict->SetKey(test_url.host(), base::Value(false));
520 SupervisedUserSettingsService* supervised_user_settings_service =
521 SupervisedUserSettingsServiceFactory::GetForKey(
522 browser()->profile()->GetProfileKey());
523 supervised_user_settings_service->SetLocalSetting(
524 supervised_users::kContentPackManualBehaviorHosts, std::move(dict));
525
526 const SupervisedUserURLFilter* filter =
527 supervised_user_service_->GetURLFilter();
528 ASSERT_EQ(SupervisedUserURLFilter::BLOCK,
529 filter->GetFilteringBehaviorForURL(test_url));
530
531 content::TestNavigationObserver block_observer(web_contents);
532 block_observer.Wait();
533
534 ASSERT_TRUE(ShownPageIsInterstitial(browser()));
535
536 dict = std::make_unique<base::DictionaryValue>();
537 dict->SetKey(test_url.host(), base::Value(true));
538 supervised_user_settings_service->SetLocalSetting(
539 supervised_users::kContentPackManualBehaviorHosts, std::move(dict));
540 ASSERT_EQ(SupervisedUserURLFilter::ALLOW,
541 filter->GetFilteringBehaviorForURL(test_url));
542
543 content::TestNavigationObserver unblock_observer(web_contents);
544 unblock_observer.Wait();
545
546 ASSERT_EQ(test_url, web_contents->GetURL());
547
548 EXPECT_FALSE(ShownPageIsInterstitial(browser()));
549 }
550
IN_PROC_BROWSER_TEST_F(SupervisedUserBlockModeTest,Unblock)551 IN_PROC_BROWSER_TEST_F(SupervisedUserBlockModeTest, Unblock) {
552 GURL test_url("http://www.example.com/simple.html");
553 ui_test_utils::NavigateToURL(browser(), test_url);
554
555 WebContents* web_contents =
556 browser()->tab_strip_model()->GetActiveWebContents();
557
558 ASSERT_TRUE(ShownPageIsInterstitial(browser()));
559
560 content::WindowedNotificationObserver observer(
561 content::NOTIFICATION_LOAD_STOP,
562 content::NotificationService::AllSources());
563
564 // Set the host as allowed.
565 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
566 dict->SetKey(test_url.host(), base::Value(true));
567 SupervisedUserSettingsService* supervised_user_settings_service =
568 SupervisedUserSettingsServiceFactory::GetForKey(
569 browser()->profile()->GetProfileKey());
570 supervised_user_settings_service->SetLocalSetting(
571 supervised_users::kContentPackManualBehaviorHosts, std::move(dict));
572
573 const SupervisedUserURLFilter* filter =
574 supervised_user_service_->GetURLFilter();
575 EXPECT_EQ(SupervisedUserURLFilter::ALLOW,
576 filter->GetFilteringBehaviorForURL(test_url.GetWithEmptyPath()));
577
578 observer.Wait();
579 EXPECT_EQ(test_url, web_contents->GetURL());
580 }
581
582 } // namespace
583