Home | History | Annotate | Download | only in signin
      1 // Copyright 2013 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 #ifndef CHROME_BROWSER_SIGNIN_SIGNIN_BROWSERTEST_H_
      6 #define CHROME_BROWSER_SIGNIN_SIGNIN_BROWSERTEST_H_
      7 
      8 #include "base/command_line.h"
      9 #include "chrome/browser/signin/chrome_signin_client.h"
     10 #include "chrome/browser/signin/chrome_signin_client_factory.h"
     11 #include "chrome/browser/signin/signin_promo.h"
     12 #include "chrome/browser/ui/browser.h"
     13 #include "chrome/browser/ui/singleton_tabs.h"
     14 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     15 #include "chrome/browser/ui/webui/signin/login_ui_service.h"
     16 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
     17 #include "chrome/common/chrome_switches.h"
     18 #include "chrome/common/url_constants.h"
     19 #include "chrome/test/base/in_process_browser_test.h"
     20 #include "chrome/test/base/ui_test_utils.h"
     21 #include "content/public/browser/notification_service.h"
     22 #include "content/public/browser/notification_types.h"
     23 #include "content/public/browser/render_process_host.h"
     24 #include "content/public/browser/render_view_host.h"
     25 #include "content/public/browser/web_contents.h"
     26 #include "content/public/browser/web_contents_observer.h"
     27 #include "content/public/common/content_switches.h"
     28 #include "google_apis/gaia/gaia_urls.h"
     29 #include "net/http/http_status_code.h"
     30 #include "net/url_request/test_url_fetcher_factory.h"
     31 #include "net/url_request/url_request_status.h"
     32 
     33 namespace {
     34 const char kNonSigninURL[] = "http://www.google.com";
     35 }
     36 
     37 class SigninBrowserTest : public InProcessBrowserTest {
     38  public:
     39   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
     40     https_server_.reset(new net::SpawnedTestServer(
     41         net::SpawnedTestServer::TYPE_HTTPS,
     42         net::SpawnedTestServer::kLocalhost,
     43         base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))));
     44     ASSERT_TRUE(https_server_->Start());
     45 
     46     // Add a host resolver rule to map all outgoing requests to the test server.
     47     // This allows us to use "real" hostnames in URLs, which we can use to
     48     // create arbitrary SiteInstances.
     49     command_line->AppendSwitchASCII(
     50         switches::kHostResolverRules,
     51         "MAP * " + https_server_->host_port_pair().ToString() +
     52             ",EXCLUDE localhost");
     53     command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
     54     // All tests in this file are for the web based sign in flows.
     55     // TODO(guohui): fix tests for inline sign in flows.
     56     command_line->AppendSwitch(switches::kEnableWebBasedSignin);
     57   }
     58 
     59   virtual void SetUp() OVERRIDE {
     60     factory_.reset(new net::URLFetcherImplFactory());
     61     fake_factory_.reset(new net::FakeURLFetcherFactory(factory_.get()));
     62     fake_factory_->SetFakeResponse(
     63         GaiaUrls::GetInstance()->service_login_url(), std::string(),
     64         net::HTTP_OK, net::URLRequestStatus::SUCCESS);
     65     fake_factory_->SetFakeResponse(
     66         GURL(kNonSigninURL), std::string(), net::HTTP_OK,
     67         net::URLRequestStatus::SUCCESS);
     68     // Yield control back to the InProcessBrowserTest framework.
     69     InProcessBrowserTest::SetUp();
     70   }
     71 
     72   virtual void TearDown() OVERRIDE {
     73     if (fake_factory_.get()) {
     74       fake_factory_->ClearFakeResponses();
     75       fake_factory_.reset();
     76     }
     77 
     78     // Cancel any outstanding URL fetches and destroy the URLFetcherImplFactory
     79     // we created.
     80     net::URLFetcher::CancelAll();
     81     factory_.reset();
     82     InProcessBrowserTest::TearDown();
     83   }
     84 
     85  private:
     86   // Fake URLFetcher factory used to mock out GAIA signin.
     87   scoped_ptr<net::FakeURLFetcherFactory> fake_factory_;
     88 
     89   // The URLFetcherImplFactory instance used to instantiate |fake_factory_|.
     90   scoped_ptr<net::URLFetcherImplFactory> factory_;
     91 
     92   scoped_ptr<net::SpawnedTestServer> https_server_;
     93 };
     94 
     95 // If the one-click-signin feature is not enabled (e.g Chrome OS), we
     96 // never grant signin privileges to any renderer processes.
     97 #if defined(ENABLE_ONE_CLICK_SIGNIN)
     98 const bool kOneClickSigninEnabled = true;
     99 #else
    100 const bool kOneClickSigninEnabled = false;
    101 #endif
    102 
    103 // Disabled on Windows due to flakiness. http://crbug.com/249055
    104 #if defined(OS_WIN)
    105 #define MAYBE_ProcessIsolation DISABLED_ProcessIsolation
    106 #else
    107 #define MAYBE_ProcessIsolation ProcessIsolation
    108 #endif
    109 IN_PROC_BROWSER_TEST_F(SigninBrowserTest, MAYBE_ProcessIsolation) {
    110   SigninClient* signin =
    111       ChromeSigninClientFactory::GetForProfile(browser()->profile());
    112   EXPECT_FALSE(signin->HasSigninProcess());
    113 
    114   ui_test_utils::NavigateToURL(browser(), signin::GetPromoURL(
    115       signin::SOURCE_NTP_LINK, true));
    116   EXPECT_EQ(kOneClickSigninEnabled, signin->HasSigninProcess());
    117 
    118   // Navigating away should change the process.
    119   ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIOmniboxURL));
    120   EXPECT_FALSE(signin->HasSigninProcess());
    121 
    122   ui_test_utils::NavigateToURL(browser(), signin::GetPromoURL(
    123       signin::SOURCE_NTP_LINK, true));
    124   EXPECT_EQ(kOneClickSigninEnabled, signin->HasSigninProcess());
    125 
    126   content::WebContents* active_tab =
    127       browser()->tab_strip_model()->GetActiveWebContents();
    128   int active_tab_process_id =
    129       active_tab->GetRenderProcessHost()->GetID();
    130   EXPECT_EQ(kOneClickSigninEnabled,
    131             signin->IsSigninProcess(active_tab_process_id));
    132   EXPECT_EQ(0, active_tab->GetRenderViewHost()->GetEnabledBindings());
    133 
    134   // Entry points to signin request "SINGLETON_TAB" mode, so a new request
    135   // shouldn't change anything.
    136   chrome::NavigateParams params(chrome::GetSingletonTabNavigateParams(
    137       browser(),
    138       GURL(signin::GetPromoURL(signin::SOURCE_NTP_LINK, false))));
    139   params.path_behavior = chrome::NavigateParams::IGNORE_AND_NAVIGATE;
    140   ShowSingletonTabOverwritingNTP(browser(), params);
    141   EXPECT_EQ(active_tab, browser()->tab_strip_model()->GetActiveWebContents());
    142   EXPECT_EQ(kOneClickSigninEnabled,
    143             signin->IsSigninProcess(active_tab_process_id));
    144 
    145   // Navigating away should change the process.
    146   ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUINewTabURL));
    147   EXPECT_FALSE(signin->IsSigninProcess(
    148       active_tab->GetRenderProcessHost()->GetID()));
    149 }
    150 
    151 #if defined (OS_MACOSX)
    152 // crbug.com/375197
    153 #define MAYBE_NotTrustedAfterRedirect DISABLED_NotTrustedAfterRedirect
    154 #else
    155 #define MAYBE_NotTrustedAfterRedirect NotTrustedAfterRedirect
    156 #endif
    157 
    158 IN_PROC_BROWSER_TEST_F(SigninBrowserTest, MAYBE_NotTrustedAfterRedirect) {
    159   SigninClient* signin =
    160       ChromeSigninClientFactory::GetForProfile(browser()->profile());
    161   EXPECT_FALSE(signin->HasSigninProcess());
    162 
    163   GURL url = signin::GetPromoURL(signin::SOURCE_NTP_LINK, true);
    164   ui_test_utils::NavigateToURL(browser(), url);
    165   EXPECT_EQ(kOneClickSigninEnabled, signin->HasSigninProcess());
    166 
    167   // Navigating in a different tab should not affect the sign-in process.
    168   ui_test_utils::NavigateToURLWithDisposition(
    169       browser(), GURL(kNonSigninURL), NEW_BACKGROUND_TAB,
    170       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
    171   EXPECT_EQ(kOneClickSigninEnabled, signin->HasSigninProcess());
    172 
    173   // Navigating away should clear the sign-in process.
    174   GURL redirect_url("https://accounts.google.com/server-redirect?"
    175       "https://foo.com?service=chromiumsync");
    176   ui_test_utils::NavigateToURL(browser(), redirect_url);
    177   EXPECT_FALSE(signin->HasSigninProcess());
    178 }
    179 
    180 class BackOnNTPCommitObserver : public content::WebContentsObserver {
    181  public:
    182   explicit BackOnNTPCommitObserver(content::WebContents* web_contents)
    183       : content::WebContentsObserver(web_contents) {
    184   }
    185 
    186   virtual void DidCommitProvisionalLoadForFrame(
    187       content::RenderFrameHost* render_frame_host,
    188       const GURL& url,
    189       ui::PageTransition transition_type) OVERRIDE {
    190     if (url == GURL(chrome::kChromeUINewTabURL) ||
    191         url == GURL(chrome::kChromeSearchLocalNtpUrl)) {
    192       content::WindowedNotificationObserver observer(
    193           content::NOTIFICATION_NAV_ENTRY_COMMITTED,
    194           content::NotificationService::AllSources());
    195       web_contents()->GetController().GoBack();
    196       observer.Wait();
    197     }
    198   }
    199 
    200  private:
    201   DISALLOW_COPY_AND_ASSIGN(BackOnNTPCommitObserver);
    202 };
    203 
    204 // This is a test for http://crbug.com/257277. It simulates the navigations
    205 // that occur if the user clicks on the "Skip for now" link at the signin page
    206 // and initiates a back navigation between the point of Commit and
    207 // DidStopLoading of the NTP.
    208 IN_PROC_BROWSER_TEST_F(SigninBrowserTest, SigninSkipForNowAndGoBack) {
    209   GURL ntp_url(chrome::kChromeUINewTabURL);
    210   GURL start_url = signin::GetPromoURL(signin::SOURCE_START_PAGE, false);
    211   GURL skip_url = signin::GetLandingURL("ntp", 1);
    212 
    213   SigninClient* signin =
    214       ChromeSigninClientFactory::GetForProfile(browser()->profile());
    215   EXPECT_FALSE(signin->HasSigninProcess());
    216 
    217   ui_test_utils::NavigateToURL(browser(), start_url);
    218   EXPECT_EQ(kOneClickSigninEnabled, signin->HasSigninProcess());
    219 
    220   content::WebContents* web_contents =
    221       browser()->tab_strip_model()->GetActiveWebContents();
    222 
    223   // Simulate clicking on the Skip for now link. It's important to have a
    224   // link transition so that OneClickSigninHelper removes the blank page
    225   // from the history.
    226   chrome::NavigateParams navigate_params(browser(),
    227                                          skip_url,
    228                                          ui::PAGE_TRANSITION_LINK);
    229   ui_test_utils::NavigateToURL(&navigate_params);
    230 
    231   // Register an observer that will navigate back immediately on the commit of
    232   // the NTP. This will allow us to hit the race condition of navigating back
    233   // before the DidStopLoading message of NTP gets delivered. This must be
    234   // created after the navigation to the skip_url has finished loading,
    235   // otherwise this observer will navigate back, before the history cleaner
    236   // has had a chance to remove the navigation entry.
    237   BackOnNTPCommitObserver commit_observer(web_contents);
    238 
    239   // Since OneClickSigninHelper aborts redirect to NTP, thus we expect the
    240   // visible URL to be the starting URL.
    241   EXPECT_EQ(skip_url, web_contents->GetLastCommittedURL());
    242   EXPECT_EQ(start_url, web_contents->GetVisibleURL());
    243 
    244   content::WindowedNotificationObserver observer(
    245       content::NOTIFICATION_LOAD_STOP,
    246       content::NotificationService::AllSources());
    247   observer.Wait();
    248   EXPECT_EQ(start_url, web_contents->GetLastCommittedURL());
    249 }
    250 #endif  // CHROME_BROWSER_SIGNIN_SIGNIN_BROWSERTEST_H_
    251