Commit c3540372 authored by Kurt Horimoto's avatar Kurt Horimoto Committed by Commit Bot

[iOS] Add UI support for infobar banner overlays.

InfobarBannerOverlayCoordinator is a coordinator that will be shared
amongst all infobar banners.  InfobarBannerOverlayMediator is a
superclass that implements behavior shared amongst all InfobarTypes,
such as setting the consumer, dispatching responses for user
interaction events, and setting up the overlay completion response.

This CL also introduces the response infos necessary for banners:
- InfobarBannerConfirmButtonTapped is dispatched to notify the model
  layer that the main button on a confirm infobar banner was tapped.
- InfobarBannerModalButtonTapped is dispatched to notify the model
  layer that the modal button was tapped.
- InfobarBannerCompletion is used a completion response and stores
  whether the dismissal was user-initiated.

Bug: 1030357
Change-Id: Icb19d2a7322fd6c765c19812c02d46dcba07b97c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1986449
Commit-Queue: Kurt Horimoto <kkhorimoto@chromium.org>
Reviewed-by: default avatarSergio Collazos <sczs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#728584}
parent 6e9a13fa
......@@ -4,6 +4,8 @@
source_set("infobar_banner") {
sources = [
"infobar_banner_overlay_responses.cc",
"infobar_banner_overlay_responses.h",
"save_password_infobar_banner_overlay.h",
"save_password_infobar_banner_overlay.mm",
]
......
// 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.
#include "ios/chrome/browser/overlays/public/infobar_banner/infobar_banner_overlay_responses.h"
#pragma mark - InfobarBannerMainActionResponse
OVERLAY_USER_DATA_SETUP_IMPL(InfobarBannerMainActionResponse);
InfobarBannerMainActionResponse::InfobarBannerMainActionResponse() = default;
InfobarBannerMainActionResponse::~InfobarBannerMainActionResponse() = default;
#pragma mark - InfobarBannerShowModalResponse
OVERLAY_USER_DATA_SETUP_IMPL(InfobarBannerShowModalResponse);
InfobarBannerShowModalResponse::InfobarBannerShowModalResponse() = default;
InfobarBannerShowModalResponse::~InfobarBannerShowModalResponse() = default;
#pragma mark - InfobarBannerCompletionResponse
OVERLAY_USER_DATA_SETUP_IMPL(InfobarBannerCompletionResponse);
InfobarBannerCompletionResponse::InfobarBannerCompletionResponse(
bool user_initiated)
: user_initiated_(user_initiated) {}
InfobarBannerCompletionResponse::~InfobarBannerCompletionResponse() = default;
// 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.
#ifndef IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_INFOBAR_BANNER_OVERLAY_RESPONSES_H_
#define IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_INFOBAR_BANNER_OVERLAY_RESPONSES_H_
#include "ios/chrome/browser/overlays/public/overlay_response_info.h"
// Response info used to create dispatched OverlayResponses that trigger the
// infobar's main action.
class InfobarBannerMainActionResponse
: public OverlayResponseInfo<InfobarBannerMainActionResponse> {
public:
~InfobarBannerMainActionResponse() override;
private:
OVERLAY_USER_DATA_SETUP(InfobarBannerMainActionResponse);
InfobarBannerMainActionResponse();
};
// Response info used to create dispatched OverlayResponses that trigger the
// presentation of the infobar's modal.
class InfobarBannerShowModalResponse
: public OverlayResponseInfo<InfobarBannerShowModalResponse> {
public:
~InfobarBannerShowModalResponse() override;
private:
OVERLAY_USER_DATA_SETUP(InfobarBannerShowModalResponse);
InfobarBannerShowModalResponse();
};
// Response info used to create completion OverlayResponses for an infobar
// banner OverlayRequest. Executed when the banner is dismissed by the user or
// the request is cancelled.
class InfobarBannerCompletionResponse
: public OverlayResponseInfo<InfobarBannerCompletionResponse> {
public:
~InfobarBannerCompletionResponse() override;
// Whether the banner dismissal was user-initiated.
bool user_initiated() const { return user_initiated_; }
private:
OVERLAY_USER_DATA_SETUP(InfobarBannerCompletionResponse);
explicit InfobarBannerCompletionResponse(bool user_initiated);
bool user_initiated_ = false;
};
#endif // IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_INFOBAR_BANNER_OVERLAY_RESPONSES_H_
......@@ -5,7 +5,7 @@
#ifndef IOS_CHROME_BROWSER_UI_INFOBARS_BANNERS_INFOBAR_BANNER_CONSUMER_H_
#define IOS_CHROME_BROWSER_UI_INFOBARS_BANNERS_INFOBAR_BANNER_CONSUMER_H_
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@protocol InfobarBannerConsumer <NSObject>
......
......@@ -5,7 +5,7 @@
#ifndef IOS_CHROME_BROWSER_UI_INFOBARS_BANNERS_INFOBAR_BANNER_DELEGATE_H_
#define IOS_CHROME_BROWSER_UI_INFOBARS_BANNERS_INFOBAR_BANNER_DELEGATE_H_
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
// Delegate to handle InfobarBanner actions.
@protocol InfobarBannerDelegate
......
# 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.
source_set("test") {
testonly = true
sources = [
"fake_infobar_banner_consumer.h",
"fake_infobar_banner_consumer.mm",
]
configs += [ "//build/config/compiler:enable_arc" ]
deps = [
"//base",
"//ios/chrome/browser/ui/infobars/banners",
]
}
// 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.
#ifndef IOS_CHROME_BROWSER_UI_INFOBARS_BANNERS_TEST_FAKE_INFOBAR_BANNER_CONSUMER_H_
#define IOS_CHROME_BROWSER_UI_INFOBARS_BANNERS_TEST_FAKE_INFOBAR_BANNER_CONSUMER_H_
#import "ios/chrome/browser/ui/infobars/banners/infobar_banner_consumer.h"
// Fake InfobarBannerConsumer used in tests.
@interface FakeInfobarBannerConsumer : NSObject <InfobarBannerConsumer>
// Redefine InfobarBannerConsumer properties as readwrite.
@property(nonatomic, copy) NSString* bannerAccessibilityLabel;
@property(nonatomic, copy) NSString* buttonText;
@property(nonatomic, strong) UIImage* iconImage;
@property(nonatomic, assign) BOOL presentsModal;
@property(nonatomic, copy) NSString* titleText;
@property(nonatomic, copy) NSString* subtitleText;
@end
#endif // IOS_CHROME_BROWSER_UI_INFOBARS_BANNERS_TEST_FAKE_INFOBAR_BANNER_CONSUMER_H_
// 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/ui/infobars/banners/test/fake_infobar_banner_consumer.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@implementation FakeInfobarBannerConsumer
@end
......@@ -14,3 +14,52 @@ source_set("infobar_banner") {
deps = []
}
source_set("common") {
sources = [
"infobar_banner_overlay_coordinator.h",
"infobar_banner_overlay_coordinator.mm",
"infobar_banner_overlay_mediator+consumer_support.h",
"infobar_banner_overlay_mediator.h",
"infobar_banner_overlay_mediator.mm",
]
configs += [ "//build/config/compiler:enable_arc" ]
deps = [
"//base",
"//components/infobars/core",
"//ios/chrome/browser/overlays",
"//ios/chrome/browser/overlays/public/common/infobars",
"//ios/chrome/browser/overlays/public/infobar_banner",
"//ios/chrome/browser/ui/infobars/banners",
"//ios/chrome/browser/ui/infobars/banners:public",
"//ios/chrome/browser/ui/overlays:coordinators",
]
}
source_set("unit_tests") {
testonly = true
sources = [
"infobar_banner_overlay_mediator_unittest.mm",
]
configs += [ "//build/config/compiler:enable_arc" ]
deps = [
":common",
"//components/infobars/core",
"//ios/chrome/browser/infobars/test",
"//ios/chrome/browser/overlays",
"//ios/chrome/browser/overlays/public/common/infobars",
"//ios/chrome/browser/overlays/public/infobar_banner",
"//ios/chrome/browser/ui/elements",
"//ios/chrome/browser/ui/infobars/banners",
"//ios/chrome/browser/ui/infobars/banners:public",
"//ios/chrome/browser/ui/infobars/banners/test",
"//ios/chrome/browser/ui/overlays/test",
"//testing/gtest",
"//third_party/ocmock",
"//ui/base",
]
}
// 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.
#ifndef IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_INFOBAR_BANNER_OVERLAY_COORDINATOR_H_
#define IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_INFOBAR_BANNER_OVERLAY_COORDINATOR_H_
#import "ios/chrome/browser/ui/overlays/overlay_request_coordinator.h"
// A coordinator that displays infobar banner UI using OverlayPresenter.
@interface InfobarBannerOverlayCoordinator : OverlayRequestCoordinator
@end
#endif // IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_INFOBAR_BANNER_OVERLAY_COORDINATOR_H_
// 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/ui/overlays/infobar_banner/infobar_banner_overlay_coordinator.h"
#include "base/logging.h"
#include "base/mac/foundation_util.h"
#include "base/no_destructor.h"
#import "ios/chrome/browser/overlays/public/common/infobars/infobar_overlay_request_config.h"
#import "ios/chrome/browser/overlays/public/overlay_request.h"
#import "ios/chrome/browser/overlays/public/overlay_request_support.h"
#import "ios/chrome/browser/overlays/public/overlay_response.h"
#import "ios/chrome/browser/ui/infobars/banners/infobar_banner_accessibility_util.h"
#import "ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.h"
#import "ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator.h"
#import "ios/chrome/browser/ui/overlays/overlay_request_coordinator+subclassing.h"
#import "ios/chrome/browser/ui/overlays/overlay_request_coordinator_delegate.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
// Creates a vector containing the OverlayRequestSupports for each
// OverlayRequestMediator class in |mediator_classes|
const std::vector<const OverlayRequestSupport*> GetSupportsForMediatorClasses(
NSArray<Class>* mediator_classes) {
std::vector<const OverlayRequestSupport*> supports(mediator_classes.count);
for (NSUInteger index = 0; index < mediator_classes.count; ++index) {
supports[index] = [mediator_classes[index] requestSupport];
}
return supports;
}
} // namespace
@interface InfobarBannerOverlayCoordinator ()
// The list of supported mediator classes.
@property(class, nonatomic, readonly) NSArray<Class>* supportedMediatorClasses;
// The banner view being managed by this coordinator.
@property(nonatomic) InfobarBannerViewController* bannerViewController;
@end
@implementation InfobarBannerOverlayCoordinator
#pragma mark - Accessors
+ (NSArray<Class>*)supportedMediatorClasses {
// TODO(crbug.com/1030357): Add more mediator classes here.
return @[];
}
+ (const OverlayRequestSupport*)requestSupport {
static std::unique_ptr<const OverlayRequestSupport> _requestSupport = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_requestSupport = std::make_unique<OverlayRequestSupport>(
GetSupportsForMediatorClasses(self.supportedMediatorClasses));
});
return _requestSupport.get();
}
#pragma mark - OverlayRequestCoordinator
- (void)startAnimated:(BOOL)animated {
if (self.started || !self.request)
return;
// Create the mediator and use it aas the delegate for the banner view.
InfobarOverlayRequestConfig* config =
self.request->GetConfig<InfobarOverlayRequestConfig>();
InfobarBannerOverlayMediator* mediator = [self newMediator];
self.bannerViewController = [[InfobarBannerViewController alloc]
initWithDelegate:mediator
presentsModal:config->has_badge()
type:config->infobar_type()];
mediator.consumer = self.bannerViewController;
self.mediator = mediator;
// Present the banner.
// TODO(crbug.com/1030357): Use custom presentation.
self.bannerViewController.modalPresentationStyle =
UIModalPresentationOverCurrentContext;
self.bannerViewController.modalTransitionStyle =
UIModalTransitionStyleCrossDissolve;
[self.baseViewController presentViewController:self.viewController
animated:animated
completion:^{
[self finishPresentation];
}];
self.started = YES;
}
- (void)stopAnimated:(BOOL)animated {
if (!self.started)
return;
[self.baseViewController dismissViewControllerAnimated:animated
completion:^{
[self finishDismissal];
}];
self.started = NO;
}
- (UIViewController*)viewController {
return self.bannerViewController;
}
#pragma mark - Private
// Called when the presentation of the banner UI is completed.
- (void)finishPresentation {
// Notify the presentation context that the presentation has finished. This
// is necessary to synchronize OverlayPresenter scheduling logic with the UI
// layer.
self.delegate->OverlayUIDidFinishPresentation(self.request);
UpdateBannerAccessibilityForPresentation(self.baseViewController,
self.viewController.view);
}
// Called when the dismissal of the banner UI is finished.
- (void)finishDismissal {
self.bannerViewController = nil;
self.mediator = nil;
// Notify the presentation context that the dismissal has finished. This
// is necessary to synchronize OverlayPresenter scheduling logic with the UI
// layer.
self.delegate->OverlayUIDidFinishDismissal(self.request);
UpdateBannerAccessibilityForDismissal(self.baseViewController);
}
// Creates a mediator instance from the supported mediator class list that
// supports the coordinator's request.
- (InfobarBannerOverlayMediator*)newMediator {
for (Class mediatorClass in [self class].supportedMediatorClasses) {
if (mediatorClass.requestSupport->IsRequestSupported(self.request))
return [[mediatorClass alloc] initWithRequest:self.request];
}
NOTREACHED() << "None of the supported mediator classes support request.";
return nil;
}
@end
// 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.
#ifndef IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_INFOBAR_BANNER_OVERLAY_MEDIATOR_CONSUMER_SUPPORT_H_
#define IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_INFOBAR_BANNER_OVERLAY_MEDIATOR_CONSUMER_SUPPORT_H_
#import "ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator.h"
// Category used by the InfobarBannerOverlayMediator superclass in order to
// configure its consumer.
@interface InfobarBannerOverlayMediator (ConsumerSupport)
// Sets up the banner consumer using the configuration information from the
// mediator's OverlayRequest. Subclasses must implement.
- (void)configureConsumer;
@end
#endif // IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_INFOBAR_BANNER_OVERLAY_MEDIATOR_CONSUMER_SUPPORT_H_
// 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.
#ifndef IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_INFOBAR_BANNER_OVERLAY_MEDIATOR_H_
#define IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_INFOBAR_BANNER_OVERLAY_MEDIATOR_H_
#import "ios/chrome/browser/ui/infobars/banners/infobar_banner_delegate.h"
#import "ios/chrome/browser/ui/overlays/overlay_request_mediator.h"
@protocol InfobarBannerConsumer;
// Mediator superclass for configuring InfobarBannerConsumers.
@interface InfobarBannerOverlayMediator
: OverlayRequestMediator <InfobarBannerDelegate>
// The consumer to be updated by this mediator. Setting to a new value updates
// the new consumer.
@property(nonatomic, weak) id<InfobarBannerConsumer> consumer;
@end
#endif // IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_INFOBAR_BANNER_OVERLAY_MEDIATOR_H_
// 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/ui/overlays/infobar_banner/infobar_banner_overlay_mediator.h"
#import <UIKit/UIKit.h>
#include "base/logging.h"
#import "base/strings/sys_string_conversions.h"
#import "ios/chrome/browser/overlays/public/common/infobars/infobar_banner_overlay_request_config.h"
#import "ios/chrome/browser/overlays/public/common/infobars/infobar_overlay_request_config.h"
#include "ios/chrome/browser/overlays/public/infobar_banner/infobar_banner_overlay_responses.h"
#include "ios/chrome/browser/overlays/public/overlay_callback_manager.h"
#include "ios/chrome/browser/overlays/public/overlay_request.h"
#include "ios/chrome/browser/overlays/public/overlay_response.h"
#import "ios/chrome/browser/ui/infobars/banners/infobar_banner_consumer.h"
#import "ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator+consumer_support.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@interface InfobarBannerOverlayMediator ()
// The banner config from the request.
@property(nonatomic, readonly) InfobarBannerOverlayRequestConfig* config;
@end
@implementation InfobarBannerOverlayMediator
- (instancetype)initWithRequest:(OverlayRequest*)request {
if (self = [super initWithRequest:request]) {
DCHECK(request->GetConfig<InfobarBannerOverlayRequestConfig>());
}
return self;
}
#pragma mark - Accessors
- (void)setConsumer:(id<InfobarBannerConsumer>)consumer {
if (_consumer == consumer)
return;
_consumer = consumer;
if (_consumer)
[self configureConsumer];
}
- (InfobarBannerOverlayRequestConfig*)config {
return self.request
? self.request->GetConfig<InfobarBannerOverlayRequestConfig>()
: nullptr;
}
#pragma mark - InfobarBannerDelegate
- (void)bannerInfobarButtonWasPressed:(UIButton*)sender {
// Notify the model layer to perform the infobar's main action before
// dismissing the banner.
[self dispatchResponseAndStopOverlay:OverlayResponse::CreateWithInfo<
InfobarBannerMainActionResponse>()];
}
- (void)dismissInfobarBannerForUserInteraction:(BOOL)userInitiated {
if (self.request) {
// Add a completion response notifying the requesting code of whether the
// dismissal was user-initiated. Provided to the request's completion
// callbacks that are executed when the UI is finished being dismissed.
self.request->GetCallbackManager()->SetCompletionResponse(
OverlayResponse::CreateWithInfo<InfobarBannerCompletionResponse>(
userInitiated));
}
[self.delegate stopOverlayForMediator:self];
}
- (void)presentInfobarModalFromBanner {
// Notify the model layer to show the infobar modal before dismissing the
// banner.
[self dispatchResponseAndStopOverlay:OverlayResponse::CreateWithInfo<
InfobarBannerShowModalResponse>()];
}
- (void)infobarBannerWasDismissed {
// Only needed in legacy implementation. Dismissal completion cleanup occurs
// in InfobarBannerOverlayCoordinator.
}
#pragma mark - Private
// Dispatches |response| through the OverlayRequest, then stops the overlay UI.
- (void)dispatchResponseAndStopOverlay:
(std::unique_ptr<OverlayResponse>)response {
if (self.request)
self.request->GetCallbackManager()->DispatchResponse(std::move(response));
[self.delegate stopOverlayForMediator:self];
}
@end
@implementation InfobarBannerOverlayMediator (ConsumerSupport)
- (void)configureConsumer {
// TODO(crbug.com/1030357): Add NOTREACHED() here to enforce that subclasses
// implement.
InfobarBannerOverlayRequestConfig* config = self.config;
if (!config)
return;
[self.consumer
setBannerAccessibilityLabel:config->banner_accessibility_label()];
[self.consumer setButtonText:config->button_text()];
[self.consumer setIconImage:[UIImage imageNamed:config->icon_image_name()]];
[self.consumer setPresentsModal:config->presents_modal()];
[self.consumer setTitleText:config->title_text()];
[self.consumer setSubtitleText:config->subtitle_text()];
}
@end
// 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/ui/overlays/infobar_banner/infobar_banner_overlay_mediator.h"
#import "base/bind.h"
#include "base/strings/sys_string_conversions.h"
#import "ios/chrome/browser/overlays/public/common/infobars/infobar_banner_overlay_request_config.h"
#include "ios/chrome/browser/overlays/public/infobar_banner/infobar_banner_overlay_responses.h"
#include "ios/chrome/browser/overlays/public/overlay_callback_manager.h"
#include "ios/chrome/browser/overlays/public/overlay_dispatch_callback.h"
#include "ios/chrome/browser/overlays/public/overlay_request.h"
#include "ios/chrome/browser/overlays/public/overlay_response.h"
#import "ios/chrome/browser/ui/infobars/banners/test/fake_infobar_banner_consumer.h"
#import "testing/gtest_mac.h"
#include "testing/platform_test.h"
#import "third_party/ocmock/OCMock/OCMock.h"
#import "third_party/ocmock/gtest_support.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
NSString* const kBannerAccessibilityLabel = @"a11y label";
NSString* const kButtonText = @"button text";
NSString* const kIconImageName = @"infobar_translate_icon";
const bool kPresentsModal(false);
NSString* const kTitleText = @"title text";
NSString* const kSubtitleText = @"subtitle text";
}
// Test fixture for InfobarBannerOverlayMediator.
class InfobarBannerOverlayMediatorTest : public PlatformTest {
public:
InfobarBannerOverlayMediatorTest()
: request_(
OverlayRequest::CreateWithConfig<InfobarBannerOverlayRequestConfig>(
kBannerAccessibilityLabel,
kButtonText,
kIconImageName,
kPresentsModal,
kTitleText,
kSubtitleText)),
delegate_(
OCMStrictProtocolMock(@protocol(OverlayRequestMediatorDelegate))),
mediator_([[InfobarBannerOverlayMediator alloc]
initWithRequest:request_.get()]) {
mediator_.delegate = delegate_;
}
~InfobarBannerOverlayMediatorTest() override {
EXPECT_OCMOCK_VERIFY(delegate_);
}
protected:
std::unique_ptr<OverlayRequest> request_;
id<OverlayRequestMediatorDelegate> delegate_ = nil;
InfobarBannerOverlayMediator* mediator_ = nil;
};
// Tests that an InfobarBannerOverlayMediator correctly sets up its consumer.
TEST_F(InfobarBannerOverlayMediatorTest, SetUpConsumer) {
FakeInfobarBannerConsumer* consumer =
[[FakeInfobarBannerConsumer alloc] init];
mediator_.consumer = consumer;
EXPECT_NSEQ(kBannerAccessibilityLabel, consumer.bannerAccessibilityLabel);
EXPECT_NSEQ(kButtonText, consumer.buttonText);
EXPECT_NSEQ([UIImage imageNamed:kIconImageName], consumer.iconImage);
EXPECT_EQ(kPresentsModal, consumer.presentsModal);
EXPECT_NSEQ(kTitleText, consumer.titleText);
EXPECT_NSEQ(kSubtitleText, consumer.subtitleText);
}
// Tests that an InfobarBannerOverlayMediator correctly dispatches a response
// for confirm button taps before stopping itself.
TEST_F(InfobarBannerOverlayMediatorTest, ConfirmButtonTapped) {
__block bool confirm_button_tapped = false;
void (^confirm_button_tapped_callback)(OverlayResponse* response) =
^(OverlayResponse* response) {
confirm_button_tapped = true;
};
request_->GetCallbackManager()->AddDispatchCallback(OverlayDispatchCallback(
base::BindRepeating(confirm_button_tapped_callback),
InfobarBannerMainActionResponse::ResponseSupport()));
ASSERT_FALSE(confirm_button_tapped);
// Notify the mediator of the button tap via its InfobarBannerDelegate
// implementation and verify that the confirm button callback was executed and
// that the mediator's delegate was instructed to stop.
OCMExpect([delegate_ stopOverlayForMediator:mediator_]);
[mediator_ bannerInfobarButtonWasPressed:nil];
EXPECT_TRUE(confirm_button_tapped);
}
// Tests that an InfobarBannerOverlayMediator correctly dispatches a response
// for modal button taps before stopping itself.
TEST_F(InfobarBannerOverlayMediatorTest, ModalButtonTapped) {
__block bool modal_button_tapped = false;
void (^modal_button_tapped_callback)(OverlayResponse* response) =
^(OverlayResponse* response) {
modal_button_tapped = true;
};
request_->GetCallbackManager()->AddDispatchCallback(OverlayDispatchCallback(
base::BindRepeating(modal_button_tapped_callback),
InfobarBannerShowModalResponse::ResponseSupport()));
ASSERT_FALSE(modal_button_tapped);
// Notify the mediator of the button tap via its InfobarBannerDelegate
// implementation and verify that the modal button callback was executed and
// that the mediator's delegate was instructed to stop.
OCMExpect([delegate_ stopOverlayForMediator:mediator_]);
[mediator_ presentInfobarModalFromBanner];
EXPECT_TRUE(modal_button_tapped);
}
// Tests that an InfobarBannerOverlayMediator correctly sets the completion
// response for user-initiated dismissals triggered by the banner UI.
TEST_F(InfobarBannerOverlayMediatorTest, UserInitiatedDismissal) {
__block bool user_initiated = false;
void (^completion_callback)(OverlayResponse* response) =
^(OverlayResponse* response) {
user_initiated = true;
};
request_->GetCallbackManager()->AddCompletionCallback(
base::BindOnce(completion_callback));
ASSERT_FALSE(user_initiated);
// Notify the mediator of the dismissal via its InfobarBannerDelegate
// implementation and verify that the completion callback was executed with
// the correct info and that the mediator's delegate was instructed to stop.
OCMExpect([delegate_ stopOverlayForMediator:mediator_]);
[mediator_ dismissInfobarBannerForUserInteraction:YES];
request_ = nullptr;
EXPECT_TRUE(user_initiated);
}
......@@ -266,6 +266,7 @@ test("ios_chrome_unittests") {
"//ios/chrome/browser/ui/open_in:unit_tests",
"//ios/chrome/browser/ui/overlays:unit_tests",
"//ios/chrome/browser/ui/overlays/common/alerts:unit_tests",
"//ios/chrome/browser/ui/overlays/infobar_banner:unit_tests",
"//ios/chrome/browser/ui/overlays/web_content_area/app_launcher:unit_tests",
"//ios/chrome/browser/ui/overlays/web_content_area/http_auth_dialogs:unit_tests",
"//ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs:unit_tests",
......
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