diff --git a/CHANGELOG.md b/CHANGELOG.md index 433372cdf..304ccf46d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,7 @@ ### Fixed * [EACQAPW-4285] Remove LOOP_CHECKING status in card attachment +* [EACQAPW-5657] Pay by Card email field bugfixes ## [3.1.1] - 2023-07-17Z diff --git a/TinkoffASDKUI/TinkoffASDKUI/Modules/MainForm/Presenter/MainFormPresenter.swift b/TinkoffASDKUI/TinkoffASDKUI/Modules/MainForm/Presenter/MainFormPresenter.swift index 557b16a08..82d0594c0 100644 --- a/TinkoffASDKUI/TinkoffASDKUI/Modules/MainForm/Presenter/MainFormPresenter.swift +++ b/TinkoffASDKUI/TinkoffASDKUI/Modules/MainForm/Presenter/MainFormPresenter.swift @@ -410,10 +410,13 @@ extension MainFormPresenter { return } - let isCvcValid = dataState.hasCards ? savedCardPresenter.isValid : true - let isEmailValid = getReceiptSwitchPresenter.isOn ? emailPresenter.isEmailValid : true - - payButtonPresenter.set(enabled: isCvcValid && isEmailValid) + if dataState.hasCards == false { + payButtonPresenter.set(enabled: true) + } else { + let isCvcValid = savedCardPresenter.isValid + let isEmailValid = getReceiptSwitchPresenter.isOn ? emailPresenter.isEmailValid : true + payButtonPresenter.set(enabled: isCvcValid && isEmailValid) + } } private func startPaymentWithSavedCard() { diff --git a/TinkoffASDKUI/TinkoffASDKUI/UIComponents/EmailView/Presenter/EmailViewPresenter.swift b/TinkoffASDKUI/TinkoffASDKUI/UIComponents/EmailView/Presenter/EmailViewPresenter.swift index 3cb9e68c4..fba23f946 100644 --- a/TinkoffASDKUI/TinkoffASDKUI/UIComponents/EmailView/Presenter/EmailViewPresenter.swift +++ b/TinkoffASDKUI/TinkoffASDKUI/UIComponents/EmailView/Presenter/EmailViewPresenter.swift @@ -81,7 +81,7 @@ extension EmailViewPresenter { } private func viewSetTextFieldHeaderState() { - guard isFieldDidBeginEditing else { + guard isFieldDidBeginEditing || currentEmail.isEmpty == false else { view?.setTextFieldHeaderNormal() return } diff --git a/TinkoffASDKUI/TinkoffASDKUITests/TestCases/CardPaymentPresenter/EmailViewOutputMock.swift b/TinkoffASDKUI/TinkoffASDKUITests/TestCases/CardPaymentPresenter/EmailViewOutputMock.swift index 3f017f2b2..e831b0f14 100644 --- a/TinkoffASDKUI/TinkoffASDKUITests/TestCases/CardPaymentPresenter/EmailViewOutputMock.swift +++ b/TinkoffASDKUI/TinkoffASDKUITests/TestCases/CardPaymentPresenter/EmailViewOutputMock.swift @@ -24,9 +24,18 @@ final class EmailViewOutputMock: IEmailViewOutput { var underlyingCurrentEmail = "" + var isEmailValidGetterCount = 0 + var isEmailValidSetterCount = 0 + var isEmailValid: Bool { - get { return underlyingIsEmailValid } - set(value) { underlyingIsEmailValid = value } + get { + isEmailValidGetterCount += 1 + return underlyingIsEmailValid + } + set(value) { + isEmailValidSetterCount += 1 + underlyingIsEmailValid = value + } } var underlyingIsEmailValid = false diff --git a/TinkoffASDKUI/TinkoffASDKUITests/TestCases/CardPaymentPresenter/SavedCardViewOutputMock.swift b/TinkoffASDKUI/TinkoffASDKUITests/TestCases/CardPaymentPresenter/SavedCardViewOutputMock.swift index 5c24ce528..04b99380c 100644 --- a/TinkoffASDKUI/TinkoffASDKUITests/TestCases/CardPaymentPresenter/SavedCardViewOutputMock.swift +++ b/TinkoffASDKUI/TinkoffASDKUITests/TestCases/CardPaymentPresenter/SavedCardViewOutputMock.swift @@ -18,9 +18,18 @@ final class SavedCardViewOutputMock: ISavedCardViewOutput { var underlyingPresentationState: SavedCardPresentationState = .idle + var isValidGetterCount = 0 + var isValidSetterCount = 0 + var isValid: Bool { - get { return underlyingIsValid } - set(value) { underlyingIsValid = value } + get { + isValidGetterCount += 1 + return underlyingIsValid + } + set(value) { + isValidSetterCount += 1 + underlyingIsValid = value + } } var underlyingIsValid = false diff --git a/TinkoffASDKUI/TinkoffASDKUITests/TestCases/CardPaymentPresenter/SwitchViewOutputMock.swift b/TinkoffASDKUI/TinkoffASDKUITests/TestCases/CardPaymentPresenter/SwitchViewOutputMock.swift index d7811bcc4..605669111 100644 --- a/TinkoffASDKUI/TinkoffASDKUITests/TestCases/CardPaymentPresenter/SwitchViewOutputMock.swift +++ b/TinkoffASDKUI/TinkoffASDKUITests/TestCases/CardPaymentPresenter/SwitchViewOutputMock.swift @@ -10,9 +10,18 @@ final class SwitchViewOutputMock: ISwitchViewOutput { var view: ISwitchViewInput? + var isOnGetterCount = 0 + var isOnSetterCount = 0 + var isOn: Bool { - get { return underlyingIsOn } - set(value) { underlyingIsOn = value } + get { + isOnGetterCount += 1 + return underlyingIsOn + } + set(value) { + isOnSetterCount += 1 + underlyingIsOn = value + } } var underlyingIsOn = false diff --git a/TinkoffASDKUI/TinkoffASDKUITests/TestCases/EmailViewPresenter/EmailViewPresenterTests.swift b/TinkoffASDKUI/TinkoffASDKUITests/TestCases/EmailViewPresenter/EmailViewPresenterTests.swift index 279e19464..abb23192d 100644 --- a/TinkoffASDKUI/TinkoffASDKUITests/TestCases/EmailViewPresenter/EmailViewPresenterTests.swift +++ b/TinkoffASDKUI/TinkoffASDKUITests/TestCases/EmailViewPresenter/EmailViewPresenterTests.swift @@ -208,17 +208,28 @@ final class EmailViewPresenterTests: BaseTestCase { // then XCTAssertFalse(isValidEmail) } + + func test_setsHeaderError_for_invalid_filled_email() { + // given + let email = "EMAIL" + + // when + setupSut(customerEmail: email, resetViewMock: false) + + // then + XCTAssertEqual(viewMock.setTextFieldHeaderErrorCallsCount, 1) + } } // MARK: - Private methods extension EmailViewPresenterTests { - private func setupSut(customerEmail: String = "") { + private func setupSut(customerEmail: String = "", resetViewMock: Bool = true) { viewMock = EmailViewInputMock() outputMock = EmailViewPresenterOutputMock() sut = EmailViewPresenter(customerEmail: customerEmail, output: outputMock) sut.view = viewMock - viewMock.fullReset() + if resetViewMock { viewMock.fullReset() } } } diff --git a/TinkoffASDKUI/TinkoffASDKUITests/TestCases/MainFormPresenter/MainFormPresenterTests.swift b/TinkoffASDKUI/TinkoffASDKUITests/TestCases/MainFormPresenter/MainFormPresenterTests.swift index 750211ace..434f8bcfe 100644 --- a/TinkoffASDKUI/TinkoffASDKUITests/TestCases/MainFormPresenter/MainFormPresenterTests.swift +++ b/TinkoffASDKUI/TinkoffASDKUITests/TestCases/MainFormPresenter/MainFormPresenterTests.swift @@ -158,14 +158,13 @@ final class MainFormPresenterTests: BaseTestCase { XCTAssertEqual(viewMock.hideCommonSheetCallsCount, 1) } - func test_viewDidLoad_when_primaryPaymentMethodCard_success() { + func test_viewDidLoad_when_primaryPaymentMethodCard_no_saved_cards_success() { // given let paymentFlow = PaymentFlow.fake() setupSut(paymentFlow: paymentFlow) - let sbpPaymentMethod = MainFormPaymentMethod.card let dataState = MainFormDataState.fake( - primaryPaymentMethod: sbpPaymentMethod, + primaryPaymentMethod: .card, otherPaymentMethods: [], cards: nil ) @@ -195,11 +194,87 @@ final class MainFormPresenterTests: BaseTestCase { XCTAssertEqual(savedCardMock.updatePresentationStateReceivedArguments, []) XCTAssertEqual(payButtonMock.presentationState, .pay) XCTAssertEqual(payButtonMock.setCallsCount, 1) - XCTAssertEqual(payButtonMock.setReceivedArguments, false) + XCTAssertEqual(payButtonMock.setReceivedArguments, true) XCTAssertEqual(viewMock.reloadDataCallsCount, 1) XCTAssertEqual(viewMock.hideCommonSheetCallsCount, 1) } + func test_main_payment_method_card_no_saved_cards_setEnabled_true() { + // given + let paymentFlow = PaymentFlow.fake() + setupSut(paymentFlow: paymentFlow) + + let dataState = MainFormDataState.fake( + primaryPaymentMethod: .card, + otherPaymentMethods: [], + cards: nil + ) + + dataStateLoaderMock.loadStateCompletionClosureInput = .success(dataState) + + let savedCardMock = SavedCardViewOutputMock() + savedCardMock.presentationState = .selected(card: .fake()) + savedCardViewPresenterAssemblyMock.buildReturnValue = savedCardMock + + let payButtonMock = PayButtonViewOutputMock() + payButtonViewPresenterAssemblyMock.buildReturnValue = payButtonMock + + let switchMock = SwitchViewOutputMock() + switchMock.underlyingIsOn = true + switchViewPresenterAssemblyMock.buildReturnValue = switchMock + + let emailPresenterMock = emailViewPresenterAssemblyMock.buildReturnValue + emailPresenterMock.underlyingIsEmailValid = false + + // when + sut.viewDidLoad() + // then + XCTAssertEqual(payButtonMock.presentationState, .pay) + XCTAssertEqual(payButtonMock.setCallsCount, 1) + XCTAssertEqual(payButtonMock.setReceivedArguments, true) + XCTAssertEqual(savedCardMock.isValidGetterCount, 0) + XCTAssertEqual(switchMock.isOnGetterCount, 1) + XCTAssertEqual(emailPresenterMock.isEmailValidGetterCount, 0) + } + + func test_main_payment_method_card_has_saved_cards_setEnabled() { + // given + let paymentFlow = PaymentFlow.fake() + setupSut(paymentFlow: paymentFlow) + + let dataState = MainFormDataState.fake( + primaryPaymentMethod: .card, + otherPaymentMethods: [], + cards: .fake() + ) + + dataStateLoaderMock.loadStateCompletionClosureInput = .success(dataState) + + let savedCardMock = SavedCardViewOutputMock() + savedCardMock.presentationState = .selected(card: .fake()) + savedCardViewPresenterAssemblyMock.buildReturnValue = savedCardMock + + let payButtonMock = PayButtonViewOutputMock() + payButtonViewPresenterAssemblyMock.buildReturnValue = payButtonMock + + let switchMock = SwitchViewOutputMock() + switchMock.underlyingIsOn = true + switchViewPresenterAssemblyMock.buildReturnValue = switchMock + + let emailPresenterMock = emailViewPresenterAssemblyMock.buildReturnValue + emailPresenterMock.underlyingIsEmailValid = false + + // when + sut.viewDidLoad() + // then + XCTAssertEqual(payButtonMock.presentationState, .pay) + XCTAssertEqual(payButtonMock.setCallsCount, 1) + XCTAssertEqual(payButtonMock.setReceivedArguments, false) + XCTAssertEqual(savedCardMock.isValidGetterCount, 1) + XCTAssertEqual(switchMock.isOnGetterCount, 2) + XCTAssertEqual(emailPresenterMock.isEmailValidGetterCount, 1) + } + func test_viewDidLoad_when_primaryPaymentMethodCard_failure() { // given let paymentFlow = PaymentFlow.fake()