blob: 3072f8518ea6d81dd2ba9837e096eb8318cdcb64 [file] [log] [blame]
// Copyright 2018 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/settings/autofill_credit_card_collection_view_controller.h"
#include "base/guid.h"
#include "base/mac/foundation_util.h"
#include "base/strings/utf_string_conversions.h"
#import "base/test/ios/wait_util.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/personal_data_manager.h"
#include "ios/chrome/browser/autofill/personal_data_manager_factory.h"
#include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
#import "ios/chrome/browser/ui/collection_view/collection_view_controller_test.h"
#include "ios/chrome/browser/ui/settings/personal_data_manager_data_changed_observer.h"
#include "ios/web/public/test/test_web_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@interface SettingsRootCollectionViewController (ExposedForTesting)
- (void)editButtonPressed;
@end
namespace {
class AutofillCreditCardCollectionViewControllerTest
: public CollectionViewControllerTest {
protected:
AutofillCreditCardCollectionViewControllerTest() {
TestChromeBrowserState::Builder test_cbs_builder;
chrome_browser_state_ = test_cbs_builder.Build();
// Credit card import requires a PersonalDataManager which itself needs the
// WebDataService; this is not initialized on a TestChromeBrowserState by
// default.
chrome_browser_state_->CreateWebDataService();
}
CollectionViewController* InstantiateController() override {
return [[AutofillCreditCardCollectionViewController alloc]
initWithBrowserState:chrome_browser_state_.get()];
}
void AddCreditCard(const std::string& origin,
const std::string& card_holder_name,
const std::string& card_number) {
autofill::PersonalDataManager* personal_data_manager =
autofill::PersonalDataManagerFactory::GetForBrowserState(
chrome_browser_state_.get());
PersonalDataManagerDataChangedObserver observer(personal_data_manager);
autofill::CreditCard credit_card(base::GenerateGUID(), origin);
credit_card.SetRawInfo(autofill::CREDIT_CARD_NAME_FULL,
base::ASCIIToUTF16(card_holder_name));
credit_card.SetRawInfo(autofill::CREDIT_CARD_NUMBER,
base::ASCIIToUTF16(card_number));
personal_data_manager->OnAcceptedLocalCreditCardSave(credit_card);
observer.Wait(); // Wait for completion of the asynchronous operation.
}
web::TestWebThreadBundle thread_bundle_;
std::unique_ptr<TestChromeBrowserState> chrome_browser_state_;
};
// Default test case of no addresses or credit cards.
TEST_F(AutofillCreditCardCollectionViewControllerTest, TestInitialization) {
CreateController();
CheckController();
// Expect one header section.
EXPECT_EQ(1, NumberOfSections());
// Expect header section to contain one row (the credit card Autofill toggle).
EXPECT_EQ(1, NumberOfItemsInSection(0));
}
// Adding a single credit card results in a credit card section.
TEST_F(AutofillCreditCardCollectionViewControllerTest, TestOneCreditCard) {
AddCreditCard("https://www.example.com/", "John Doe", "378282246310005");
CreateController();
CheckController();
// Expect two sections (header and credit cards section).
EXPECT_EQ(2, NumberOfSections());
// Expect address section to contain one row (the credit card itself).
EXPECT_EQ(1, NumberOfItemsInSection(1));
}
// Deleting the only credit card results in item deletion and section deletion.
TEST_F(AutofillCreditCardCollectionViewControllerTest,
TestOneCreditCardItemDeleted) {
AddCreditCard("https://www.example.com/", "John Doe", "378282246310005");
CreateController();
CheckController();
// Expect two sections (header and credit cards section).
EXPECT_EQ(2, NumberOfSections());
// Expect address section to contain one row (the credit card itself).
EXPECT_EQ(1, NumberOfItemsInSection(1));
AutofillCreditCardCollectionViewController* view_controller =
base::mac::ObjCCastStrict<AutofillCreditCardCollectionViewController>(
controller());
// Put the collectionView in 'edit' mode.
[view_controller editButtonPressed];
// This is a bit of a shortcut, since actually clicking on the 'delete'
// button would be tough.
void (^delete_item_with_wait)(int, int) = ^(int i, int j) {
__block BOOL completion_called = NO;
this->DeleteItem(i, j, ^{
completion_called = YES;
});
EXPECT_TRUE(base::test::ios::WaitUntilConditionOrTimeout(
base::test::ios::kWaitForUIElementTimeout, ^bool() {
return completion_called;
}));
};
autofill::PersonalDataManager* personal_data_manager =
autofill::PersonalDataManagerFactory::GetForBrowserState(
chrome_browser_state_.get());
PersonalDataManagerDataChangedObserver observer(personal_data_manager);
// This call cause a modification of the PersonalDataManager, so wait until
// the asynchronous task complete in addition to waiting for the UI update.
delete_item_with_wait(1, 0);
observer.Wait(); // Wait for completion of the asynchronous operation.
// Exit 'edit' mode.
[view_controller editButtonPressed];
// Expect one header section only.
EXPECT_EQ(1, NumberOfSections());
}
} // namespace