Commit b3a4a4bc authored by Eugene But's avatar Eugene But Committed by Commit Bot

Call DidChangeVisibleSecurityState when interstitial is dismissed.

Dismissing SSL interstitial may change SSL status, in which case
WebStateImpl should call WebStateObserver::DidChangeVisibleSecurityState

Bug: None
Cq-Include-Trybots: luci.chromium.try:ios-simulator-full-configs;master.tryserver.chromium.mac:ios-simulator-cronet
Change-Id: If9737cfa13829f17c2f4d9b5d965df2197f71669
Reviewed-on: https://chromium-review.googlesource.com/1114839
Commit-Queue: Stepan Khapugin <stkhapugin@chromium.org>
Reviewed-by: default avatarStepan Khapugin <stkhapugin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#570806}
parent 2c670dc8
......@@ -377,6 +377,7 @@ source_set("ios_web_web_state_unittests") {
"//ios/testing:ios_test_support",
"//ios/testing:ocmock_support",
"//ios/web",
"//ios/web/interstitials",
"//ios/web/navigation",
"//ios/web/public",
"//ios/web/public/test",
......@@ -384,6 +385,7 @@ source_set("ios_web_web_state_unittests") {
"//ios/web/test:mojo_bindings",
"//ios/web/test:test_constants",
"//ios/web/test:test_support",
"//ios/web/test/fakes",
"//ios/web/web_state",
"//ios/web/web_state:context_menu",
"//ios/web/web_state:error_translation_util",
......
......@@ -7,9 +7,9 @@
#include <memory>
#import "ios/web/navigation/navigation_manager_impl.h"
#import "ios/web/public/interstitials/web_interstitial_delegate.h"
#include "ios/web/public/test/fakes/test_web_state_observer.h"
#include "ios/web/public/test/web_test.h"
#import "ios/web/test/fakes/mock_interstitial_delegate.h"
#import "ios/web/web_state/web_state_impl.h"
#include "testing/gmock/include/gmock/gmock.h"
......@@ -23,17 +23,6 @@ namespace {
const char kTestHostName[] = "https://chromium.test/";
// A mock html web interstitial delegate.
class MockInterstitialDelegate : public HtmlWebInterstitialDelegate {
public:
~MockInterstitialDelegate() override = default;
// HtmlWebMockInterstitialDelegate overrides
MOCK_METHOD0(OnProceed, void());
MOCK_METHOD0(OnDontProceed, void());
std::string GetHtmlContents() const override { return ""; }
};
} // namespace
// Test fixture for HtmlWebInterstitialImpl class.
......
......@@ -11,6 +11,7 @@ source_set("fakes") {
"//ios/web/navigation:core",
"//ios/web/public:public",
"//ios/web/web_state/ui:crw_web_view_navigation_proxy",
"//testing/gmock",
"//third_party/ocmock:ocmock",
]
......@@ -23,6 +24,8 @@ source_set("fakes") {
"crw_fake_wk_navigation_response.mm",
"fake_navigation_manager_delegate.h",
"fake_navigation_manager_delegate.mm",
"mock_interstitial_delegate.h",
"mock_interstitial_delegate.mm",
]
libs = [ "WebKit.framework" ]
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_WEB_TEST_FAKES_MOCK_INTERSTITIAL_DELEGATE_H_
#define IOS_WEB_TEST_FAKES_MOCK_INTERSTITIAL_DELEGATE_H_
#import "ios/web/public/interstitials/web_interstitial_delegate.h"
#include "testing/gmock/include/gmock/gmock.h"
// A mock html web interstitial delegate.
class MockInterstitialDelegate : public web::HtmlWebInterstitialDelegate {
public:
MockInterstitialDelegate();
~MockInterstitialDelegate();
// HtmlWebMockInterstitialDelegate overrides
MOCK_METHOD0(OnProceed, void());
MOCK_METHOD0(OnDontProceed, void());
std::string GetHtmlContents() const override { return ""; }
};
#endif // IOS_WEB_TEST_FAKES_MOCK_INTERSTITIAL_DELEGATE_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/web/test/fakes/mock_interstitial_delegate.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
MockInterstitialDelegate::MockInterstitialDelegate() = default;
MockInterstitialDelegate::~MockInterstitialDelegate() = default;
......@@ -804,6 +804,10 @@ void WebStateImpl::OnNavigationFinished(web::NavigationContext* context) {
void WebStateImpl::ClearTransientContent() {
if (interstitial_) {
// |visible_item| can be null if non-committed entries where discarded.
NavigationItem* visible_item = navigation_manager_->GetVisibleItem();
const SSLStatus* old_status =
visible_item ? &(visible_item->GetSSL()) : nullptr;
// Store the currently displayed interstitial in a local variable and reset
// |interstitial_| early. This is to prevent an infinite loop, as
// |DontProceed()| internally calls |ClearTransientContent()|.
......@@ -812,6 +816,12 @@ void WebStateImpl::ClearTransientContent() {
interstitial->DontProceed();
// Don't access |interstitial| after calling |DontProceed()|, as it triggers
// deletion.
const web::NavigationItem* new_item = navigation_manager_->GetVisibleItem();
if (!new_item || !old_status || !new_item->GetSSL().Equals(*old_status)) {
// Visible SSL state has actually changed after interstitial dismissal.
DidChangeVisibleSecurityState();
}
}
[web_controller_ clearTransientContentView];
}
......
......@@ -16,6 +16,7 @@
#import "base/strings/sys_string_conversions.h"
#import "base/test/ios/wait_util.h"
#include "base/test/scoped_feature_list.h"
#import "ios/web/interstitials/html_web_interstitial_impl.h"
#import "ios/web/navigation/wk_navigation_util.h"
#import "ios/web/public/crw_navigation_item_storage.h"
#import "ios/web/public/crw_session_storage.h"
......@@ -33,6 +34,7 @@
#import "ios/web/public/web_state/web_state_delegate.h"
#include "ios/web/public/web_state/web_state_observer.h"
#import "ios/web/public/web_state/web_state_policy_decider.h"
#import "ios/web/test/fakes/mock_interstitial_delegate.h"
#include "ios/web/web_state/global_web_state_event_tracker.h"
#import "ios/web/web_state/navigation_context_impl.h"
#import "ios/web/web_state/ui/crw_web_controller.h"
......@@ -195,6 +197,26 @@ class WebStateImplTest : public web::WebTest {
web_state_ = std::make_unique<web::WebStateImpl>(params);
}
// Adds PendingNavigationItem and commits it.
void AddCommittedNavigationItem() {
web_state_->GetNavigationManagerImpl().InitializeSession();
web_state_->GetNavigationManagerImpl().AddPendingItem(
GURL::EmptyGURL(), web::Referrer(), ui::PAGE_TRANSITION_LINK,
NavigationInitiationType::RENDERER_INITIATED,
NavigationManager::UserAgentOverrideOption::DESKTOP);
web_state_->GetNavigationManagerImpl().CommitPendingItem();
}
// Creates interstitial raw pointer and calls Show(). The pointer must be
// deleted by dismissing the interstitial.
WebInterstitialImpl* ShowInterstitial() {
auto delegate = std::make_unique<MockInterstitialDelegate>();
WebInterstitialImpl* result =
new HtmlWebInterstitialImpl(web_state_.get(), /*new_navigation=*/true,
GURL::EmptyGURL(), std::move(delegate));
result->Show();
return result;
}
std::unique_ptr<WebStateImpl> web_state_;
};
......@@ -983,4 +1005,87 @@ TEST_F(WebStateImplTest, NoUncommittedRestoreSession) {
EXPECT_TRUE(web_state_->GetTitle().empty());
}
// Tests showing and clearing interstitial when NavigationManager is
// empty.
TEST_F(WebStateImplTest, ShowAndClearInterstitialWithNoCommittedItems) {
web_state_->GetNavigationManagerImpl().InitializeSession();
// Show the interstitial.
ASSERT_FALSE(web_state_->IsShowingWebInterstitial());
ASSERT_FALSE(web_state_->GetWebInterstitial());
WebInterstitialImpl* interstitial = ShowInterstitial();
ASSERT_EQ(interstitial, web_state_->GetWebInterstitial());
ASSERT_TRUE(web_state_->IsShowingWebInterstitial());
// Clear the interstitial.
TestWebStateObserver observer(web_state_.get());
ASSERT_FALSE(observer.did_change_visible_security_state_info());
web_state_->ClearTransientContent();
// Verify that interstitial was removed and DidChangeVisibleSecurityState was
// called.
EXPECT_FALSE(web_state_->IsShowingWebInterstitial());
EXPECT_FALSE(web_state_->GetWebInterstitial());
ASSERT_TRUE(observer.did_change_visible_security_state_info());
EXPECT_EQ(web_state_.get(),
observer.did_change_visible_security_state_info()->web_state);
}
// Tests showing and clearing interstitial when NavigationManager has a
// committed item.
TEST_F(WebStateImplTest, ShowAndClearInterstitialWithCommittedItem) {
// Add SECURITY_STYLE_AUTHENTICATED committed item to navigation manager.
AddCommittedNavigationItem();
web_state_->GetNavigationManagerImpl()
.GetLastCommittedItem()
->GetSSL()
.security_style = SECURITY_STYLE_AUTHENTICATED;
// Show the interstitial.
ASSERT_FALSE(web_state_->IsShowingWebInterstitial());
ASSERT_FALSE(web_state_->GetWebInterstitial());
WebInterstitialImpl* interstitial = ShowInterstitial();
ASSERT_TRUE(web_state_->IsShowingWebInterstitial());
ASSERT_EQ(interstitial, web_state_->GetWebInterstitial());
// Clear the interstitial.
TestWebStateObserver observer(web_state_.get());
ASSERT_FALSE(observer.did_change_visible_security_state_info());
web_state_->ClearTransientContent();
// Verify that interstitial was removed and DidChangeVisibleSecurityState was
// called.
EXPECT_FALSE(web_state_->IsShowingWebInterstitial());
EXPECT_FALSE(web_state_->GetWebInterstitial());
ASSERT_TRUE(observer.did_change_visible_security_state_info());
EXPECT_EQ(web_state_.get(),
observer.did_change_visible_security_state_info()->web_state);
}
// Tests showing and clearing interstitial when visible SSL status does not
// change.
TEST_F(WebStateImplTest, ShowAndClearInterstitialWithoutChangingSslStatus) {
// Add a committed item to navigation manager with default SSL status.
AddCommittedNavigationItem();
// Show the interstitial.
ASSERT_FALSE(web_state_->IsShowingWebInterstitial());
ASSERT_FALSE(web_state_->GetWebInterstitial());
WebInterstitialImpl* interstitial = ShowInterstitial();
ASSERT_TRUE(web_state_->IsShowingWebInterstitial());
ASSERT_EQ(interstitial, web_state_->GetWebInterstitial());
// Clear the interstitial.
TestWebStateObserver observer(web_state_.get());
ASSERT_FALSE(observer.did_change_visible_security_state_info());
web_state_->ClearTransientContent();
// Verify that interstitial was removed.
EXPECT_FALSE(web_state_->IsShowingWebInterstitial());
EXPECT_FALSE(web_state_->GetWebInterstitial());
// DidChangeVisibleSecurityState is not called, because last committed and
// transient items had the same SSL status.
EXPECT_FALSE(observer.did_change_visible_security_state_info());
}
} // namespace web
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment