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