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