// Copyright 2023 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/settings/autofill/autofill_settings_profile_edit_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/test_personal_data_manager.h"
#import "components/autofill/core/common/autofill_features.h"
#import "ios/chrome/browser/autofill/ui_bundled/autofill_profile_edit_handler.h"
#import "ios/chrome/browser/autofill/ui_bundled/autofill_profile_edit_mediator.h"
#import "ios/chrome/browser/autofill/ui_bundled/autofill_profile_edit_table_view_controller.h"
#import "ios/chrome/browser/autofill/ui_bundled/autofill_ui_type_util.h"
#import "ios/chrome/browser/shared/model/application_context/application_context.h"
#import "ios/chrome/browser/shared/ui/table_view/cells/table_view_header_footer_item.h"
#import "ios/chrome/browser/shared/ui/table_view/cells/table_view_link_header_footer_item.h"
#import "ios/chrome/browser/shared/ui/table_view/cells/table_view_multi_detail_text_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/cells/table_view_text_item.h"
#import "ios/chrome/browser/shared/ui/table_view/legacy_chrome_table_view_controller_test.h"
#import "ios/chrome/browser/shared/ui/table_view/table_view_model.h"
#import "ios/chrome/browser/shared/ui/table_view/table_view_utils.h"
#import "ios/chrome/browser/ui/settings/cells/settings_image_detail_text_item.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 {
const char16_t kTestSyncingEmail[] = u"[email protected]";
class AutofillSettingsProfileEditTableViewControllerTest
: public LegacyChromeTableViewControllerTest {
protected:
void SetUp() override {
LegacyChromeTableViewControllerTest::SetUp();
personal_data_manager_ =
std::make_unique<autofill::TestPersonalDataManager>();
profile_ = std::make_unique<autofill::AutofillProfile>(
autofill::test::GetFullProfile2());
autofill_profile_edit_mediator_ = [[AutofillProfileEditMediator alloc]
initWithDelegate:nil
personalDataManager:personal_data_manager_.get()
autofillProfile:profile_.get()
isMigrationPrompt:NO];
CreateController();
CheckController();
// Reload the model so that the changes are propogated.
[controller() loadModel];
}
LegacyChromeTableViewController* InstantiateController() override {
AutofillSettingsProfileEditTableViewController* viewController =
[[AutofillSettingsProfileEditTableViewController alloc]
initWithDelegate:nil
shouldShowMigrateToAccountButton:NO
userEmail:nil];
autofill_profile_edit_table_view_controller_ =
[[AutofillProfileEditTableViewController alloc]
initWithDelegate:autofill_profile_edit_mediator_
userEmail:nil
controller:viewController
settingsView:YES];
viewController.handler = autofill_profile_edit_table_view_controller_;
autofill_profile_edit_mediator_.consumer =
autofill_profile_edit_table_view_controller_;
return viewController;
}
AutofillProfileEditTableViewController*
autofill_profile_edit_table_view_controller_;
AutofillProfileEditMediator* autofill_profile_edit_mediator_;
std::unique_ptr<autofill::AutofillProfile> profile_;
std::unique_ptr<autofill::TestPersonalDataManager> personal_data_manager_;
id delegate_mock_;
};
// Default test case of no addresses or credit cards.
TEST_F(AutofillSettingsProfileEditTableViewControllerTest, TestInitialization) {
TableViewModel* model = [controller() tableViewModel];
EXPECT_EQ(1, [model numberOfSections]);
EXPECT_EQ(10, [model numberOfItemsInSection:0]);
}
// TODO(crbug.com/40233297): Merge into main test fixture.
class AutofillSettingsProfileEditTableViewControllerTestWithUnionViewEnabled
: public AutofillSettingsProfileEditTableViewControllerTest {
protected:
AutofillSettingsProfileEditTableViewControllerTestWithUnionViewEnabled() {}
LegacyChromeTableViewController* InstantiateController() override {
AutofillSettingsProfileEditTableViewController* viewController =
[[AutofillSettingsProfileEditTableViewController alloc]
initWithDelegate:nil
shouldShowMigrateToAccountButton:NO
userEmail:base::SysUTF16ToNSString(
kTestSyncingEmail)];
autofill_profile_edit_table_view_controller_ =
[[AutofillProfileEditTableViewController alloc]
initWithDelegate:autofill_profile_edit_mediator_
userEmail:base::SysUTF16ToNSString(kTestSyncingEmail)
controller:viewController
settingsView:YES];
viewController.handler = autofill_profile_edit_table_view_controller_;
autofill_profile_edit_mediator_.consumer =
autofill_profile_edit_table_view_controller_;
return viewController;
}
void CreateAccountProfile() {
[autofill_profile_edit_table_view_controller_ setAccountProfile:YES];
// Reload the model so that the changes are propogated.
[controller() loadModel];
}
// Tests the data in the address section.
void TestViewData() {
TableViewModel* model = [controller() tableViewModel];
NSString* countryCode = base::SysUTF16ToNSString(
profile_->GetRawInfo(autofill::FieldType::ADDRESS_HOME_COUNTRY));
std::vector<std::pair<autofill::FieldType, std::u16string>> expected_values;
for (size_t i = 0; i < std::size(kProfileFieldsToDisplay); ++i) {
const AutofillProfileFieldDisplayInfo& field = kProfileFieldsToDisplay[i];
if (!FieldIsUsedInAddress(field.autofillType, countryCode)) {
continue;
}
expected_values.push_back(
{field.autofillType,
profile_->GetInfo(field.autofillType,
GetApplicationContext()->GetApplicationLocale())});
}
EXPECT_EQ(expected_values.size(), (size_t)[model numberOfItemsInSection:0]);
for (size_t row = 0; row < expected_values.size(); row++) {
if (expected_values[row].first == autofill::ADDRESS_HOME_COUNTRY) {
TableViewMultiDetailTextItem* countryCell =
static_cast<TableViewMultiDetailTextItem*>(
GetTableViewItem(0, row));
EXPECT_NSEQ(base::SysUTF16ToNSString(expected_values[row].second),
countryCell.trailingDetailText);
continue;
}
TableViewTextEditItem* cell =
static_cast<TableViewTextEditItem*>(GetTableViewItem(0, row));
EXPECT_NSEQ(base::SysUTF16ToNSString(expected_values[row].second),
cell.textFieldValue);
}
}
};
// Adding an account address results in an address section.
TEST_F(AutofillSettingsProfileEditTableViewControllerTestWithUnionViewEnabled,
TestAccountProfileView) {
CreateAccountProfile();
EXPECT_EQ(2, [[controller() tableViewModel] numberOfSections]);
TestViewData();
}
// Adding an address results in an address section.
TEST_F(AutofillSettingsProfileEditTableViewControllerTestWithUnionViewEnabled,
TestProfileView) {
EXPECT_EQ(1, [[controller() tableViewModel] numberOfSections]);
TestViewData();
}
// Tests the footer text of the view controller for the address profiles with
// source kAccount.
TEST_F(AutofillSettingsProfileEditTableViewControllerTestWithUnionViewEnabled,
TestFooterTextWithEmail) {
CreateAccountProfile();
TableViewModel* model = [controller() tableViewModel];
NSString* expected_footer_text = l10n_util::GetNSStringF(
IDS_IOS_SETTINGS_AUTOFILL_ACCOUNT_ADDRESS_FOOTER_TEXT, kTestSyncingEmail);
TableViewLinkHeaderFooterItem* footer = [model footerForSectionIndex:1];
EXPECT_NSEQ(expected_footer_text, footer.text);
}
class AutofillSettingsProfileEditTableViewControllerWithMigrationButtonTest
: public AutofillSettingsProfileEditTableViewControllerTest {
protected:
LegacyChromeTableViewController* InstantiateController() override {
AutofillSettingsProfileEditTableViewController* viewController =
[[AutofillSettingsProfileEditTableViewController alloc]
initWithDelegate:nil
shouldShowMigrateToAccountButton:YES
userEmail:base::SysUTF16ToNSString(
kTestSyncingEmail)];
autofill_profile_edit_table_view_controller_ =
[[AutofillProfileEditTableViewController alloc]
initWithDelegate:autofill_profile_edit_mediator_
userEmail:base::SysUTF16ToNSString(kTestSyncingEmail)
controller:viewController
settingsView:YES];
viewController.handler = autofill_profile_edit_table_view_controller_;
autofill_profile_edit_mediator_.consumer =
autofill_profile_edit_table_view_controller_;
return viewController;
}
};
// Tests the number of sections and the number of items in the sections.
TEST_F(AutofillSettingsProfileEditTableViewControllerWithMigrationButtonTest,
TestElementsInView) {
TableViewModel* model = [controller() tableViewModel];
int rowCnt = 12;
EXPECT_EQ(1, [model numberOfSections]);
EXPECT_EQ(rowCnt, [model numberOfItemsInSection:0]);
NSString* migrateButtonDescription = l10n_util::GetNSStringF(
IDS_IOS_SETTINGS_AUTOFILL_MIGRATE_ADDRESS_TO_ACCOUNT_BUTTON_DESCRIPTION,
kTestSyncingEmail);
TableViewItem* descriptionItem = GetTableViewItem(0, rowCnt - 2);
EXPECT_NSEQ(
static_cast<SettingsImageDetailTextItem*>(descriptionItem).detailText,
migrateButtonDescription);
EXPECT_NSEQ(
static_cast<TableViewTextItem*>(GetTableViewItem(0, rowCnt - 1)).text,
l10n_util::GetNSString(
IDS_IOS_SETTINGS_AUTOFILL_MIGRATE_ADDRESS_TO_ACCOUNT_BUTTON_TITLE));
}
} // namespace