Chromium Code Reviews| Index: chrome/browser/ui/login/login_prompt_browsertest.cc |
| diff --git a/chrome/browser/ui/login/login_prompt_browsertest.cc b/chrome/browser/ui/login/login_prompt_browsertest.cc |
| index e5dea589d6fbaec47174498e1d6c108d17d7687d..055ae030d71f2d8bc4e3ef885641c1194f41c277 100644 |
| --- a/chrome/browser/ui/login/login_prompt_browsertest.cc |
| +++ b/chrome/browser/ui/login/login_prompt_browsertest.cc |
| @@ -18,13 +18,16 @@ |
| #include "chrome/test/base/in_process_browser_test.h" |
| #include "chrome/test/base/ui_test_utils.h" |
| #include "content/public/browser/interstitial_page.h" |
| +#include "content/public/browser/navigation_entry.h" |
| #include "content/public/browser/notification_details.h" |
| #include "content/public/browser/notification_source.h" |
| #include "content/public/browser/web_contents.h" |
| +#include "content/public/common/ssl_status.h" |
| #include "content/public/test/browser_test_utils.h" |
| #include "content/public/test/test_navigation_observer.h" |
| #include "net/base/auth.h" |
| #include "net/dns/mock_host_resolver.h" |
| +#include "net/test/spawned_test_server/spawned_test_server.h" |
| using content::NavigationController; |
| using content::OpenURLParams; |
| @@ -59,7 +62,8 @@ class LoginPromptBrowserTest : public InProcessBrowserTest { |
| typedef std::map<std::string, AuthInfo> AuthMap; |
| - void SetAuthFor(LoginHandler* handler); |
| + void CheckSSLState(content::WebContents* contents, bool expect_broken) const; |
| + void SetAuthFor(LoginHandler* handler) const; |
| AuthMap auth_map_; |
| std::string bad_password_; |
| @@ -69,11 +73,11 @@ class LoginPromptBrowserTest : public InProcessBrowserTest { |
| std::string username_digest_; |
| }; |
| -void LoginPromptBrowserTest::SetAuthFor(LoginHandler* handler) { |
| +void LoginPromptBrowserTest::SetAuthFor(LoginHandler* handler) const { |
| const net::AuthChallengeInfo* challenge = handler->auth_info(); |
| ASSERT_TRUE(challenge); |
| - AuthMap::iterator i = auth_map_.find(challenge->realm); |
| + AuthMap::const_iterator i = auth_map_.find(challenge->realm); |
| EXPECT_TRUE(auth_map_.end() != i); |
| if (i != auth_map_.end()) { |
| const AuthInfo& info = i->second; |
| @@ -82,6 +86,22 @@ void LoginPromptBrowserTest::SetAuthFor(LoginHandler* handler) { |
| } |
| } |
| +void LoginPromptBrowserTest::CheckSSLState( |
| + content::WebContents* contents, |
| + bool expect_broken) const { |
| + NavigationController* controller = &contents->GetController(); |
| + content::NavigationEntry* entry = controller->GetVisibleEntry(); |
| + const content::SSLStatus& ssl_status = entry->GetSSL(); |
| + EXPECT_EQ(content::SSLStatus::NORMAL_CONTENT, ssl_status.content_status); |
| + EXPECT_EQ(128, ssl_status.security_bits); |
| + if (!expect_broken) { |
| + EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED, ssl_status.security_style); |
| + } else { |
| + EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATION_BROKEN, |
| + ssl_status.security_style); |
| + } |
| +} |
| + |
| class InterstitialObserver : public content::WebContentsObserver { |
| public: |
| InterstitialObserver(content::WebContents* web_contents, |
| @@ -118,6 +138,18 @@ void WaitForInterstitialAttach(content::WebContents* web_contents) { |
| interstitial_attach_loop_runner->Run(); |
| } |
| +void CancelAndWaitForInterstitialDetach(LoginHandler* handler, |
| + content::WebContents* contents) { |
| + scoped_refptr<content::MessageLoopRunner> loop_runner( |
| + new content::MessageLoopRunner); |
| + InterstitialObserver interstitial_observer(contents, |
| + base::Closure(), |
| + loop_runner->QuitClosure()); |
| + handler->CancelAuth(); |
| + if (content::InterstitialPage::GetInterstitialPage(contents)) |
| + loop_runner->Run(); |
| +} |
| + |
| const char kPrefetchAuthPage[] = "files/login/prefetch.html"; |
| const char kMultiRealmTestPage[] = "files/login/multi_realm.html"; |
| @@ -1211,18 +1243,101 @@ IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest, |
| EXPECT_EQ("www.a.com", contents->GetURL().host()); |
| EXPECT_TRUE(contents->ShowingInterstitialPage()); |
| + CancelAndWaitForInterstitialDetach(*observer.handlers().begin(), contents); |
| + EXPECT_EQ("www.a.com", contents->GetURL().host()); |
| + EXPECT_FALSE(contents->ShowingInterstitialPage()); |
| + } |
| +} |
| + |
| +// Omnibox and connection tab should reflect the correct SSL State when login |
| +// prompt is displayed in the main frame. |
| +IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest, |
| + ShouldUpdateSSLStateOnMainFrameNavigation) { |
| + net::SpawnedTestServer https_server( |
| + net::SpawnedTestServer::TYPE_HTTPS, |
| + net::SpawnedTestServer::SSLOptions( |
| + net::SpawnedTestServer::SSLOptions::CERT_OK), |
| + base::FilePath() |
| + ); |
| + ASSERT_TRUE(https_server.Start()); |
| + content::WebContents* contents = |
| + browser()->tab_strip_model()->GetActiveWebContents(); |
| + NavigationController* controller = &contents->GetController(); |
| + LoginPromptBrowserTestObserver observer; |
| + |
| + observer.Register(content::Source<NavigationController>(controller)); |
| + { |
| + GURL test_page = https_server.GetURL(kAuthBasicPage); |
| + ASSERT_EQ("127.0.0.1", test_page.host()); |
| + |
| + WindowedAuthNeededObserver auth_needed_waiter(controller); |
| + browser()->OpenURL(OpenURLParams( |
| + test_page, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_TYPED, |
| + false)); |
| + ASSERT_EQ("127.0.0.1", contents->GetURL().host()); |
| + auth_needed_waiter.Wait(); |
| + ASSERT_EQ(1u, observer.handlers().size()); |
| + EXPECT_EQ("127.0.0.1", contents->GetVisibleURL().host()); |
| + EXPECT_FALSE(contents->ShowingInterstitialPage()); |
| + CheckSSLState(contents, false); |
| + |
| + EXPECT_EQ("127.0.0.1", contents->GetVisibleURL().host()); |
| + EXPECT_FALSE(contents->ShowingInterstitialPage()); |
| + CheckSSLState(contents, false); |
| + } |
| +} |
| + |
| +// Omnibox and connection tab should reflect the correct SSL State when login |
| +// prompt is displayed with a blank login interstitial on cross origin |
| +// navigations. |
| +IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest, |
| + ShouldUpdateSSLStateOnCrossOriginMainFrameNavigation) { |
| + host_resolver()->AddRule("www.a.com", "127.0.0.1"); |
| + net::SpawnedTestServer https_server( |
| + net::SpawnedTestServer::TYPE_HTTPS, |
| + net::SpawnedTestServer::SSLOptions( |
| + net::SpawnedTestServer::SSLOptions::CERT_OK), |
| + base::FilePath(FILE_PATH_LITERAL("chrome/test/data")) |
| + ); |
| + ASSERT_TRUE(https_server.Start()); |
| + |
| + content::WebContents* contents = |
| + browser()->tab_strip_model()->GetActiveWebContents(); |
| + NavigationController* controller = &contents->GetController(); |
| + LoginPromptBrowserTestObserver observer; |
| + |
| + observer.Register(content::Source<NavigationController>(controller)); |
| + |
| + // Load a page which navigates to a cross origin page with a login prompt. |
| + { |
| + const char* kTestPage = "files/login/cross_origin.html"; |
| + GURL test_page = https_server.GetURL(kTestPage); |
| + ASSERT_EQ("127.0.0.1", test_page.host()); |
| + |
| + WindowedAuthNeededObserver auth_needed_waiter(controller); |
| + browser()->OpenURL(OpenURLParams( |
| + test_page, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_TYPED, |
| + false)); |
| + ASSERT_EQ("127.0.0.1", contents->GetURL().host()); |
| + // Wait for the broken SSL interstitial for https://www.a.com and proceed |
| + // through it. |
| + WaitForInterstitialAttach(contents); |
| + contents->GetInterstitialPage()->Proceed(); |
| + // The auth prompt should show with the blank login interstitial, and the |
| + // SSL status should be broken. |
| + auth_needed_waiter.Wait(); |
| + ASSERT_EQ(1u, observer.handlers().size()); |
| + WaitForInterstitialAttach(contents); |
| + CheckSSLState(contents, true); |
| + // The omnibox should show the correct origin for the new page when the |
| + // login prompt is shown. |
| + EXPECT_EQ("www.a.com", contents->GetURL().host()); |
|
nasko
2014/07/24 09:32:34
nit: GetVisibleURL
Also, at this point we either
meacer
2014/07/24 17:32:32
Done.
|
| + EXPECT_TRUE(contents->ShowingInterstitialPage()); |
| // Cancel and wait for the interstitial to detach. |
| - LoginHandler* handler = *observer.handlers().begin(); |
| - scoped_refptr<content::MessageLoopRunner> loop_runner( |
| - new content::MessageLoopRunner); |
| - InterstitialObserver interstitial_observer(contents, |
| - base::Closure(), |
| - loop_runner->QuitClosure()); |
| - handler->CancelAuth(); |
| - if (content::InterstitialPage::GetInterstitialPage(contents)) |
| - loop_runner->Run(); |
| + CancelAndWaitForInterstitialDetach(*observer.handlers().begin(), contents); |
| EXPECT_EQ("www.a.com", contents->GetURL().host()); |
|
nasko
2014/07/24 09:32:33
nit: GetVisibleURL
Here we should have the LastCo
meacer
2014/07/24 17:32:32
Done.
|
| EXPECT_FALSE(contents->ShowingInterstitialPage()); |
| + CheckSSLState(contents, true); |
| } |
| } |