[iOS] Show Bottom Sheet for the edit profile view
This CL introduces coordinator as well as view controller to implement the bottom sheet for the address edit in the save flow.
Screencast: http://screencast/cast/NjI4NzY0MjI1NjczNjI1Nnw0MDhlYmQ2MC1jMQ
Low-Coverage-Reason: TESTS_IN_SEPARATE_CL (https://crrev.com/c/5440193) The feature is in development and more tests will be added.
Bug: 1482269
Change-Id: I2ec00e71550c384a441bbb1ec691ff609a32e1e1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5439433
Reviewed-by: Tommy Martino <tmartino@chromium.org>
Commit-Queue: Vidhan Jain <vidhanj@google.com>
Reviewed-by: Gauthier Ambard <gambard@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1287276}
diff --git a/ios/chrome/browser/autofill/model/bottom_sheet/autofill_bottom_sheet_tab_helper.h b/ios/chrome/browser/autofill/model/bottom_sheet/autofill_bottom_sheet_tab_helper.h
index d264e15..434be2bb 100644
--- a/ios/chrome/browser/autofill/model/bottom_sheet/autofill_bottom_sheet_tab_helper.h
+++ b/ios/chrome/browser/autofill/model/bottom_sheet/autofill_bottom_sheet_tab_helper.h
@@ -139,6 +139,10 @@
// This value is moved and should only be retrieved once per bottom sheet.
autofill::VirtualCardEnrollmentCallbacks GetVirtualCardEnrollmentCallbacks();
+ std::unique_ptr<autofill::AutofillProfile> address_profile_for_edit() {
+ return std::move(address_profile_for_edit_);
+ }
+
private:
friend class web::WebStateUserData<AutofillBottomSheetTabHelper>;
diff --git a/ios/chrome/browser/ui/autofill/bottom_sheet/BUILD.gn b/ios/chrome/browser/ui/autofill/bottom_sheet/BUILD.gn
index 262cbb87..0a4cbc8 100644
--- a/ios/chrome/browser/ui/autofill/bottom_sheet/BUILD.gn
+++ b/ios/chrome/browser/ui/autofill/bottom_sheet/BUILD.gn
@@ -13,6 +13,8 @@
source_set("bottom_sheet") {
sources = [
+ "autofill_edit_profile_bottom_sheet_coordinator.h",
+ "autofill_edit_profile_bottom_sheet_coordinator.mm",
"payments_suggestion_bottom_sheet_coordinator.h",
"payments_suggestion_bottom_sheet_coordinator.mm",
"payments_suggestion_bottom_sheet_exit_reason.h",
@@ -35,6 +37,9 @@
"//ios/chrome/browser/shared/model/browser_state",
"//ios/chrome/browser/shared/model/web_state_list",
"//ios/chrome/browser/shared/public/commands",
+ "//ios/chrome/browser/shared/ui/table_view",
+ "//ios/chrome/browser/ui/autofill:autofill_shared_ui",
+ "//ios/chrome/browser/ui/autofill/cells",
"//ios/web/public",
"//ios/web/public/js_messaging",
"//ui/base",
@@ -43,6 +48,8 @@
source_set("bottom_sheet_ui") {
sources = [
+ "autofill_edit_profile_bottom_sheet_table_view_controller.h",
+ "autofill_edit_profile_bottom_sheet_table_view_controller.mm",
"payments_suggestion_bottom_sheet_consumer.h",
"payments_suggestion_bottom_sheet_delegate.h",
"payments_suggestion_bottom_sheet_handler.h",
@@ -54,15 +61,20 @@
"//components/autofill/core/browser",
"//components/autofill/ios/browser",
"//components/resources:components_scaled_resources_grit",
+ "//components/strings:components_strings_grit",
"//components/url_formatter",
"//ios/chrome/app/strings",
"//ios/chrome/browser/autofill/model/credit_card",
"//ios/chrome/browser/shared/ui/bottom_sheet:table_view_bottom_sheet_view_controller",
"//ios/chrome/browser/shared/ui/symbols",
+ "//ios/chrome/browser/shared/ui/table_view:styler",
+ "//ios/chrome/browser/shared/ui/table_view:table_view",
"//ios/chrome/browser/shared/ui/table_view/cells",
"//ios/chrome/browser/shared/ui/util",
+ "//ios/chrome/browser/ui/autofill:autofill_shared_ui",
"//ios/chrome/common/ui/colors",
"//ios/chrome/common/ui/confirmation_alert",
+ "//ios/chrome/common/ui/table_view:cells_constants",
"//ui/base:base",
"//url",
]
@@ -71,6 +83,7 @@
source_set("bottom_sheet_unit_tests") {
testonly = true
sources = [
+ "autofill_edit_profile_bottom_sheet_table_view_controller_unittest.mm",
"payments_suggestion_bottom_sheet_coordinator_unittest.mm",
"payments_suggestion_bottom_sheet_mediator_unittest.mm",
]
@@ -83,6 +96,7 @@
"//components/autofill/ios/form_util",
"//components/prefs",
"//components/sync:test_support",
+ "//ios/chrome/app/strings:ios_strings_grit",
"//ios/chrome/browser/autofill/model",
"//ios/chrome/browser/autofill/model/credit_card",
"//ios/chrome/browser/default_browser/model:utils",
@@ -90,9 +104,12 @@
"//ios/chrome/browser/shared/model/browser_state:test_support",
"//ios/chrome/browser/shared/model/web_state_list",
"//ios/chrome/browser/shared/model/web_state_list/test:test_support",
+ "//ios/chrome/browser/shared/ui/table_view:test_support",
+ "//ios/chrome/browser/shared/ui/table_view/cells",
"//ios/chrome/browser/signin/model",
"//ios/chrome/browser/signin/model:test_support",
"//ios/chrome/browser/tabs/model",
+ "//ios/chrome/browser/ui/autofill:autofill_shared_ui",
"//ios/chrome/browser/webdata_services/model",
"//ios/chrome/test:test_support",
"//ios/web/public/test",
diff --git a/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_coordinator.h b/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_coordinator.h
new file mode 100644
index 0000000..e7b5706
--- /dev/null
+++ b/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_coordinator.h
@@ -0,0 +1,16 @@
+// Copyright 2024 The Chromium Authors
+// 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_AUTOFILL_BOTTOM_SHEET_AUTOFILL_EDIT_PROFILE_BOTTOM_SHEET_COORDINATOR_H_
+#define IOS_CHROME_BROWSER_UI_AUTOFILL_BOTTOM_SHEET_AUTOFILL_EDIT_PROFILE_BOTTOM_SHEET_COORDINATOR_H_
+
+#import "ios/chrome/browser/shared/coordinator/chrome_coordinator/chrome_coordinator.h"
+
+// Coordinator for showing the bottomsheet view for editing an address during
+// the save flow.
+@interface AutofillEditProfileBottomSheetCoordinator : ChromeCoordinator
+
+@end
+
+#endif // IOS_CHROME_BROWSER_UI_AUTOFILL_BOTTOM_SHEET_AUTOFILL_EDIT_PROFILE_BOTTOM_SHEET_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_coordinator.mm b/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_coordinator.mm
new file mode 100644
index 0000000..2ac9843
--- /dev/null
+++ b/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_coordinator.mm
@@ -0,0 +1,135 @@
+// Copyright 2024 The Chromium Authors
+// 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/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_coordinator.h"
+
+#import "components/autofill/core/browser/data_model/autofill_profile.h"
+#import "ios/chrome/browser/autofill/model/bottom_sheet/autofill_bottom_sheet_tab_helper.h"
+#import "ios/chrome/browser/autofill/model/personal_data_manager_factory.h"
+#import "ios/chrome/browser/shared/model/browser/browser.h"
+#import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
+#import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h"
+#import "ios/chrome/browser/shared/ui/table_view/table_view_navigation_controller.h"
+#import "ios/chrome/browser/ui/autofill/autofill_country_selection_table_view_controller.h"
+#import "ios/chrome/browser/ui/autofill/autofill_profile_edit_mediator.h"
+#import "ios/chrome/browser/ui/autofill/autofill_profile_edit_mediator_delegate.h"
+#import "ios/chrome/browser/ui/autofill/autofill_profile_edit_table_view_controller.h"
+#import "ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_table_view_controller.h"
+#import "ios/chrome/browser/ui/autofill/cells/country_item.h"
+
+@interface AutofillEditProfileBottomSheetCoordinator () <
+ AutofillProfileEditMediatorDelegate>
+@end
+
+@implementation AutofillEditProfileBottomSheetCoordinator {
+ // Profile to be edited.
+ std::unique_ptr<autofill::AutofillProfile> _autofillProfile;
+
+ // Navigation controller presented by this coordinator.
+ TableViewNavigationController* _navigationController;
+
+ // TVC for displaying the bottom sheet.
+ AutofillEditProfileBottomSheetTableViewController* _viewController;
+
+ // Mediator and view controller used to display the edit view.
+ AutofillProfileEditTableViewController*
+ _autofillProfileEditTableViewController;
+ AutofillProfileEditMediator* _autofillProfileEditMediator;
+
+ raw_ptr<autofill::PersonalDataManager> _personalDataManager;
+}
+
+- (instancetype)initWithBaseViewController:
+ (UINavigationController*)viewController
+ browser:(Browser*)browser {
+ self = [super initWithBaseViewController:viewController browser:browser];
+ if (self) {
+ ChromeBrowserState* browserState = browser->GetBrowserState();
+
+ // Address Save Prompt is not shown in the incognito mode.
+ CHECK(!browserState->IsOffTheRecord());
+ _personalDataManager =
+ autofill::PersonalDataManagerFactory::GetForBrowserState(browserState);
+
+ web::WebState* webState = browser->GetWebStateList()->GetActiveWebState();
+ AutofillBottomSheetTabHelper* bottomSheetTabHelper =
+ AutofillBottomSheetTabHelper::FromWebState(webState);
+
+ _autofillProfile = bottomSheetTabHelper->address_profile_for_edit();
+ CHECK(_autofillProfile);
+ }
+ return self;
+}
+
+#pragma mark - ChromeCoordinator
+
+- (void)start {
+ _autofillProfileEditMediator = [[AutofillProfileEditMediator alloc]
+ initWithDelegate:self
+ personalDataManager:_personalDataManager
+ autofillProfile:_autofillProfile.get()
+ countryCode:nil
+ isMigrationPrompt:NO];
+
+ // Bottom sheet table VC
+ AutofillEditProfileBottomSheetTableViewController* editModalViewController =
+ [[AutofillEditProfileBottomSheetTableViewController alloc]
+ initWithStyle:UITableViewStylePlain];
+
+ // View controller that lays down the table views for the edit profile view.
+ _autofillProfileEditTableViewController =
+ [[AutofillProfileEditTableViewController alloc]
+ initWithDelegate:_autofillProfileEditMediator
+ userEmail:@""
+ controller:editModalViewController
+ settingsView:NO];
+ _autofillProfileEditMediator.consumer =
+ _autofillProfileEditTableViewController;
+ // `editModalViewController` lays down the bottom sheet view and communicates
+ // with `_autofillProfileEditTableViewController` via
+ // `AutofillProfileEditHandler` protocol.
+ // `_autofillProfileEditTableViewController` is responsible for loading the
+ // model and dealing with the table view user interactions.
+ editModalViewController.handler = _autofillProfileEditTableViewController;
+
+ _viewController = editModalViewController;
+
+ _navigationController =
+ [[TableViewNavigationController alloc] initWithTable:_viewController];
+ _navigationController.modalPresentationStyle = UIModalPresentationFormSheet;
+ _navigationController.modalTransitionStyle =
+ UIModalTransitionStyleCoverVertical;
+
+ [self.baseViewController presentViewController:_navigationController
+ animated:YES
+ completion:nil];
+}
+
+- (void)stop {
+ [super stop];
+ [_navigationController.presentingViewController
+ dismissViewControllerAnimated:YES
+ completion:nil];
+ _viewController = nil;
+ _autofillProfileEditMediator = nil;
+}
+
+#pragma mark - AutofillProfileEditMediatorDelegate
+
+- (void)autofillEditProfileMediatorDidFinish:
+ (AutofillProfileEditMediator*)mediator {
+ // TODO(crbug.com/1482269): Implement.
+}
+
+- (void)willSelectCountryWithCurrentlySelectedCountry:(NSString*)country
+ countryList:(NSArray<CountryItem*>*)
+ allCountries {
+ // TODO(crbug.com/1482269): Implement.
+}
+
+- (void)didSaveProfile {
+ // TODO(crbug.com/1482269): Implement.
+}
+
+@end
diff --git a/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_table_view_controller.h b/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_table_view_controller.h
new file mode 100644
index 0000000..b1f4ad3
--- /dev/null
+++ b/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_table_view_controller.h
@@ -0,0 +1,19 @@
+// Copyright 2024 The Chromium Authors
+// 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_AUTOFILL_BOTTOM_SHEET_AUTOFILL_EDIT_PROFILE_BOTTOM_SHEET_TABLE_VIEW_CONTROLLER_H_
+#define IOS_CHROME_BROWSER_UI_AUTOFILL_BOTTOM_SHEET_AUTOFILL_EDIT_PROFILE_BOTTOM_SHEET_TABLE_VIEW_CONTROLLER_H_
+
+#import "ios/chrome/browser/shared/ui/table_view/legacy_chrome_table_view_controller.h"
+#import "ios/chrome/browser/ui/autofill/autofill_profile_edit_handler.h"
+
+// The Bottom Sheet TableView for an Autofill save/update address edit menu.
+@interface AutofillEditProfileBottomSheetTableViewController
+ : LegacyChromeTableViewController
+
+@property(nonatomic, weak) id<AutofillProfileEditHandler> handler;
+
+@end
+
+#endif // IOS_CHROME_BROWSER_UI_AUTOFILL_BOTTOM_SHEET_AUTOFILL_EDIT_PROFILE_BOTTOM_SHEET_TABLE_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_table_view_controller.mm b/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_table_view_controller.mm
new file mode 100644
index 0000000..27ed0fa
--- /dev/null
+++ b/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_table_view_controller.mm
@@ -0,0 +1,164 @@
+// Copyright 2024 The Chromium Authors
+// 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/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_table_view_controller.h"
+
+#import "base/apple/foundation_util.h"
+#import "components/strings/grit/components_strings.h"
+#import "ios/chrome/browser/shared/ui/table_view/legacy_chrome_table_view_styler.h"
+#import "ios/chrome/common/ui/colors/semantic_color_names.h"
+#import "ios/chrome/common/ui/table_view/table_view_cells_constants.h"
+#import "ios/chrome/grit/ios_strings.h"
+#import "ui/base/l10n/l10n_util_mac.h"
+
+namespace {
+
+// Custom radius for the half sheet presentation.
+CGFloat const kHalfSheetCornerRadius = 20;
+
+// Custom detent identifier for when the bottom sheet is minimized.
+NSString* const kCustomMinimizedDetentIdentifier = @"customMinimizedDetent";
+
+// Custom detent identifier for when the bottom sheet is expanded.
+NSString* const kCustomExpandedDetentIdentifier = @"customExpandedDetent";
+
+} // namespace
+
+@interface AutofillEditProfileBottomSheetTableViewController () <
+ UITextFieldDelegate>
+
+// TODO(crbug.com/1482269): Update via the consumer protocol.
+// Yes, if the edit is done for updating the profile.
+@property(nonatomic, assign) BOOL isEditForUpdate;
+
+// TODO(crbug.com/1482269): Update via the consumer protocol.
+// Yes, if the edit is shown for the migration prompt.
+@property(nonatomic, assign) BOOL migrationPrompt;
+
+@end
+
+@implementation AutofillEditProfileBottomSheetTableViewController
+
+#pragma mark - Initialization
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ [self setUpBottomSheetPresentationController];
+ [self setUpBottomSheetDetents];
+
+ self.view.backgroundColor = [UIColor colorNamed:kBackgroundColor];
+ self.styler.cellBackgroundColor = [UIColor colorNamed:kBackgroundColor];
+ self.tableView.sectionHeaderHeight = 0;
+ self.tableView.estimatedRowHeight = 56;
+ [self.tableView
+ setSeparatorInset:UIEdgeInsetsMake(0, kTableViewHorizontalSpacing, 0, 0)];
+
+ // Configure the NavigationBar.
+ UIBarButtonItem* cancelButton = [[UIBarButtonItem alloc]
+ initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
+ target:self
+ action:@selector(handleCancelButton)];
+
+ self.navigationItem.leftBarButtonItem = cancelButton;
+ self.navigationController.navigationBar.prefersLargeTitles = NO;
+ if (self.migrationPrompt) {
+ [self setTitle:
+ l10n_util::GetNSString(
+ IDS_IOS_AUTOFILL_ADDRESS_MIGRATION_TO_ACCOUNT_PROMPT_TITLE)];
+ } else {
+ [self setTitle:l10n_util::GetNSString(
+ self.isEditForUpdate
+ ? IDS_IOS_AUTOFILL_UPDATE_ADDRESS_PROMPT_TITLE
+ : IDS_IOS_AUTOFILL_SAVE_ADDRESS_PROMPT_TITLE)];
+ }
+
+ self.tableView.allowsSelectionDuringEditing = YES;
+
+ [self loadModel];
+}
+
+- (void)loadModel {
+ [super loadModel];
+ [self.handler setMigrationPrompt:self.migrationPrompt];
+ [self.handler loadModel];
+ [self.handler
+ loadMessageAndButtonForModalIfSaveOrUpdate:self.isEditForUpdate];
+}
+
+- (void)expandBottomSheet {
+ UISheetPresentationController* presentationController =
+ self.sheetPresentationController;
+ // Expand to large detent.
+ [presentationController animateChanges:^{
+ presentationController.selectedDetentIdentifier =
+ UISheetPresentationControllerDetentIdentifierLarge;
+ }];
+}
+
+- (void)setUpBottomSheetPresentationController {
+ UISheetPresentationController* presentationController =
+ self.sheetPresentationController;
+ presentationController.prefersEdgeAttachedInCompactHeight = YES;
+ presentationController.widthFollowsPreferredContentSizeWhenEdgeAttached = YES;
+ presentationController.preferredCornerRadius = kHalfSheetCornerRadius;
+}
+
+- (void)setUpBottomSheetDetents {
+ UISheetPresentationController* presentationController =
+ self.sheetPresentationController;
+ presentationController.detents = @[
+ [UISheetPresentationControllerDetent mediumDetent],
+ [UISheetPresentationControllerDetent largeDetent]
+ ];
+ presentationController.selectedDetentIdentifier =
+ UISheetPresentationControllerDetentIdentifierLarge;
+}
+
+#pragma mark - UITableViewDataSource
+
+- (UITableViewCell*)tableView:(UITableView*)tableView
+ cellForRowAtIndexPath:(NSIndexPath*)indexPath {
+ UITableViewCell* cell = [super tableView:tableView
+ cellForRowAtIndexPath:indexPath];
+ return [self.handler cell:cell
+ forRowAtIndexPath:indexPath
+ withTextDelegate:self];
+}
+
+- (void)tableView:(UITableView*)tableView
+ didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
+ [self.handler didSelectRowAtIndexPath:indexPath];
+}
+
+- (CGFloat)tableView:(UITableView*)tableView
+ heightForHeaderInSection:(NSInteger)section {
+ if ([self.handler heightForHeaderShouldBeZeroInSection:section]) {
+ return 0;
+ }
+ return [super tableView:tableView heightForHeaderInSection:section];
+}
+
+- (CGFloat)tableView:(UITableView*)tableView
+ heightForFooterInSection:(NSInteger)section {
+ if ([self.handler heightForFooterShouldBeZeroInSection:section]) {
+ return 0;
+ }
+ return [super tableView:tableView heightForFooterInSection:section];
+}
+
+#pragma mark - Actions
+
+- (void)handleCancelButton {
+ // TODO(crbug.com/1482269): Implement.
+}
+
+#pragma mark - UITextFieldDelegate
+
+- (BOOL)textFieldShouldReturn:(UITextField*)textField {
+ [textField resignFirstResponder];
+ return NO;
+}
+
+@end
diff --git a/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_table_view_controller_unittest.mm b/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_table_view_controller_unittest.mm
new file mode 100644
index 0000000..dfa9e266
--- /dev/null
+++ b/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_table_view_controller_unittest.mm
@@ -0,0 +1,140 @@
+// Copyright 2024 The Chromium Authors
+// 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/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_table_view_controller.h"
+
+#import <memory>
+
+#import "base/apple/foundation_util.h"
+#import "base/feature_list.h"
+#import "base/strings/sys_string_conversions.h"
+#import "base/strings/utf_string_conversions.h"
+#import "components/autofill/core/browser/autofill_test_utils.h"
+#import "components/autofill/core/browser/data_model/autofill_profile.h"
+#import "ios/chrome/browser/shared/ui/table_view/cells/table_view_text_button_item.h"
+#import "ios/chrome/browser/shared/ui/table_view/cells/table_view_text_edit_item.h"
+#import "ios/chrome/browser/shared/ui/table_view/legacy_chrome_table_view_controller_test.h"
+#import "ios/chrome/browser/ui/autofill/autofill_profile_edit_handler.h"
+#import "ios/chrome/browser/ui/autofill/autofill_profile_edit_table_view_controller.h"
+#import "ios/chrome/browser/ui/autofill/autofill_profile_edit_table_view_controller_delegate.h"
+#import "ios/chrome/grit/ios_strings.h"
+#import "testing/gtest_mac.h"
+#import "testing/platform_test.h"
+#import "third_party/ocmock/OCMock/OCMock.h"
+#import "ui/base/l10n/l10n_util_mac.h"
+
+namespace {
+
+class AutofillEditProfileBottomSheetTableViewControllerTest
+ : public LegacyChromeTableViewControllerTest {
+ protected:
+ void SetUp() override {
+ LegacyChromeTableViewControllerTest::SetUp();
+ delegate_mock_ = OCMProtocolMock(
+ @protocol(AutofillProfileEditTableViewControllerDelegate));
+ CreateController();
+ CheckController();
+ CreateProfileData();
+
+ // Reload the model so that the changes are propogated.
+ [controller() loadModel];
+ }
+
+ LegacyChromeTableViewController* InstantiateController() override {
+ AutofillEditProfileBottomSheetTableViewController* viewController =
+ [[AutofillEditProfileBottomSheetTableViewController alloc]
+ initWithStyle:UITableViewStylePlain];
+ autofill_profile_edit_table_view_controller_ =
+ [[AutofillProfileEditTableViewController alloc]
+ initWithDelegate:delegate_mock_
+ userEmail:nil
+ controller:viewController
+ settingsView:NO];
+ viewController.handler = autofill_profile_edit_table_view_controller_;
+ return viewController;
+ }
+
+ void CreateProfileData() {
+ autofill::AutofillProfile profile = autofill::test::GetFullProfile2();
+ [autofill_profile_edit_table_view_controller_
+ setFullName:base::SysUTF16ToNSString(
+ profile.GetRawInfo(autofill::NAME_FULL))];
+ [autofill_profile_edit_table_view_controller_
+ setCompanyName:base::SysUTF16ToNSString(
+ profile.GetRawInfo(autofill::COMPANY_NAME))];
+ [autofill_profile_edit_table_view_controller_
+ setHomeAddressLine1:base::SysUTF16ToNSString(profile.GetRawInfo(
+ autofill::ADDRESS_HOME_LINE1))];
+ [autofill_profile_edit_table_view_controller_
+ setHomeAddressLine2:base::SysUTF16ToNSString(profile.GetRawInfo(
+ autofill::ADDRESS_HOME_LINE2))];
+ [autofill_profile_edit_table_view_controller_
+ setHomeAddressDependentLocality:
+ base::SysUTF16ToNSString(
+ profile.GetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_LOCALITY))];
+ [autofill_profile_edit_table_view_controller_
+ setHomeAddressCity:base::SysUTF16ToNSString(profile.GetRawInfo(
+ autofill::ADDRESS_HOME_CITY))];
+ [autofill_profile_edit_table_view_controller_
+ setHomeAddressAdminLevel2:base::SysUTF16ToNSString(profile.GetRawInfo(
+ autofill::ADDRESS_HOME_ADMIN_LEVEL2))];
+ [autofill_profile_edit_table_view_controller_
+ setHomeAddressState:base::SysUTF16ToNSString(profile.GetRawInfo(
+ autofill::ADDRESS_HOME_STATE))];
+ [autofill_profile_edit_table_view_controller_
+ setHomeAddressZip:base::SysUTF16ToNSString(
+ profile.GetRawInfo(autofill::ADDRESS_HOME_ZIP))];
+ [autofill_profile_edit_table_view_controller_
+ setHomeAddressCountry:base::SysUTF16ToNSString(profile.GetRawInfo(
+ autofill::ADDRESS_HOME_COUNTRY))];
+ [autofill_profile_edit_table_view_controller_
+ setHomePhoneWholeNumber:base::SysUTF16ToNSString(profile.GetRawInfo(
+ autofill::PHONE_HOME_WHOLE_NUMBER))];
+ [autofill_profile_edit_table_view_controller_
+ setEmailAddress:base::SysUTF16ToNSString(
+ profile.GetRawInfo(autofill::EMAIL_ADDRESS))];
+ }
+
+ AutofillProfileEditTableViewController*
+ autofill_profile_edit_table_view_controller_;
+ id delegate_mock_;
+};
+
+// Tests that there are no requirement checks for the profiles saved to sync.
+TEST_F(AutofillEditProfileBottomSheetTableViewControllerTest,
+ TestNoRequirements) {
+ [autofill_profile_edit_table_view_controller_ setLine1Required:YES];
+ [autofill_profile_edit_table_view_controller_ setCityRequired:YES];
+ [autofill_profile_edit_table_view_controller_ setStateRequired:YES];
+ [autofill_profile_edit_table_view_controller_ setZipRequired:NO];
+
+ TableViewTextButtonItem* button_item = static_cast<TableViewTextButtonItem*>(
+ GetTableViewItem(0, NumberOfItemsInSection(0) - 1));
+ EXPECT_EQ(button_item.enabled, YES);
+
+ TableViewTextEditItem* zip_item =
+ static_cast<TableViewTextEditItem*>(GetTableViewItem(0, 6));
+ zip_item.textFieldValue = @"";
+ [autofill_profile_edit_table_view_controller_
+ tableViewItemDidChange:zip_item];
+ // Since, zip was set as not required, the button should be enabled.
+ EXPECT_EQ(button_item.enabled, YES);
+
+ TableViewTextEditItem* name_item =
+ static_cast<TableViewTextEditItem*>(GetTableViewItem(0, 0));
+ name_item.textFieldValue = @"";
+ [autofill_profile_edit_table_view_controller_
+ tableViewItemDidChange:name_item];
+ // Should be still enabled.
+ EXPECT_EQ(button_item.enabled, YES);
+
+ TableViewTextEditItem* city_item =
+ static_cast<TableViewTextEditItem*>(GetTableViewItem(0, 4));
+ city_item.textFieldValue = @"";
+ [autofill_profile_edit_table_view_controller_
+ tableViewItemDidChange:city_item];
+ EXPECT_EQ(button_item.enabled, YES);
+}
+
+} // namespace
diff --git a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
index c3f34e0d..0f79d7a 100644
--- a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
@@ -130,6 +130,7 @@
#import "ios/chrome/browser/ui/authentication/enterprise/enterprise_prompt/enterprise_prompt_type.h"
#import "ios/chrome/browser/ui/authentication/signin_presenter.h"
#import "ios/chrome/browser/ui/autofill/authentication/card_unmask_authentication_coordinator.h"
+#import "ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_coordinator.h"
#import "ios/chrome/browser/ui/autofill/bottom_sheet/payments_suggestion_bottom_sheet_coordinator.h"
#import "ios/chrome/browser/ui/autofill/bottom_sheet/virtual_card_enrollment_bottom_sheet_coordinator.h"
#import "ios/chrome/browser/ui/autofill/error_dialog/autofill_error_dialog_coordinator.h"
@@ -372,6 +373,9 @@
@property(nonatomic, strong)
PlusAddressBottomSheetCoordinator* plusAddressBottomSheetCoordinator;
+@property(nonatomic, strong) AutofillEditProfileBottomSheetCoordinator*
+ autofillEditProfileBottomSheetCoordinator;
+
@property(nonatomic, strong) VirtualCardEnrollmentBottomSheetCoordinator*
virtualCardEnrollmentBottomSheetCoordinator;
@@ -1688,7 +1692,11 @@
}
- (void)showEditAddressBottomSheet {
- // TODO(crbug.com/148226): Implement.
+ self.autofillEditProfileBottomSheetCoordinator =
+ [[AutofillEditProfileBottomSheetCoordinator alloc]
+ initWithBaseViewController:self.viewController
+ browser:self.browser];
+ [self.autofillEditProfileBottomSheetCoordinator start];
}
- (void)showAutofillErrorDialog: