supervised_user_browsertest.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
1a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file. 4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/command_line.h" 6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/prefs/pref_service.h" 7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/values.h" 9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/chrome_notification_types.h" 10a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "chrome/browser/common/cancelable_request.h" 11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/history/history_service_factory.h" 12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/infobars/infobar_service.h" 13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/supervised_user/supervised_user_constants.h" 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/supervised_user/supervised_user_interstitial.h" 16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/supervised_user/supervised_user_navigation_observer.h" 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/supervised_user/supervised_user_service.h" 1823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "chrome/browser/supervised_user/supervised_user_service_factory.h" 19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/supervised_user/supervised_user_settings_service.h" 20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h" 21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/ui/browser.h" 2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/browser/ui/browser_navigator.h" 2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model_observer.h" 2546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/common/chrome_switches.h" 26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/common/pref_names.h" 27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/test/base/in_process_browser_test.h" 28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/test/base/ui_test_utils.h" 29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/infobars/core/confirm_infobar_delegate.h" 30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/infobars/core/infobar.h" 31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/pref_registry/pref_registry_syncable.h" 32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/browser/interstitial_page.h" 33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/browser/navigation_controller.h" 34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/browser/navigation_entry.h" 35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/browser/notification_service.h" 36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/browser/web_contents.h" 37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/browser/web_contents_observer.h" 38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/test/browser_test_utils.h" 39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "grit/generated_resources.h" 40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)using content::InterstitialPage; 44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)using content::NavigationController; 45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)using content::NavigationEntry; 46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)using content::WebContents; 47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 48namespace { 49 50// Tests the filter mode in which all sites are blocked by default. 51class SupervisedUserBlockModeTest : public InProcessBrowserTest { 52 public: 53 // Indicates whether the interstitial should proceed or not. 54 enum InterstitialAction { 55 INTERSTITIAL_PROCEED, 56 INTERSTITIAL_DONTPROCEED, 57 }; 58 59 SupervisedUserBlockModeTest() : supervised_user_service_(NULL) {} 60 virtual ~SupervisedUserBlockModeTest() {} 61 62 void CheckShownPageIsInterstitial(WebContents* tab) { 63 CheckShownPage(tab, content::PAGE_TYPE_INTERSTITIAL); 64 } 65 66 void CheckShownPageIsNotInterstitial(WebContents* tab) { 67 CheckShownPage(tab, content::PAGE_TYPE_NORMAL); 68 } 69 70 // Checks to see if the type of the current page is |page_type|. 71 void CheckShownPage(WebContents* tab, content::PageType page_type) { 72 ASSERT_FALSE(tab->IsCrashed()); 73 NavigationEntry* entry = tab->GetController().GetActiveEntry(); 74 ASSERT_TRUE(entry); 75 ASSERT_EQ(page_type, entry->GetPageType()); 76 } 77 78 void SendAccessRequest(WebContents* tab) { 79 InterstitialPage* interstitial_page = tab->GetInterstitialPage(); 80 ASSERT_TRUE(interstitial_page); 81 82 // Get the SupervisedUserInterstitial delegate. 83 content::InterstitialPageDelegate* delegate = 84 interstitial_page->GetDelegateForTesting(); 85 86 // Simulate the click on the "request" button. 87 delegate->CommandReceived("\"request\""); 88 } 89 90 void GoBack(WebContents* tab) { 91 InterstitialPage* interstitial_page = tab->GetInterstitialPage(); 92 ASSERT_TRUE(interstitial_page); 93 94 // Get the SupervisedUserInterstitial delegate. 95 content::InterstitialPageDelegate* delegate = 96 interstitial_page->GetDelegateForTesting(); 97 98 // Simulate the click on the "back" button. 99 delegate->CommandReceived("\"back\""); 100 } 101 102 protected: 103 virtual void SetUpOnMainThread() OVERRIDE { 104 // Set up the SupervisedUserNavigationObserver manually since the profile 105 // was not supervised when the browser was created. 106 content::WebContents* web_contents = 107 browser()->tab_strip_model()->GetActiveWebContents(); 108 SupervisedUserNavigationObserver::CreateForWebContents(web_contents); 109 110 Profile* profile = browser()->profile(); 111 supervised_user_service_ = 112 SupervisedUserServiceFactory::GetForProfile(profile); 113 SupervisedUserSettingsService* supervised_user_settings_service = 114 SupervisedUserSettingsServiceFactory::GetForProfile(profile); 115 supervised_user_settings_service->SetLocalSettingForTesting( 116 supervised_users::kContentPackDefaultFilteringBehavior, 117 scoped_ptr<base::Value>( 118 new base::FundamentalValue(SupervisedUserURLFilter::BLOCK))); 119 } 120 121 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 122 // Enable the test server and remap all URLs to it. 123 ASSERT_TRUE(test_server()->Start()); 124 std::string host_port = test_server()->host_port_pair().ToString(); 125 command_line->AppendSwitchASCII(switches::kHostResolverRules, 126 "MAP *.example.com " + host_port + "," + 127 "MAP *.new-example.com " + host_port + "," + 128 "MAP *.a.com " + host_port); 129 130 command_line->AppendSwitchASCII(switches::kSupervisedUserId, "asdf"); 131 } 132 133 // Acts like a synchronous call to history's QueryHistory. Modified from 134 // history_querying_unittest.cc. 135 void QueryHistory(HistoryService* history_service, 136 const std::string& text_query, 137 const history::QueryOptions& options, 138 history::QueryResults* results) { 139 CancelableRequestConsumer history_request_consumer; 140 base::RunLoop run_loop; 141 history_service->QueryHistory( 142 base::UTF8ToUTF16(text_query), 143 options, 144 &history_request_consumer, 145 base::Bind(&SupervisedUserBlockModeTest::QueryHistoryComplete, 146 base::Unretained(this), 147 results, 148 &run_loop)); 149 run_loop.Run(); // Will go until ...Complete calls Quit. 150 } 151 152 void QueryHistoryComplete(history::QueryResults* new_results, 153 base::RunLoop* run_loop, 154 HistoryService::Handle /* handle */, 155 history::QueryResults* results) { 156 results->Swap(new_results); 157 run_loop->Quit(); // Will return out to QueryHistory. 158 } 159 160 SupervisedUserService* supervised_user_service_; 161}; 162 163class MockTabStripModelObserver : public TabStripModelObserver { 164 public: 165 explicit MockTabStripModelObserver(TabStripModel* tab_strip) 166 : tab_strip_(tab_strip) { 167 tab_strip_->AddObserver(this); 168 } 169 170 ~MockTabStripModelObserver() { 171 tab_strip_->RemoveObserver(this); 172 } 173 174 MOCK_METHOD3(TabClosingAt, void(TabStripModel*, content::WebContents*, int)); 175 176 private: 177 TabStripModel* tab_strip_; 178}; 179 180// Navigates to a blocked URL. 181IN_PROC_BROWSER_TEST_F(SupervisedUserBlockModeTest, 182 SendAccessRequestOnBlockedURL) { 183 GURL test_url("http://www.example.com/files/simple.html"); 184 ui_test_utils::NavigateToURL(browser(), test_url); 185 186 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 187 188 CheckShownPageIsInterstitial(tab); 189 190 SendAccessRequest(tab); 191 192 // TODO(sergiu): Properly check that the access request was sent here. 193 194 GoBack(tab); 195 196 // Make sure that the tab is still there. 197 EXPECT_EQ(tab, browser()->tab_strip_model()->GetActiveWebContents()); 198 199 CheckShownPageIsNotInterstitial(tab); 200} 201 202// Navigates to a blocked URL in a new tab. We expect the tab to be closed 203// automatically on pressing the "back" button on the interstitial. 204IN_PROC_BROWSER_TEST_F(SupervisedUserBlockModeTest, OpenBlockedURLInNewTab) { 205 TabStripModel* tab_strip = browser()->tab_strip_model(); 206 WebContents* prev_tab = tab_strip->GetActiveWebContents(); 207 208 // Open blocked URL in a new tab. 209 GURL test_url("http://www.example.com/files/simple.html"); 210 ui_test_utils::NavigateToURLWithDisposition( 211 browser(), test_url, NEW_FOREGROUND_TAB, 212 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 213 214 // Check that we got the interstitial. 215 WebContents* tab = tab_strip->GetActiveWebContents(); 216 CheckShownPageIsInterstitial(tab); 217 218 // On pressing the "back" button, the new tab should be closed, and we should 219 // get back to the previous active tab. 220 MockTabStripModelObserver observer(tab_strip); 221 EXPECT_CALL(observer, 222 TabClosingAt(tab_strip, tab, tab_strip->active_index())); 223 GoBack(tab); 224 EXPECT_EQ(prev_tab, tab_strip->GetActiveWebContents()); 225} 226 227// Tests whether a visit attempt adds a special history entry. 228IN_PROC_BROWSER_TEST_F(SupervisedUserBlockModeTest, 229 HistoryVisitRecorded) { 230 GURL allowed_url("http://www.example.com/files/simple.html"); 231 232 // Set the host as allowed. 233 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue); 234 dict->SetBooleanWithoutPathExpansion(allowed_url.host(), true); 235 SupervisedUserSettingsService* supervised_user_settings_service = 236 SupervisedUserSettingsServiceFactory::GetForProfile( 237 browser()->profile()); 238 supervised_user_settings_service->SetLocalSettingForTesting( 239 supervised_users::kContentPackManualBehaviorHosts, 240 dict.PassAs<base::Value>()); 241 EXPECT_EQ( 242 SupervisedUserService::MANUAL_ALLOW, 243 supervised_user_service_->GetManualBehaviorForHost(allowed_url.host())); 244 245 ui_test_utils::NavigateToURL(browser(), allowed_url); 246 247 // Navigate to it and check that we don't get an interstitial. 248 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 249 CheckShownPageIsNotInterstitial(tab); 250 251 // Navigate to a blocked page and go back on the interstitial. 252 GURL blocked_url("http://www.new-example.com/files/simple.html"); 253 ui_test_utils::NavigateToURL(browser(), blocked_url); 254 255 tab = browser()->tab_strip_model()->GetActiveWebContents(); 256 257 CheckShownPageIsInterstitial(tab); 258 GoBack(tab); 259 260 // Check that we went back to the first URL and that the manual behaviors 261 // have not changed. 262 EXPECT_EQ(allowed_url.spec(), tab->GetURL().spec()); 263 EXPECT_EQ(SupervisedUserService::MANUAL_ALLOW, 264 supervised_user_service_->GetManualBehaviorForHost( 265 "www.example.com")); 266 EXPECT_EQ( 267 SupervisedUserService::MANUAL_NONE, 268 supervised_user_service_->GetManualBehaviorForHost( 269 "www.new-example.com")); 270 271 // Query the history entry. 272 HistoryService* history_service = HistoryServiceFactory::GetForProfile( 273 browser()->profile(), Profile::EXPLICIT_ACCESS); 274 history::QueryOptions options; 275 history::QueryResults results; 276 QueryHistory(history_service, "", options, &results); 277 278 // Check that the entries have the correct blocked_visit value. 279 ASSERT_EQ(2u, results.size()); 280 EXPECT_EQ(blocked_url.spec(), results[0].url().spec()); 281 EXPECT_TRUE(results[0].blocked_visit()); 282 EXPECT_EQ(allowed_url.spec(), results[1].url().spec()); 283 EXPECT_FALSE(results[1].blocked_visit()); 284} 285 286IN_PROC_BROWSER_TEST_F(SupervisedUserBlockModeTest, Unblock) { 287 GURL test_url("http://www.example.com/files/simple.html"); 288 ui_test_utils::NavigateToURL(browser(), test_url); 289 290 WebContents* web_contents = 291 browser()->tab_strip_model()->GetActiveWebContents(); 292 293 CheckShownPageIsInterstitial(web_contents); 294 295 content::WindowedNotificationObserver observer( 296 content::NOTIFICATION_LOAD_STOP, 297 content::NotificationService::AllSources()); 298 299 // Set the host as allowed. 300 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue); 301 dict->SetBooleanWithoutPathExpansion(test_url.host(), true); 302 SupervisedUserSettingsService* supervised_user_settings_service = 303 SupervisedUserSettingsServiceFactory::GetForProfile( 304 browser()->profile()); 305 supervised_user_settings_service->SetLocalSettingForTesting( 306 supervised_users::kContentPackManualBehaviorHosts, 307 dict.PassAs<base::Value>()); 308 EXPECT_EQ( 309 SupervisedUserService::MANUAL_ALLOW, 310 supervised_user_service_->GetManualBehaviorForHost(test_url.host())); 311 312 observer.Wait(); 313 EXPECT_EQ(test_url, web_contents->GetURL()); 314} 315 316} // namespace 317