Chromium Code Reviews| Index: chrome/browser/ssl/chrome_security_state_model_client_browser_tests.cc |
| diff --git a/chrome/browser/ssl/chrome_security_state_model_client_browser_tests.cc b/chrome/browser/ssl/chrome_security_state_model_client_browser_tests.cc |
| index 64a9b83d86c975ebceb35bf440b583b751500291..5ed53b7e645eea3237bb7a6c12575e77e2321723 100644 |
| --- a/chrome/browser/ssl/chrome_security_state_model_client_browser_tests.cc |
| +++ b/chrome/browser/ssl/chrome_security_state_model_client_browser_tests.cc |
| @@ -1122,6 +1122,214 @@ IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTestWithPasswordCcSwitch, |
| content::SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP); |
| } |
| +// A Browser subclass that keeps track of messages that have been |
| +// added to the console. Messages can be retrieved or cleared with |
| +// console_messages() and ClearConsoleMessages(). The user of this class |
| +// can set a callback to run when the next console message notification |
| +// arrives. |
| +class ConsoleWebContentsDelegate : public Browser { |
| + public: |
| + explicit ConsoleWebContentsDelegate(const Browser::CreateParams& params) |
| + : Browser(params) {} |
| + ~ConsoleWebContentsDelegate() override {} |
| + |
| + const std::vector<base::string16>& console_messages() const { |
| + return console_messages_; |
| + } |
| + |
| + void set_console_message_callback(const base::Closure& callback) { |
| + console_message_callback_ = callback; |
| + } |
| + |
| + void ClearConsoleMessages() { console_messages_.clear(); } |
| + |
| + // content::WebContentsDelegate |
| + bool AddMessageToConsole(content::WebContents* source, |
| + int32_t level, |
| + const base::string16& message, |
| + int32_t line_no, |
| + const base::string16& source_id) override { |
| + console_messages_.push_back(message); |
| + if (!console_message_callback_.is_null()) { |
| + console_message_callback_.Run(); |
| + console_message_callback_.Reset(); |
| + } |
| + return true; |
| + } |
| + |
| + private: |
| + std::vector<base::string16> console_messages_; |
| + base::Closure console_message_callback_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ConsoleWebContentsDelegate); |
| +}; |
| + |
| +// Checks that |delegate| has observed exactly one console message for |
| +// HTTP_SHOW_WARNING. This does not check for the exact string (for fear |
| +// of being too brittle) but rather just a keyword ("not secure"). |
| +void CheckForOneHttpWarningConsoleMessage( |
| + ConsoleWebContentsDelegate* delegate) { |
| + const std::vector<base::string16>& messages = delegate->console_messages(); |
| + ASSERT_EQ(1u, messages.size()); |
| + EXPECT_NE(base::string16::npos, |
| + messages[0].find(base::ASCIIToUTF16("not secure"))); |
| +} |
| + |
| +// Tests that console messages are printed upon a call to |
| +// GetSecurityInfo() on an HTTP_SHOW_WARNING page, exactly once per |
| +// main-frame navigation. |
|
elawrence
2016/10/14 15:12:27
Do we need a test for "navigation-like" operations
estark
2016/10/14 17:57:06
Done. I think (?) we can distinguish with Navigati
|
| +IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTestWithPasswordCcSwitch, |
| + ConsoleMessage) { |
| + ConsoleWebContentsDelegate* delegate = new ConsoleWebContentsDelegate( |
| + Browser::CreateParams(browser()->profile())); |
| + content::WebContents* original_contents = |
| + browser()->tab_strip_model()->GetActiveWebContents(); |
| + content::WebContents* contents = |
| + content::WebContents::Create(content::WebContents::CreateParams( |
| + original_contents->GetBrowserContext())); |
| + ASSERT_TRUE(contents); |
| + contents->SetDelegate(delegate); |
| + delegate->tab_strip_model()->AppendWebContents(contents, true); |
| + int index = delegate->tab_strip_model()->GetIndexOfWebContents(contents); |
| + delegate->tab_strip_model()->ActivateTabAt(index, true); |
| + ASSERT_EQ(contents, delegate->tab_strip_model()->GetActiveWebContents()); |
| + |
| + // Navigate to an HTTP page. Use a non-local hostname so that is it |
| + // not considered secure. |
| + GURL http_url = |
| + GetURLWithNonLocalHostname(embedded_test_server(), "/title1.html"); |
| + ui_test_utils::NavigateToURL(delegate, http_url); |
| + content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); |
| + ASSERT_TRUE(entry); |
| + EXPECT_EQ(http_url, entry->GetURL()); |
| + EXPECT_TRUE(delegate->console_messages().empty()); |
| + |
| + // Trigger the HTTP_SHOW_WARNING state. |
| + base::RunLoop first_message; |
| + delegate->set_console_message_callback(first_message.QuitClosure()); |
| + contents->OnPasswordInputShownOnHttp(); |
| + first_message.Run(); |
| + |
| + // Check that the HTTP_SHOW_WARNING state was actually triggered. |
| + ChromeSecurityStateModelClient* client = |
| + ChromeSecurityStateModelClient::FromWebContents(contents); |
| + ASSERT_TRUE(client); |
| + security_state::SecurityStateModel::SecurityInfo security_info; |
| + client->GetSecurityInfo(&security_info); |
| + EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
| + security_info.security_level); |
| + |
| + // Check that the expected console message is present. |
| + ASSERT_NO_FATAL_FAILURE(CheckForOneHttpWarningConsoleMessage(delegate)); |
| + delegate->ClearConsoleMessages(); |
| + |
| + // Two subsequent triggers of VisibleSSLStateChanged -- one on the |
| + // same navigation and one on another navigation -- should only result |
| + // in one additional console message. |
| + contents->OnCreditCardInputShownOnHttp(); |
| + GURL second_http_url = |
| + GetURLWithNonLocalHostname(embedded_test_server(), "/title2.html"); |
| + ui_test_utils::NavigateToURL(delegate, second_http_url); |
| + entry = contents->GetController().GetVisibleEntry(); |
| + ASSERT_TRUE(entry); |
| + EXPECT_EQ(second_http_url, entry->GetURL()); |
| + |
| + base::RunLoop second_message; |
| + delegate->set_console_message_callback(second_message.QuitClosure()); |
| + contents->OnPasswordInputShownOnHttp(); |
| + second_message.Run(); |
| + |
| + client->GetSecurityInfo(&security_info); |
| + EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
| + security_info.security_level); |
| + |
| + ASSERT_NO_FATAL_FAILURE(CheckForOneHttpWarningConsoleMessage(delegate)); |
| +} |
| + |
| +// Tests that new HTTP_SHOW_WARNING console messages are not printed for |
| +// subframe navigations. |
|
elawrence
2016/10/14 15:12:27
I think this means "Test that additional HTTP_SHOW
estark
2016/10/14 17:57:06
I clarified the comment, but I don't think it's ne
|
| +IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTestWithPasswordCcSwitch, |
| + ConsoleMessageNotPrintedForFrameNavigation) { |
| + ConsoleWebContentsDelegate* delegate = new ConsoleWebContentsDelegate( |
| + Browser::CreateParams(browser()->profile())); |
| + content::WebContents* original_contents = |
| + browser()->tab_strip_model()->GetActiveWebContents(); |
| + content::WebContents* contents = |
| + content::WebContents::Create(content::WebContents::CreateParams( |
| + original_contents->GetBrowserContext())); |
| + ASSERT_TRUE(contents); |
| + contents->SetDelegate(delegate); |
| + delegate->tab_strip_model()->AppendWebContents(contents, true); |
| + int index = delegate->tab_strip_model()->GetIndexOfWebContents(contents); |
| + delegate->tab_strip_model()->ActivateTabAt(index, true); |
| + ASSERT_EQ(contents, delegate->tab_strip_model()->GetActiveWebContents()); |
| + |
| + // Navigate to an HTTP page. Use a non-local hostname so that is it |
| + // not considered secure. |
| + GURL http_url = GetURLWithNonLocalHostname(embedded_test_server(), |
| + "/ssl/page_with_frame.html"); |
| + ui_test_utils::NavigateToURL(delegate, http_url); |
| + content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); |
| + ASSERT_TRUE(entry); |
| + EXPECT_EQ(http_url, entry->GetURL()); |
| + EXPECT_TRUE(delegate->console_messages().empty()); |
| + |
| + // Trigger the HTTP_SHOW_WARNING state. |
| + base::RunLoop first_message; |
| + delegate->set_console_message_callback(first_message.QuitClosure()); |
| + contents->OnPasswordInputShownOnHttp(); |
| + first_message.Run(); |
| + |
| + // Check that the HTTP_SHOW_WARNING state was actually triggered. |
| + ChromeSecurityStateModelClient* client = |
| + ChromeSecurityStateModelClient::FromWebContents(contents); |
| + ASSERT_TRUE(client); |
| + security_state::SecurityStateModel::SecurityInfo security_info; |
| + client->GetSecurityInfo(&security_info); |
| + EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
| + security_info.security_level); |
| + |
| + // Check that the expected console message is present. |
| + ASSERT_NO_FATAL_FAILURE(CheckForOneHttpWarningConsoleMessage(delegate)); |
| + delegate->ClearConsoleMessages(); |
| + |
| + // Navigate the subframe and trigger VisibleSSLStateChanged |
| + // again. While the security level is still HTTP_SHOW_WARNING, an |
| + // additional console message should not be logged because there was |
| + // already a console message logged for the current main-frame |
| + // navigation. |
| + content::WindowedNotificationObserver subframe_observer( |
| + content::NOTIFICATION_LOAD_STOP, |
| + content::Source<content::NavigationController>( |
| + &contents->GetController())); |
| + EXPECT_TRUE(content::ExecuteScript( |
| + contents, "document.getElementById('navFrame').src = '/title2.html';")); |
| + subframe_observer.Wait(); |
| + contents->OnCreditCardInputShownOnHttp(); |
| + EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
| + security_info.security_level); |
| + |
| + // Do a main frame navigation and then trigger HTTP_SHOW_WARNING |
| + // again. From the above subframe navigation and this main-frame |
| + // navigation, exactly one console message is expected. |
| + GURL second_http_url = |
| + GetURLWithNonLocalHostname(embedded_test_server(), "/title2.html"); |
| + ui_test_utils::NavigateToURL(delegate, second_http_url); |
| + entry = contents->GetController().GetVisibleEntry(); |
| + ASSERT_TRUE(entry); |
| + EXPECT_EQ(second_http_url, entry->GetURL()); |
| + |
| + base::RunLoop second_message; |
| + delegate->set_console_message_callback(second_message.QuitClosure()); |
| + contents->OnPasswordInputShownOnHttp(); |
| + second_message.Run(); |
| + |
| + client->GetSecurityInfo(&security_info); |
| + EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
| + security_info.security_level); |
| + ASSERT_NO_FATAL_FAILURE(CheckForOneHttpWarningConsoleMessage(delegate)); |
| +} |
| + |
| // Tests that the SecurityStateModel for a WebContents is up to date |
| // when the WebContents is inserted into a Browser's TabStripModel. |
| IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, AddedTab) { |