From 805bdb6478715eb796b292f97ef398440636a7c4 Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Mon, 28 Oct 2024 11:35:44 +0100 Subject: [PATCH] COIOS-811: Expiry date sanitization fix (#1875) # Summary - Fixed a bug where the expiry date field ended up in an invalid state when trying to add additional characters to the textfield ### What steps will reproduce the problem? 1. Enter an expiry date 03 / 30 (It jumps to the next field CVC) 2. Go back into the expiry date field and add another character e.g. 5 ### What is the expected result? - The character is ignored (sanitized out) ### What happens instead? - It does not show it in the UI but the value of the item is now 03305 and errors out but there is no visual indicator why # Release notes In the **Expiry date** field, when the shopper tries to enter additional characters to the field after having already entered characters in it, the field no longer ends up in an invalid state. # Ticket COIOS-811 --------- Co-authored-by: Alex Guretzki --- AdyenCard/Form/FormCardNumberItem.swift | 2 +- AdyenCard/Formatters/CardExpiryDateFormatter.swift | 6 +++++- .../Formatters/CardExpiryDateFormatterTests.swift | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/AdyenCard/Form/FormCardNumberItem.swift b/AdyenCard/Form/FormCardNumberItem.swift index f10842ed1c..38cff928a2 100644 --- a/AdyenCard/Form/FormCardNumberItem.swift +++ b/AdyenCard/Form/FormCardNumberItem.swift @@ -133,7 +133,7 @@ internal final class FormCardNumberItem: FormTextItem, AdyenObserver { let isAdding = formattedText.count > text.count let oldNumberOfSpacesBeforeCursor = text.numberOfSpaces(beforeOffset: oldCursorOffset) - + let projectedNewCursorOffset = oldCursorOffset + replacementLength + (isAdding ? 1 : 0) let newNumberOfSpacesBeforeCursor = formattedText.numberOfSpaces( beforeOffset: projectedNewCursorOffset diff --git a/AdyenCard/Formatters/CardExpiryDateFormatter.swift b/AdyenCard/Formatters/CardExpiryDateFormatter.swift index 3f81649c16..94c7b81529 100644 --- a/AdyenCard/Formatters/CardExpiryDateFormatter.swift +++ b/AdyenCard/Formatters/CardExpiryDateFormatter.swift @@ -11,10 +11,14 @@ import Foundation /// The input is expected to be sanitized as "MMYY", which will result in "MM / YY". public final class CardExpiryDateFormatter: NumericFormatter { + override public func sanitizedValue(for value: String) -> String { + super.sanitizedValue(for: value).adyen.truncate(to: maxLength) + } + override public func formattedValue(for value: String) -> String { let separator = " / " - let sanitizedString = sanitizedValue(for: value).adyen.truncate(to: maxLength) + let sanitizedString = sanitizedValue(for: value) var formattedDate = sanitizedString var month = 0 diff --git a/Tests/IntegrationTests/Card Tests/Formatters/CardExpiryDateFormatterTests.swift b/Tests/IntegrationTests/Card Tests/Formatters/CardExpiryDateFormatterTests.swift index 712932389f..1b10dfa1c0 100644 --- a/Tests/IntegrationTests/Card Tests/Formatters/CardExpiryDateFormatterTests.swift +++ b/Tests/IntegrationTests/Card Tests/Formatters/CardExpiryDateFormatterTests.swift @@ -75,6 +75,7 @@ class CardExpiryDateFormatterTests: XCTestCase { XCTAssertEqual(sut.sanitizedValue(for: "09 / "), "09") XCTAssertEqual(sut.sanitizedValue(for: "10 / 1"), "101") XCTAssertEqual(sut.sanitizedValue(for: "09 / 21"), "0921") + XCTAssertEqual(sut.sanitizedValue(for: "09 / 213"), "0921") } func testNonDecimalDigitSanitizing() {