Commit 0ae21014 authored by Kurt Horimoto's avatar Kurt Horimoto Committed by Commit Bot

[iOS] Update http auth overlays to use AlertOverlayCoordinator.

This eliminates the boilerplate code of UIViewController setup in the
coordinator, as well as the delegate and datasource capabilities
provided to the mediator.

Bug: 990070
Change-Id: Id0a385a7ebc171f7ff103b9bda1928d1a813eac9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1809515
Commit-Queue: Kurt Horimoto <kkhorimoto@chromium.org>
Reviewed-by: default avatarMike Dougherty <michaeldo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#699449}
parent 5703cf75
......@@ -22,7 +22,7 @@ source_set("http_auth_dialogs") {
"//ios/chrome/browser/ui/alert_view_controller",
"//ios/chrome/browser/ui/elements",
"//ios/chrome/browser/ui/overlays:coordinators",
"//ios/chrome/browser/ui/presenters",
"//ios/chrome/browser/ui/overlays/common/alerts",
"//ui/base",
]
}
......@@ -48,6 +48,7 @@ source_set("unit_tests") {
"//ios/chrome/browser/ui/alert_view_controller/test",
"//ios/chrome/browser/ui/dialogs",
"//ios/chrome/browser/ui/elements",
"//ios/chrome/browser/ui/overlays/common/alerts/test",
"//ios/chrome/browser/ui/overlays/test",
"//ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/test",
"//ios/web/public",
......
......@@ -5,11 +5,11 @@
#ifndef IOS_CHROME_BROWSER_UI_OVERLAYS_WEB_CONTENT_AREA_HTTP_AUTH_DIALOGS_HTTP_AUTH_DIALOG_OVERLAY_COORDINATOR_H_
#define IOS_CHROME_BROWSER_UI_OVERLAYS_WEB_CONTENT_AREA_HTTP_AUTH_DIALOGS_HTTP_AUTH_DIALOG_OVERLAY_COORDINATOR_H_
#import "ios/chrome/browser/ui/overlays/overlay_request_coordinator.h"
#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator.h"
// A coordinator that is used to display UI for HTTP authentication dialogs via
// OverlayPresenter.
@interface HTTPAuthDialogOverlayCoordinator : OverlayRequestCoordinator
@interface HTTPAuthDialogOverlayCoordinator : AlertOverlayCoordinator
@end
#endif // IOS_CHROME_BROWSER_UI_OVERLAYS_WEB_CONTENT_AREA_HTTP_AUTH_DIALOGS_HTTP_AUTH_DIALOG_OVERLAY_COORDINATOR_H_
......@@ -7,113 +7,30 @@
#include "ios/chrome/browser/overlays/public/overlay_request.h"
#include "ios/chrome/browser/overlays/public/web_content_area/http_auth_overlay.h"
#import "ios/chrome/browser/ui/alert_view_controller/alert_view_controller.h"
#import "ios/chrome/browser/ui/overlays/overlay_request_coordinator_delegate.h"
#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_coordinator+subclassing.h"
#import "ios/chrome/browser/ui/overlays/web_content_area/http_auth_dialogs/http_auth_dialog_overlay_mediator.h"
#import "ios/chrome/browser/ui/presenters/contained_presenter_delegate.h"
#import "ios/chrome/browser/ui/presenters/non_modal_view_controller_presenter.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@interface HTTPAuthDialogOverlayCoordinator () <
ContainedPresenterDelegate,
HTTPAuthDialogOverlayMediatorDataSource,
HTTPAuthDialogOverlayMediatorDelegate>
// Whether the coordinator has been started.
@property(nonatomic, getter=isStarted) BOOL started;
@property(nonatomic) AlertViewController* alertViewController;
@property(nonatomic) NonModalViewControllerPresenter* presenter;
@property(nonatomic) HTTPAuthDialogOverlayMediator* mediator;
@interface HTTPAuthDialogOverlayCoordinator ()
@end
@implementation HTTPAuthDialogOverlayCoordinator
#pragma mark - Accessors
- (void)setMediator:(HTTPAuthDialogOverlayMediator*)mediator {
if (_mediator == mediator)
return;
_mediator.delegate = nil;
_mediator.dataSource = nil;
_mediator = mediator;
_mediator.dataSource = self;
_mediator.delegate = self;
}
#pragma mark - ContainedPresenterDelegate
- (void)containedPresenterDidPresent:(id<ContainedPresenter>)presenter {
self.delegate->OverlayUIDidFinishPresentation(self.request);
}
- (void)containedPresenterDidDismiss:(id<ContainedPresenter>)presenter {
self.alertViewController = nil;
self.presenter = nil;
self.delegate->OverlayUIDidFinishDismissal(self.request);
}
#pragma mark - HTTPAuthDialogOverlayMediatorDataSource
- (NSString*)userForMediator:(HTTPAuthDialogOverlayMediator*)mediator {
DCHECK(!self.alertViewController ||
self.alertViewController.textFieldResults.count == 2);
return self.alertViewController.textFieldResults[0];
}
- (NSString*)passwordForMediator:(HTTPAuthDialogOverlayMediator*)mediator {
DCHECK(!self.alertViewController ||
self.alertViewController.textFieldResults.count == 2);
return self.alertViewController.textFieldResults[1];
}
#pragma mark - HTTPAuthDialogOverlayMediatorDelegate
- (void)stopDialogForMediator:(HTTPAuthDialogOverlayMediator*)mediator {
DCHECK_EQ(self.mediator, mediator);
[self stopAnimated:YES];
}
#pragma mark - OverlayCoordinator
+ (BOOL)supportsRequest:(OverlayRequest*)request {
return !!request->GetConfig<HTTPAuthOverlayRequestConfig>();
}
+ (BOOL)usesChildViewController {
return YES;
}
- (UIViewController*)viewController {
return self.alertViewController;
}
@end
- (void)startAnimated:(BOOL)animated {
if (self.started)
return;
self.alertViewController = [[AlertViewController alloc] init];
self.alertViewController.modalPresentationStyle =
UIModalPresentationOverCurrentContext;
self.alertViewController.modalTransitionStyle =
UIModalTransitionStyleCrossDissolve;
self.mediator =
[[HTTPAuthDialogOverlayMediator alloc] initWithRequest:self.request];
self.mediator.consumer = self.alertViewController;
self.presenter = [[NonModalViewControllerPresenter alloc] init];
self.presenter.delegate = self;
self.presenter.baseViewController = self.baseViewController;
self.presenter.presentedViewController = self.alertViewController;
[self.presenter prepareForPresentation];
[self.presenter presentAnimated:animated];
self.started = YES;
}
@implementation HTTPAuthDialogOverlayCoordinator (Subclassing)
- (void)stopAnimated:(BOOL)animated {
if (!self.started)
return;
[self.presenter dismissAnimated:animated];
self.started = NO;
- (AlertOverlayMediator*)newMediator {
return [[HTTPAuthDialogOverlayMediator alloc] initWithRequest:self.request];
}
@end
......@@ -5,53 +5,20 @@
#ifndef IOS_CHROME_BROWSER_UI_OVERLAYS_WEB_CONTENT_AREA_HTTP_AUTH_DIALOGS_HTTP_AUTH_DIALOG_OVERLAY_MEDIATOR_H_
#define IOS_CHROME_BROWSER_UI_OVERLAYS_WEB_CONTENT_AREA_HTTP_AUTH_DIALOGS_HTTP_AUTH_DIALOG_OVERLAY_MEDIATOR_H_
#import <Foundation/Foundation.h>
#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator.h"
class OverlayRequest;
class HTTPAuthOverlayRequestConfig;
@protocol HTTPAuthDialogOverlayMediatorDelegate;
@protocol HTTPAuthDialogOverlayMediatorDataSource;
@protocol AlertConsumer;
// Mediator object that uses a HTTPAuthOverlayRequestConfig to set up the UI for
// an HTTP authentication dialog.
@interface HTTPAuthDialogOverlayMediator : NSObject
// The consumer to be updated by this mediator. Setting to a new value uses the
// HTTPAuthOverlayRequestConfig to update the new consumer.
@property(nonatomic, weak) id<AlertConsumer> consumer;
// The delegate that handles action button functionality set up by the mediator.
@property(nonatomic, weak) id<HTTPAuthDialogOverlayMediatorDelegate> delegate;
// The datasource for prompt input values.
@property(nonatomic, weak) id<HTTPAuthDialogOverlayMediatorDataSource>
dataSource;
@interface HTTPAuthDialogOverlayMediator : AlertOverlayMediator
// Designated initializer for a mediator that uses |request|'s configuration to
// set up an AlertConsumer.
- (instancetype)initWithRequest:(OverlayRequest*)request;
@end
// Protocol used by the actions set up by the
// HTTPAuthDialogOverlayMediator.
@protocol HTTPAuthDialogOverlayMediatorDelegate <NSObject>
// Called by |mediator| to dismiss the dialog overlay when
// an action is tapped.
- (void)stopDialogForMediator:(HTTPAuthDialogOverlayMediator*)mediator;
@end
// Protocol used to provide the text input from the HTTP authentication UI to
// the mediator.
@protocol HTTPAuthDialogOverlayMediatorDataSource <NSObject>
// Fetches the current value of the username and password text fields from the
// UI that was set up by |mediator|.
- (NSString*)userForMediator:(HTTPAuthDialogOverlayMediator*)mediator;
- (NSString*)passwordForMediator:(HTTPAuthDialogOverlayMediator*)mediator;
- (instancetype)initWithRequest:(OverlayRequest*)request
NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
@end
......
......@@ -13,6 +13,7 @@
#import "ios/chrome/browser/ui/alert_view_controller/alert_action.h"
#import "ios/chrome/browser/ui/alert_view_controller/alert_consumer.h"
#import "ios/chrome/browser/ui/elements/text_field_configuration.h"
#import "ios/chrome/browser/ui/overlays/common/alerts/alert_overlay_mediator+subclassing.h"
#include "ios/chrome/grit/ios_strings.h"
#include "ui/base/l10n/l10n_util.h"
......@@ -22,8 +23,11 @@
@interface HTTPAuthDialogOverlayMediator ()
@property(nonatomic, readonly) OverlayRequest* request;
// The HTTP authentication config.
@property(nonatomic, readonly) HTTPAuthOverlayRequestConfig* config;
// Sets the OverlayResponse using the user input from the prompt UI.
// |cancelled| indicates whether the alert's cancel button was tapped.
- (void)updateResponseCancelled:(BOOL)cancelled;
@end
@implementation HTTPAuthDialogOverlayMediator
......@@ -44,16 +48,59 @@
return self.request->GetConfig<HTTPAuthOverlayRequestConfig>();
}
- (void)setConsumer:(id<AlertConsumer>)consumer {
if (self.consumer == consumer)
return;
_consumer = consumer;
[_consumer setTitle:l10n_util::GetNSStringWithFixup(IDS_LOGIN_DIALOG_TITLE)];
[self.consumer setMessage:base::SysUTF8ToNSString(self.config->message())];
#pragma mark - Response helpers
- (void)updateResponseCancelled:(BOOL)cancelled {
std::unique_ptr<OverlayResponse> response;
if (!cancelled) {
std::string user =
base::SysNSStringToUTF8([self.dataSource textFieldInputForMediator:self
textFieldIndex:0]);
std::string password =
base::SysNSStringToUTF8([self.dataSource textFieldInputForMediator:self
textFieldIndex:1]);
response = OverlayResponse::CreateWithInfo<HTTPAuthOverlayResponseInfo>(
user, password);
}
self.request->set_response(std::move(response));
}
@end
@implementation HTTPAuthDialogOverlayMediator (Subclassing)
- (NSString*)alertTitle {
return l10n_util::GetNSStringWithFixup(IDS_LOGIN_DIALOG_TITLE);
}
- (NSString*)alertMessage {
return base::SysUTF8ToNSString(self.config->message());
}
- (NSArray<TextFieldConfiguration*>*)alertTextFieldConfigurations {
NSString* defaultUsername =
base::SysUTF8ToNSString(self.config->default_username());
NSString* usernamePlaceholder =
l10n_util::GetNSString(IDS_IOS_HTTP_LOGIN_DIALOG_USERNAME_PLACEHOLDER);
NSString* passwordPlaceholder =
l10n_util::GetNSString(IDS_IOS_HTTP_LOGIN_DIALOG_PASSWORD_PLACEHOLDER);
return @[
[[TextFieldConfiguration alloc] initWithText:defaultUsername
placeholder:usernamePlaceholder
accessibilityIdentifier:nil
secureTextEntry:NO],
[[TextFieldConfiguration alloc] initWithText:nil
placeholder:passwordPlaceholder
accessibilityIdentifier:nil
secureTextEntry:YES]
];
}
- (NSArray<AlertAction*>*)alertActions {
__weak __typeof__(self) weakSelf = self;
NSString* OKLabel =
l10n_util::GetNSStringWithFixup(IDS_LOGIN_DIALOG_OK_BUTTON_LABEL);
[self.consumer setActions:@[
return @[
[AlertAction actionWithTitle:OKLabel
style:UIAlertActionStyleDefault
handler:^(AlertAction* action) {
......@@ -70,41 +117,7 @@
[strongSelf.delegate
stopDialogForMediator:strongSelf];
}],
]];
NSString* defaultUsername =
base::SysUTF8ToNSString(self.config->default_username());
NSString* usernamePlaceholder =
l10n_util::GetNSString(IDS_IOS_HTTP_LOGIN_DIALOG_USERNAME_PLACEHOLDER);
NSString* passwordPlaceholder =
l10n_util::GetNSString(IDS_IOS_HTTP_LOGIN_DIALOG_PASSWORD_PLACEHOLDER);
[self.consumer setTextFieldConfigurations:@[
[[TextFieldConfiguration alloc] initWithText:defaultUsername
placeholder:usernamePlaceholder
accessibilityIdentifier:nil
secureTextEntry:NO],
[[TextFieldConfiguration alloc] initWithText:nil
placeholder:passwordPlaceholder
accessibilityIdentifier:nil
secureTextEntry:YES]
]];
}
#pragma mark - Response helpers
// Sets the OverlayResponse using the user input from the prompt UI.
// |cancelled| indicates whether the alert's cancel button was tapped.
- (void)updateResponseCancelled:(BOOL)cancelled {
std::unique_ptr<OverlayResponse> response;
if (!cancelled) {
std::string user =
base::SysNSStringToUTF8([self.dataSource userForMediator:self]);
std::string password =
base::SysNSStringToUTF8([self.dataSource passwordForMediator:self]);
response = OverlayResponse::CreateWithInfo<HTTPAuthOverlayResponseInfo>(
user, password);
}
self.request->set_response(std::move(response));
];
}
@end
......@@ -14,6 +14,7 @@
#import "ios/chrome/browser/ui/alert_view_controller/test/fake_alert_consumer.h"
#import "ios/chrome/browser/ui/dialogs/java_script_dialog_blocking_state.h"
#import "ios/chrome/browser/ui/elements/text_field_configuration.h"
#import "ios/chrome/browser/ui/overlays/common/alerts/test/alert_overlay_mediator_test.h"
#include "ios/chrome/grit/ios_strings.h"
#include "testing/gtest_mac.h"
#include "testing/platform_test.h"
......@@ -23,49 +24,45 @@
#error "This file requires ARC support."
#endif
class HTTPAuthDialogOverlayMediatorTest : public PlatformTest {
class HTTPAuthDialogOverlayMediatorTest : public AlertOverlayMediatorTest {
public:
HTTPAuthDialogOverlayMediatorTest()
: consumer_([[FakeAlertConsumer alloc] init]),
message_("Message"),
: message_("Message"),
default_user_text_("Default Text"),
request_(OverlayRequest::CreateWithConfig<HTTPAuthOverlayRequestConfig>(
message_,
default_user_text_)),
mediator_([[HTTPAuthDialogOverlayMediator alloc]
initWithRequest:request_.get()]) {
mediator_.consumer = consumer_;
default_user_text_)) {
SetMediator(
[[HTTPAuthDialogOverlayMediator alloc] initWithRequest:request_.get()]);
}
protected:
FakeAlertConsumer* consumer_ = nil;
const std::string message_;
const std::string default_user_text_;
std::unique_ptr<OverlayRequest> request_;
HTTPAuthDialogOverlayMediator* mediator_ = nil;
};
// Tests that the consumer values are set correctly for confirmations.
TEST_F(HTTPAuthDialogOverlayMediatorTest, AlertSetup) {
// Verify the consumer values.
EXPECT_NSEQ(base::SysUTF8ToNSString(message_), consumer_.message);
EXPECT_EQ(2U, consumer_.textFieldConfigurations.count);
EXPECT_NSEQ(base::SysUTF8ToNSString(message_), consumer().message);
EXPECT_EQ(2U, consumer().textFieldConfigurations.count);
EXPECT_NSEQ(base::SysUTF8ToNSString(default_user_text_),
consumer_.textFieldConfigurations[0].text);
consumer().textFieldConfigurations[0].text);
NSString* user_placeholer =
l10n_util::GetNSString(IDS_IOS_HTTP_LOGIN_DIALOG_USERNAME_PLACEHOLDER);
EXPECT_NSEQ(user_placeholer,
consumer_.textFieldConfigurations[0].placeholder);
EXPECT_FALSE(!!consumer_.textFieldConfigurations[1].text);
consumer().textFieldConfigurations[0].placeholder);
EXPECT_FALSE(!!consumer().textFieldConfigurations[1].text);
NSString* password_placeholder =
l10n_util::GetNSString(IDS_IOS_HTTP_LOGIN_DIALOG_PASSWORD_PLACEHOLDER);
EXPECT_NSEQ(password_placeholder,
consumer_.textFieldConfigurations[1].placeholder);
ASSERT_EQ(2U, consumer_.actions.count);
EXPECT_EQ(UIAlertActionStyleDefault, consumer_.actions[0].style);
consumer().textFieldConfigurations[1].placeholder);
ASSERT_EQ(2U, consumer().actions.count);
EXPECT_EQ(UIAlertActionStyleDefault, consumer().actions[0].style);
NSString* sign_in_label =
l10n_util::GetNSStringWithFixup(IDS_LOGIN_DIALOG_OK_BUTTON_LABEL);
EXPECT_NSEQ(sign_in_label, consumer_.actions[0].title);
EXPECT_EQ(UIAlertActionStyleCancel, consumer_.actions[1].style);
EXPECT_NSEQ(l10n_util::GetNSString(IDS_CANCEL), consumer_.actions[1].title);
EXPECT_NSEQ(sign_in_label, consumer().actions[0].title);
EXPECT_EQ(UIAlertActionStyleCancel, consumer().actions[1].style);
EXPECT_NSEQ(l10n_util::GetNSString(IDS_CANCEL), consumer().actions[1].title);
}
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