blob: 4f38cc0a74619344e34a98290cf5e157e9514ea6 [file] [log] [blame]
// Copyright 2019 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/chrome/browser/overlays/overlay_presenter_impl.h"
#import "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
#import "ios/chrome/browser/main/test_browser.h"
#include "ios/chrome/browser/overlays/overlay_request_queue_impl.h"
#include "ios/chrome/browser/overlays/public/overlay_modality.h"
#include "ios/chrome/browser/overlays/public/overlay_presenter_observer.h"
#include "ios/chrome/browser/overlays/public/overlay_request.h"
#include "ios/chrome/browser/overlays/test/fake_overlay_presentation_context.h"
#include "ios/chrome/browser/overlays/test/fake_overlay_request_cancel_handler.h"
#include "ios/chrome/browser/overlays/test/fake_overlay_user_data.h"
#import "ios/chrome/browser/web_state_list/fake_web_state_list_delegate.h"
#import "ios/chrome/browser/web_state_list/web_state_list.h"
#import "ios/chrome/browser/web_state_list/web_state_opener.h"
#import "ios/web/public/test/fakes/fake_web_state.h"
#include "ios/web/public/test/web_task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/platform_test.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
// Mock queue observer.
class MockOverlayPresenterObserver : public OverlayPresenterObserver {
public:
MockOverlayPresenterObserver() {}
~MockOverlayPresenterObserver() {}
MOCK_METHOD3(WillShowOverlay, void(OverlayPresenter*, OverlayRequest*, bool));
MOCK_METHOD2(DidHideOverlay, void(OverlayPresenter*, OverlayRequest*));
// OverlayPresenter's ObserverList checks that it is empty upon deallocation,
// so a custom verification implemetation must be created.
void OverlayPresenterDestroyed(OverlayPresenter* presenter) override {
presenter_destroyed_ = true;
presenter->RemoveObserver(this);
}
bool presenter_destroyed() const { return presenter_destroyed_; }
private:
bool presenter_destroyed_ = false;
};
} // namespace
// Test fixture for OverlayPresenterImpl.
class OverlayPresenterImplTest : public PlatformTest {
public:
OverlayPresenterImplTest() : web_state_list_(&web_state_list_delegate_) {
TestChromeBrowserState::Builder browser_state_builder;
chrome_browser_state_ = browser_state_builder.Build();
browser_ = std::make_unique<TestBrowser>(chrome_browser_state_.get(),
&web_state_list_);
OverlayPresenterImpl::Container::CreateForUserData(browser_.get(),
browser_.get());
presenter().AddObserver(&observer_);
}
~OverlayPresenterImplTest() override {
if (browser_)
presenter().RemoveObserver(&observer_);
}
WebStateList& web_state_list() { return web_state_list_; }
web::WebState* active_web_state() {
return web_state_list_.GetActiveWebState();
}
OverlayPresenterImpl& presenter() {
return *OverlayPresenterImpl::Container::FromUserData(browser_.get())
->PresenterForModality(OverlayModality::kWebContentArea);
}
FakeOverlayPresentationContext& presentation_context() {
return presentation_context_;
}
MockOverlayPresenterObserver& observer() { return observer_; }
OverlayRequestQueueImpl* GetQueueForWebState(web::WebState* web_state) {
if (!web_state)
return nullptr;
OverlayRequestQueueImpl::Container::CreateForWebState(web_state);
return OverlayRequestQueueImpl::Container::FromWebState(web_state)
->QueueForModality(OverlayModality::kWebContentArea);
}
OverlayRequest* InsertRequest(web::WebState* web_state,
size_t index,
bool expect_presentation = true) {
OverlayRequestQueueImpl* queue = GetQueueForWebState(web_state);
if (!queue)
return nullptr;
std::unique_ptr<OverlayRequest> inserted_request =
OverlayRequest::CreateWithConfig<FakeOverlayUserData>();
OverlayRequest* request = inserted_request.get();
if (expect_presentation)
EXPECT_CALL(observer(), WillShowOverlay(&presenter(), request,
/*initial_presentation=*/true));
GetQueueForWebState(web_state)->InsertRequest(index,
std::move(inserted_request));
return request;
}
OverlayRequest* AddRequest(web::WebState* web_state,
bool expect_presentation = true) {
return InsertRequest(web_state, GetQueueForWebState(web_state)->size(),
expect_presentation);
}
void DeleteBrowser() { browser_ = nullptr; }
private:
web::WebTaskEnvironment task_environment_;
FakeWebStateListDelegate web_state_list_delegate_;
WebStateList web_state_list_;
FakeOverlayPresentationContext presentation_context_;
MockOverlayPresenterObserver observer_;
std::unique_ptr<TestChromeBrowserState> chrome_browser_state_;
std::unique_ptr<Browser> browser_;
};
// Tests that setting the presentation context will present overlays requested
// before the delegate is provided.
TEST_F(OverlayPresenterImplTest, PresentAfterSettingPresentationContext) {
// Add a WebState to the list and add a request to that WebState's queue.
web_state_list().InsertWebState(
/*index=*/0, std::make_unique<web::FakeWebState>(),
WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
OverlayRequest* request = AddRequest(active_web_state());
ASSERT_EQ(FakeOverlayPresentationContext::PresentationState::kNotPresented,
presentation_context().GetPresentationState(request));
// Set the UI delegate and verify that the request has been presented.
presenter().SetPresentationContext(&presentation_context());
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
presentation_context().GetPresentationState(request));
EXPECT_TRUE(presenter().IsShowingOverlayUI());
}
// Tests that requested overlays are presented when added to the active queue
// after the presentation context has been provided.
TEST_F(OverlayPresenterImplTest, PresentAfterRequestAddedToActiveQueue) {
// Add a WebState to the list and add a request to that WebState's queue.
presenter().SetPresentationContext(&presentation_context());
web_state_list().InsertWebState(
/*index=*/0, std::make_unique<web::FakeWebState>(),
WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
OverlayRequest* request = AddRequest(active_web_state());
// Verify that the requested overlay has been presented.
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
presentation_context().GetPresentationState(request));
EXPECT_TRUE(presenter().IsShowingOverlayUI());
}
// Tests that the requested overlay is presented when inserted to the front of
// the active queue while already presenting overlay UI for its front request.
TEST_F(OverlayPresenterImplTest,
PresentAfterRequestInsertedToFrontOfActiveQueue) {
// Add a WebState to the list and add a request to that WebState's queue.
presenter().SetPresentationContext(&presentation_context());
web_state_list().InsertWebState(
/*index=*/0, std::make_unique<web::FakeWebState>(),
WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
OverlayRequest* request = AddRequest(active_web_state());
// Verify that the requested overlay has been presented.
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
presentation_context().GetPresentationState(request));
EXPECT_TRUE(presenter().IsShowingOverlayUI());
// Insert a request in front of the |request| and verify that the inserted
// request's UI is presented while |request|'s UI is hidden.
EXPECT_CALL(observer(), DidHideOverlay(&presenter(), request));
OverlayRequest* inserted_request =
InsertRequest(active_web_state(), /*index=*/0);
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
presentation_context().GetPresentationState(inserted_request));
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kHidden,
presentation_context().GetPresentationState(request));
EXPECT_TRUE(presenter().IsShowingOverlayUI());
// Dismiss |inserted_request|'s UI check that the |request|'s UI is presented
// again.
EXPECT_CALL(observer(), DidHideOverlay(&presenter(), inserted_request));
EXPECT_CALL(observer(), WillShowOverlay(&presenter(), request,
/*initial_presentation=*/false));
presentation_context().SimulateDismissalForRequest(
inserted_request, OverlayDismissalReason::kUserInteraction);
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kUserDismissed,
presentation_context().GetPresentationState(inserted_request));
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
presentation_context().GetPresentationState(request));
EXPECT_TRUE(presenter().IsShowingOverlayUI());
}
// Tests that requested overlays are presented when the presentation context is
// activated.
TEST_F(OverlayPresenterImplTest, PresentAfterContextActivation) {
// Add a WebState to the list and add a request to that WebState's queue.
presentation_context().SetPresentationCapabilities(
OverlayPresentationContext::UIPresentationCapabilities::kNone);
presenter().SetPresentationContext(&presentation_context());
web_state_list().InsertWebState(
/*index=*/0, std::make_unique<web::FakeWebState>(),
WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
OverlayRequest* request = AddRequest(active_web_state());
ASSERT_EQ(FakeOverlayPresentationContext::PresentationState::kNotPresented,
presentation_context().GetPresentationState(request));
// Activate the presentation context and verify that the UI is presented.
presentation_context().SetPresentationCapabilities(
OverlayPresentationContext::UIPresentationCapabilities::kPresented);
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
presentation_context().GetPresentationState(request));
EXPECT_TRUE(presenter().IsShowingOverlayUI());
}
// Tests that presented overlay UI is hidden when the presentation context is
// deactivated.
TEST_F(OverlayPresenterImplTest, HideAfterContextDeactivation) {
// Add a WebState to the list and add a request to that WebState's queue.
presenter().SetPresentationContext(&presentation_context());
web_state_list().InsertWebState(
/*index=*/0, std::make_unique<web::FakeWebState>(),
WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
OverlayRequest* request = AddRequest(active_web_state());
ASSERT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
presentation_context().GetPresentationState(request));
ASSERT_TRUE(presenter().IsShowingOverlayUI());
// Deactivate the presentation context and verify that the UI is hidden.
presentation_context().SetPresentationCapabilities(
OverlayPresentationContext::UIPresentationCapabilities::kNone);
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kHidden,
presentation_context().GetPresentationState(request));
EXPECT_FALSE(presenter().IsShowingOverlayUI());
}
// Tests resetting the presentation context. The UI should be cancelled in the
// previous context and presented in the new context.
TEST_F(OverlayPresenterImplTest, ResetPresentationContext) {
// Add a WebState to the list and add a request to that WebState's queue.
presenter().SetPresentationContext(&presentation_context());
web_state_list().InsertWebState(
/*index=*/0, std::make_unique<web::FakeWebState>(),
WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
web::WebState* web_state = active_web_state();
OverlayRequest* request = AddRequest(web_state);
OverlayRequestQueueImpl* queue = GetQueueForWebState(web_state);
ASSERT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
presentation_context().GetPresentationState(request));
ASSERT_TRUE(presenter().IsShowingOverlayUI());
// Reset the presentation context and verify that the overlay UI is cancelled
// in the previous context and presented in the new context.
FakeOverlayPresentationContext new_presentation_context;
EXPECT_CALL(observer(), DidHideOverlay(&presenter(), request));
EXPECT_CALL(observer(), WillShowOverlay(&presenter(), request,
/*initial_presentation=*/true));
presenter().SetPresentationContext(&new_presentation_context);
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kCancelled,
presentation_context().GetPresentationState(request));
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
new_presentation_context.GetPresentationState(request));
EXPECT_EQ(request, queue->front_request());
EXPECT_TRUE(presenter().IsShowingOverlayUI());
// Reset the UI delegate to nullptr and verify that the overlay UI is
// cancelled in |new_presentation_context|'s context.
EXPECT_CALL(observer(), DidHideOverlay(&presenter(), request));
presenter().SetPresentationContext(nullptr);
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kCancelled,
new_presentation_context.GetPresentationState(request));
EXPECT_EQ(request, queue->front_request());
EXPECT_FALSE(presenter().IsShowingOverlayUI());
}
// Tests changing the active WebState while no overlays are presented over the
// current active WebState.
TEST_F(OverlayPresenterImplTest, ChangeActiveWebStateWhileNotPresenting) {
// Add a WebState to the list and activate it.
presenter().SetPresentationContext(&presentation_context());
web_state_list().InsertWebState(
/*index=*/0, std::make_unique<web::FakeWebState>(),
WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
// Create a new WebState with a queued request and add it as the new active
// WebState.
auto passed_web_state = std::make_unique<web::FakeWebState>();
web::WebState* second_web_state = passed_web_state.get();
OverlayRequest* request = AddRequest(second_web_state);
web_state_list().InsertWebState(/*index=*/1, std::move(passed_web_state),
WebStateList::InsertionFlags::INSERT_ACTIVATE,
WebStateOpener());
// Verify that the new active WebState's overlay is being presented.
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
presentation_context().GetPresentationState(request));
EXPECT_TRUE(presenter().IsShowingOverlayUI());
}
// Tests changing the active WebState while is it presenting an overlay.
TEST_F(OverlayPresenterImplTest, ChangeActiveWebStateWhilePresenting) {
// Add a WebState to the list and add a request to that WebState's queue.
presenter().SetPresentationContext(&presentation_context());
web_state_list().InsertWebState(
/*index=*/0, std::make_unique<web::FakeWebState>(),
WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
web::WebState* first_web_state = active_web_state();
OverlayRequest* first_request = AddRequest(first_web_state);
ASSERT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
presentation_context().GetPresentationState(first_request));
ASSERT_TRUE(presenter().IsShowingOverlayUI());
// Create a new WebState with a queued request and add it as the new active
// WebState.
auto passed_web_state = std::make_unique<web::FakeWebState>();
web::WebState* second_web_state = passed_web_state.get();
OverlayRequest* second_request = AddRequest(second_web_state);
EXPECT_CALL(observer(), DidHideOverlay(&presenter(), first_request));
web_state_list().InsertWebState(/*index=*/1, std::move(passed_web_state),
WebStateList::InsertionFlags::INSERT_ACTIVATE,
WebStateOpener());
// Verify that the previously shown overlay is hidden and that the overlay for
// the new active WebState is presented.
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kHidden,
presentation_context().GetPresentationState(first_request));
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
presentation_context().GetPresentationState(second_request));
EXPECT_TRUE(presenter().IsShowingOverlayUI());
// Reactivate the first WebState and verify that its overlay is presented
// while the second WebState's overlay is hidden.
EXPECT_CALL(observer(), DidHideOverlay(&presenter(), second_request));
EXPECT_CALL(observer(), WillShowOverlay(&presenter(), first_request,
/*initial_presentation=*/false));
web_state_list().ActivateWebStateAt(0);
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
presentation_context().GetPresentationState(first_request));
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kHidden,
presentation_context().GetPresentationState(second_request));
EXPECT_TRUE(presenter().IsShowingOverlayUI());
}
// Tests replacing the active WebState while it is presenting an overlay.
TEST_F(OverlayPresenterImplTest, ReplaceActiveWebState) {
// Add a WebState to the list and add a request to that WebState's queue.
presenter().SetPresentationContext(&presentation_context());
web_state_list().InsertWebState(
/*index=*/0, std::make_unique<web::FakeWebState>(),
WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
web::WebState* first_web_state = active_web_state();
OverlayRequest* first_request = AddRequest(first_web_state);
ASSERT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
presentation_context().GetPresentationState(first_request));
ASSERT_TRUE(presenter().IsShowingOverlayUI());
// Replace |first_web_state| with a new active WebState with a queued request.
auto passed_web_state = std::make_unique<web::FakeWebState>();
web::WebState* replacement_web_state = passed_web_state.get();
OverlayRequest* replacement_request = AddRequest(replacement_web_state);
EXPECT_CALL(observer(), DidHideOverlay(&presenter(), first_request));
web_state_list().ReplaceWebStateAt(/*index=*/0, std::move(passed_web_state));
// Verify that the previously shown overlay is canceled and that the overlay
// for the replacement WebState is presented.
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kCancelled,
presentation_context().GetPresentationState(first_request));
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
presentation_context().GetPresentationState(replacement_request));
EXPECT_TRUE(presenter().IsShowingOverlayUI());
}
// Tests removing the active WebState while it is presenting an overlay.
TEST_F(OverlayPresenterImplTest, RemoveActiveWebState) {
// Add a WebState to the list and add a request to that WebState's queue.
presenter().SetPresentationContext(&presentation_context());
web_state_list().InsertWebState(
/*index=*/0, std::make_unique<web::FakeWebState>(),
WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
web::WebState* web_state = active_web_state();
OverlayRequest* request = AddRequest(web_state);
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
presentation_context().GetPresentationState(request));
EXPECT_TRUE(presenter().IsShowingOverlayUI());
// Remove the WebState and verify that its overlay was cancelled.
EXPECT_CALL(observer(), DidHideOverlay(&presenter(), request));
web_state_list().CloseWebStateAt(/*index=*/0, /* close_flags= */ 0);
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kCancelled,
presentation_context().GetPresentationState(request));
}
// Tests detaching the active WebState while it is presenting an overlay and
// removing the presenter as the queue's delegate.
TEST_F(OverlayPresenterImplTest, DetachWebStateRemoveDelegate) {
// Add a WebState to the list and add a request to that WebState's queue.
presenter().SetPresentationContext(&presentation_context());
web_state_list().InsertWebState(
/*index=*/0, std::make_unique<web::FakeWebState>(),
WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
web::WebState* web_state = active_web_state();
OverlayRequest* request = AddRequest(web_state);
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
presentation_context().GetPresentationState(request));
EXPECT_TRUE(presenter().IsShowingOverlayUI());
presentation_context().SetDismissalCallbacksEnabled(false);
// Remove the WebState and verify that its overlay was cancelled.
std::unique_ptr<web::WebState> detached_web_state =
web_state_list().DetachWebStateAt(/*index=*/0);
EXPECT_CALL(observer(), DidHideOverlay(&presenter(), request));
GetQueueForWebState(detached_web_state.get())->SetDelegate(nullptr);
presentation_context().SetDismissalCallbacksEnabled(true);
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kCancelled,
presentation_context().GetPresentationState(request));
}
// Tests detaching the active WebState while it is presenting an overlay and
// cancelling all requests before the dismissal callback for the presenting
// overlay executes.
TEST_F(OverlayPresenterImplTest,
DetachWebStateCancelRequestBeforeDismissalCallback) {
// Add a WebState to the list and add a request to that WebState's queue.
presenter().SetPresentationContext(&presentation_context());
web_state_list().InsertWebState(
/*index=*/0, std::make_unique<web::FakeWebState>(),
WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
web::WebState* web_state = active_web_state();
OverlayRequest* request = AddRequest(web_state);
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
presentation_context().GetPresentationState(request));
EXPECT_TRUE(presenter().IsShowingOverlayUI());
presentation_context().SetDismissalCallbacksEnabled(false);
// Remove the WebState and verify that its overlay was cancelled.
std::unique_ptr<web::WebState> detached_web_state =
web_state_list().DetachWebStateAt(/*index=*/0);
GetQueueForWebState(detached_web_state.get())->CancelAllRequests();
EXPECT_CALL(observer(), DidHideOverlay(&presenter(), request));
presentation_context().SetDismissalCallbacksEnabled(true);
}
// Tests detaching the active WebState while it is presenting an overlay and
// executing the dismissal callback after detachment.
TEST_F(OverlayPresenterImplTest,
DetachWebStateDismissalCallbackCallsDidHideOverlay) {
// Add a WebState to the list and add a request to that WebState's queue.
presenter().SetPresentationContext(&presentation_context());
web_state_list().InsertWebState(
/*index=*/0, std::make_unique<web::FakeWebState>(),
WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
web::WebState* web_state = active_web_state();
OverlayRequest* request = AddRequest(web_state);
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
presentation_context().GetPresentationState(request));
EXPECT_TRUE(presenter().IsShowingOverlayUI());
presentation_context().SetDismissalCallbacksEnabled(false);
// Remove the WebState and verify that its overlay was cancelled.
std::unique_ptr<web::WebState> detached_web_state =
web_state_list().DetachWebStateAt(/*index=*/0);
EXPECT_CALL(observer(), DidHideOverlay(&presenter(), request));
presentation_context().SetDismissalCallbacksEnabled(true);
}
// Tests dismissing an overlay for user interaction.
TEST_F(OverlayPresenterImplTest, DismissForUserInteraction) {
// Add a WebState to the list and add two request to that WebState's queue.
presenter().SetPresentationContext(&presentation_context());
web_state_list().InsertWebState(
/*index=*/0, std::make_unique<web::FakeWebState>(),
WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
web::WebState* web_state = active_web_state();
OverlayRequestQueueImpl* queue = GetQueueForWebState(web_state);
OverlayRequest* first_request = AddRequest(web_state);
OverlayRequest* second_request = AddRequest(web_state);
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
presentation_context().GetPresentationState(first_request));
EXPECT_TRUE(presenter().IsShowingOverlayUI());
EXPECT_EQ(first_request, queue->front_request());
EXPECT_EQ(2U, queue->size());
// Dismiss the overlay and check that the second request's overlay is
// presented.
EXPECT_CALL(observer(), DidHideOverlay(&presenter(), first_request));
presentation_context().SimulateDismissalForRequest(
first_request, OverlayDismissalReason::kUserInteraction);
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kUserDismissed,
presentation_context().GetPresentationState(first_request));
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
presentation_context().GetPresentationState(second_request));
EXPECT_EQ(second_request, queue->front_request());
EXPECT_EQ(1U, queue->size());
EXPECT_TRUE(presenter().IsShowingOverlayUI());
}
// Tests cancelling the requests.
TEST_F(OverlayPresenterImplTest, CancelRequests) {
// Add a WebState to the list and a request to that WebState's queue.
presenter().SetPresentationContext(&presentation_context());
web_state_list().InsertWebState(0, std::make_unique<web::FakeWebState>(),
WebStateList::InsertionFlags::INSERT_ACTIVATE,
WebStateOpener());
OverlayRequestQueueImpl* queue = GetQueueForWebState(active_web_state());
OverlayRequest* active_request = AddRequest(active_web_state());
OverlayRequest* queued_request =
AddRequest(active_web_state(), /*expect_presentation=*/false);
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
presentation_context().GetPresentationState(active_request));
ASSERT_TRUE(presenter().IsShowingOverlayUI());
// Cancel the queue's requests and verify that the UI is also cancelled.
EXPECT_CALL(observer(), DidHideOverlay(&presenter(), active_request));
queue->CancelAllRequests();
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kCancelled,
presentation_context().GetPresentationState(active_request));
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kCancelled,
presentation_context().GetPresentationState(queued_request));
}
// Tests that the presented UI is correctly hidden if the presentation
// capabilities change to kNone during the dismissal of overlay UI whose request
// is owned by an inactive WebState.
TEST_F(OverlayPresenterImplTest,
ChangePresentationCapabilitiesDuringDismissalForInactiveWebState) {
// Insert an activated WebState to the list and add a request.
presenter().SetPresentationContext(&presentation_context());
web_state_list().InsertWebState(0, std::make_unique<web::FakeWebState>(),
WebStateList::InsertionFlags::INSERT_ACTIVATE,
WebStateOpener());
OverlayRequest* request = AddRequest(active_web_state());
// Disable dismissal callbacks in the fake context and activate a new
// WebState.
presentation_context().SetDismissalCallbacksEnabled(false);
web_state_list().InsertWebState(1, std::make_unique<web::FakeWebState>(),
WebStateList::InsertionFlags::INSERT_ACTIVATE,
WebStateOpener());
// Reset the presentation capabilities to kNone. Since the context can no
// longer support presenting |request|, it will be hidden.
presentation_context().SetPresentationCapabilities(
OverlayPresentationContext::UIPresentationCapabilities::kNone);
// Re-enable dismissal callbacks to dimulate the dismissal finishing after the
// presentation capability reset.
EXPECT_CALL(observer(), DidHideOverlay(&presenter(), request));
presentation_context().SetDismissalCallbacksEnabled(true);
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kHidden,
presentation_context().GetPresentationState(request));
}
// Tests that the presented UI is correctly hidden if the presentation
// capabilities change to kNone during the dismissal of overlay UI whose request
// that was cancelled.
TEST_F(OverlayPresenterImplTest,
ChangePresentationCapabilitiesDuringDismissalForCancelledRequest) {
// Insert an activated WebState to the list.
presenter().SetPresentationContext(&presentation_context());
web_state_list().InsertWebState(0, std::make_unique<web::FakeWebState>(),
WebStateList::InsertionFlags::INSERT_ACTIVATE,
WebStateOpener());
OverlayRequestQueueImpl* queue = GetQueueForWebState(active_web_state());
// Add a request with a fake cancel handler.
std::unique_ptr<OverlayRequest> inserted_request =
OverlayRequest::CreateWithConfig<FakeOverlayUserData>();
OverlayRequest* request = inserted_request.get();
std::unique_ptr<FakeOverlayRequestCancelHandler> inserted_cancel_handler =
std::make_unique<FakeOverlayRequestCancelHandler>(request, queue);
FakeOverlayRequestCancelHandler* cancel_handler =
inserted_cancel_handler.get();
EXPECT_CALL(observer(), WillShowOverlay(&presenter(), request,
/*initial_presentation=*/true));
queue->AddRequest(std::move(inserted_request));
// Disable dismissal callbacks in the fake context and cancel the request.
presentation_context().SetDismissalCallbacksEnabled(false);
cancel_handler->TriggerCancellation();
EXPECT_FALSE(queue->front_request());
// Reset the presentation capabilities to kNone. Since the context can no
// longer support presenting |request|, it will be hidden.
presentation_context().SetPresentationCapabilities(
OverlayPresentationContext::UIPresentationCapabilities::kNone);
// Re-enable dismissal callbacks to dimulate the dismissal finishing after the
// presentation capability reset.
EXPECT_CALL(observer(), DidHideOverlay(&presenter(), request));
presentation_context().SetDismissalCallbacksEnabled(true);
EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kHidden,
presentation_context().GetPresentationState(request));
}
// Tests that deleting the presenter
TEST_F(OverlayPresenterImplTest, PresenterWasDestroyed) {
DeleteBrowser();
EXPECT_TRUE(observer().presenter_destroyed());
}