Skip to content

Commit

Permalink
Correctly persist selected phone country in address element (#1494)
Browse files Browse the repository at this point in the history
* Correctly persist selected phone country

* update test

* Allow country to be automatically updated several times

* Add tests for PhoneNumberElement.selectCountry

* Fix tests

* Slim down UI test
  • Loading branch information
porter-stripe authored Oct 12, 2022
1 parent f784a18 commit 498de94
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -263,4 +263,23 @@ class PaymentSheet_AddressTests: XCTestCase {
XCTAssertEqual(app.textFields["Country or region"].value as? String, "United States")
XCTAssertEqual(app.textFields["ZIP"].value as? String, "94102")
}

func testManualAddressEntry_phoneCountryDoesPersist() throws {
loadPlayground(app, settings: [:])
let shippingButton = app.buttons["Shipping address"]
XCTAssertTrue(shippingButton.waitForExistence(timeout: 4.0))
shippingButton.tap()

// The Save Address button should be disabled
let saveAddressButton = app.buttons["Save address"]
XCTAssertFalse(saveAddressButton.isEnabled)

// Select UK for phone number country
app.textFields["United States +1"].tap()
app.pickerWheels.firstMatch.adjust(toPickerWheelValue: "🇬🇧 United Kingdom +44")
app.toolbars.buttons["Done"].tap()

// Ensure UK is persisted as phone country after tapping done
XCTAssert(app.textFields["United Kingdom +44"].exists)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -384,11 +384,14 @@ extension AddressSectionElement: ElementDelegate {
}
delegate?.didUpdate(element: self)

// Update the selected country in the phone element if the text is empty
// Update the selected country in the phone element if the no defaults have been provided
// and the phone number element hasn't been modified
// to match the country picker if they don't match
if let phone = phone, phone.textFieldElement.text.isEmpty
if let phone = phone,
defaults.phone == nil,
!phone.hasBeenModified
&& phone.countryDropdownElement.selectedIndex != country.selectedIndex {
phone.countryDropdownElement.select(index: country.selectedIndex)
phone.selectCountry(index: country.selectedIndex, shouldUpdateDefaultNumber: true)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ import UIKit
return PhoneNumber(number: textFieldElement.text, countryCode: countryDropdownElement.selectedItem.rawData)
}

public var hasBeenModified: Bool {
return defaultPhoneNumber?.number != phoneNumber?.number ||
defaultPhoneNumber?.countryCode != phoneNumber?.countryCode
}

// MARK: - Private properties
private var defaultPhoneNumber: PhoneNumber?

// MARK: - Initializer
/**
Creates an address section with a country dropdown populated from the given list of countryCodes.
Expand Down Expand Up @@ -68,6 +76,7 @@ import UIKit
return countryDropdownElement.selectedItem.rawData
}
).makeElement(theme: theme)
self.defaultPhoneNumber = phoneNumber
self.countryDropdownElement.delegate = self
self.textFieldElement.delegate = self
}
Expand Down Expand Up @@ -107,6 +116,14 @@ import UIKit
return (countryCode, phoneNumber)
}
}

func selectCountry(index: Int, shouldUpdateDefaultNumber: Bool = false) {
countryDropdownElement.select(index: index)

if shouldUpdateDefaultNumber {
self.defaultPhoneNumber = phoneNumber
}
}
}

// MARK: - DropdownFieldElement helper
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,5 @@ class AddressSectionElementTest: XCTestCase {
sut.phone?.textFieldElement.setText("555")
sut.country.select(index: 0)
XCTAssertNotEqual(sut.country.selectedIndex, sut.phone?.countryDropdownElement.selectedIndex)

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,85 @@ class PhoneNumberElementTests: XCTestCase {
XCTAssertEqual(sut.phoneNumber?.number, "441234567890")
}

func test_hasBeenModified_noDefaults_noModification() {
let sut = PhoneNumberElement(
allowedCountryCodes: ["US"],
locale: Locale(identifier: "en_US")
)
XCTAssertFalse(sut.hasBeenModified)
}

func test_hasBeenModified_defaultNumber() {
let sut = PhoneNumberElement(
allowedCountryCodes: ["US"],
defaultPhoneNumber: "3105551234",
locale: Locale(identifier: "en_US")
)
XCTAssertFalse(sut.hasBeenModified)
}

func test_hasBeenModified_isModified() {
let sut = PhoneNumberElement(
allowedCountryCodes: ["US"],
locale: Locale(identifier: "en_US")
)
simulateAutofill(sut, autofilledPhoneNumber: "3")
XCTAssertTrue(sut.hasBeenModified)
}

func test_hasBeenModified_defaultNumber_isModified() {
let sut = PhoneNumberElement(
allowedCountryCodes: ["US"],
defaultPhoneNumber: "3105551234",
locale: Locale(identifier: "en_US")
)
simulateAutofill(sut, autofilledPhoneNumber: "3")
XCTAssertTrue(sut.hasBeenModified)
}

func test_hasBeenModified_isNotModified() {
let sut = PhoneNumberElement(
allowedCountryCodes: ["US"],
locale: Locale(identifier: "en_US")
)
simulateAutofill(sut, autofilledPhoneNumber: "3")
simulateAutofill(sut, autofilledPhoneNumber: "")
XCTAssertFalse(sut.hasBeenModified)
}

func test_hasBeenModified_defaultNumber_isNotModified() {
let sut = PhoneNumberElement(
allowedCountryCodes: ["US"],
defaultPhoneNumber: "3105551234",
locale: Locale(identifier: "en_US")
)
simulateAutofill(sut, autofilledPhoneNumber: "3")
simulateAutofill(sut, autofilledPhoneNumber: "3105551234")
XCTAssertFalse(sut.hasBeenModified)
}

func test_selectCountry_dontUpdateDefault() {
let sut = PhoneNumberElement(
allowedCountryCodes: ["US", "CA"],
locale: Locale(identifier: "en_US")
)

sut.selectCountry(index: 0, shouldUpdateDefaultNumber: false) // select CA
XCTAssertEqual(sut.countryDropdownElement.selectedIndex, 0)
XCTAssert(sut.hasBeenModified)
}

func test_selectCountry_updateDefault() {
let sut = PhoneNumberElement(
allowedCountryCodes: ["US", "CA"],
locale: Locale(identifier: "en_US")
)

sut.selectCountry(index: 0, shouldUpdateDefaultNumber: true) // select CA
XCTAssertEqual(sut.countryDropdownElement.selectedIndex, 0)
XCTAssertFalse(sut.hasBeenModified)
}

private func simulateAutofill(_ sut: PhoneNumberElement, autofilledPhoneNumber: String) {
let textField = sut.textFieldElement.textFieldView.textField
_ = sut.textFieldElement.textFieldView.textField(textField, shouldChangeCharactersIn: NSRange(location: 0, length: 0), replacementString: autofilledPhoneNumber)
Expand Down

0 comments on commit 498de94

Please sign in to comment.