From 8d25e1b1719ca50c5bdf76513a73213159f66014 Mon Sep 17 00:00:00 2001 From: Corinna Hillebrand Date: Tue, 17 Sep 2024 14:16:38 +0200 Subject: [PATCH] Fix some tests and clean up code - remove unused statements in the code - fix warning in test setup - fix scroll tests - fix tests around error summary https://phabricator.wikimedia.org/T368525 --- .../usePersonalDataSectionEventHandlers.ts | 10 ++++- .../PersonalDataSection.vue | 1 - .../PersonalDataSectionDonationReceipt.vue | 1 - .../SinglePageErrorSummary.vue | 1 + .../usePersonalDataSectionEventHandlers.ts | 15 ++++++-- .../single_page_form/DonationForm.spec.ts | 2 +- .../PersonalDataSection.spec.ts | 26 ++++++------- ...PersonalDataSectionDonationReceipt.spec.ts | 16 ++++---- ...nDonationReceiptStreetAutoComplete.spec.ts | 32 ++++++++-------- ...sonalDataSectionStreetAutoComplete.spec.ts | 37 +++++++++++++------ 10 files changed, 86 insertions(+), 55 deletions(-) diff --git a/src/components/pages/donation_form/DonationReceipt/usePersonalDataSectionEventHandlers.ts b/src/components/pages/donation_form/DonationReceipt/usePersonalDataSectionEventHandlers.ts index 6216afa00..958814e6c 100644 --- a/src/components/pages/donation_form/DonationReceipt/usePersonalDataSectionEventHandlers.ts +++ b/src/components/pages/donation_form/DonationReceipt/usePersonalDataSectionEventHandlers.ts @@ -2,7 +2,8 @@ import { Store } from 'vuex'; import { action } from '@src/store/util'; import { AddressTypeModel } from '@src/view_models/AddressTypeModel'; import { waitForServerValidationToFinish } from '@src/util/wait_for_server_validation'; -import { computed, ComputedRef, ref, Ref } from 'vue'; +import { computed, ComputedRef, ref, Ref, watch } from 'vue'; +import { Validity } from '@src/view_models/Validity'; type ReturnType = { submit: () => Promise, @@ -81,6 +82,13 @@ export function usePersonalDataSectionEventHandlers( } } ); + watch( () => store.state.payment.values.type, ( newType: string ) => { + if ( newType !== 'BEZ' ) { + bankDataIsValid.value = true; + store.dispatch( action( 'bankdata', 'setBankDataValidity' ), Validity.VALID ); + } + } ); + return { submit, submitValuesForm, diff --git a/src/components/pages/donation_form/singlePageFormSections/PersonalDataSection.vue b/src/components/pages/donation_form/singlePageFormSections/PersonalDataSection.vue index c0a0debda..69a81ee4f 100644 --- a/src/components/pages/donation_form/singlePageFormSections/PersonalDataSection.vue +++ b/src/components/pages/donation_form/singlePageFormSections/PersonalDataSection.vue @@ -131,7 +131,6 @@ const props = defineProps(); const campaignParams = inject( QUERY_STRING_INJECTION_KEY, '' ); const isFullSelected = ref( false ); const store = useStore(); -defineExpose( { focus: (): void => pageRef.value.focus() } ); const setFullSelected = ( selected: boolean ) => { isFullSelected.value = selected; diff --git a/src/components/pages/donation_form/singlePageFormSections/PersonalDataSectionDonationReceipt.vue b/src/components/pages/donation_form/singlePageFormSections/PersonalDataSectionDonationReceipt.vue index 3ef7d2073..8a0fc35aa 100644 --- a/src/components/pages/donation_form/singlePageFormSections/PersonalDataSectionDonationReceipt.vue +++ b/src/components/pages/donation_form/singlePageFormSections/PersonalDataSectionDonationReceipt.vue @@ -199,7 +199,6 @@ const { addressSummary, inlineSummaryLanguageItem } = useAddressSummary( store ) const mailingList = useMailingListModel( store ); const { receiptNeeded, showReceiptOptionError } = useReceiptModel( store ); const countryWasRestored = ref( false ); -defineExpose( { focus: (): void => pageRef.value.focus() } ); const scrollToPaymentSection = () => { const scrollIntoViewElement = document.getElementById( 'donation-page-form-section-payment' ); if ( scrollIntoViewElement ) { diff --git a/src/components/pages/donation_form/singlePageFormSections/SinglePageErrorSummary.vue b/src/components/pages/donation_form/singlePageFormSections/SinglePageErrorSummary.vue index 5911fdefb..a4fff5b7a 100644 --- a/src/components/pages/donation_form/singlePageFormSections/SinglePageErrorSummary.vue +++ b/src/components/pages/donation_form/singlePageFormSections/SinglePageErrorSummary.vue @@ -216,6 +216,7 @@ import { computed } from 'vue'; interface Props { showErrorSummary: boolean; addressType: AddressTypeModel; + receiptNeeded?: boolean; } defineProps(); diff --git a/src/components/pages/donation_form/usePersonalDataSectionEventHandlers.ts b/src/components/pages/donation_form/usePersonalDataSectionEventHandlers.ts index e0b04a828..666202d5d 100644 --- a/src/components/pages/donation_form/usePersonalDataSectionEventHandlers.ts +++ b/src/components/pages/donation_form/usePersonalDataSectionEventHandlers.ts @@ -4,7 +4,8 @@ import { action } from '@src/store/util'; import { AddressTypeModel } from '@src/view_models/AddressTypeModel'; import { waitForServerValidationToFinish } from '@src/util/wait_for_server_validation'; import { AddressTypeIds } from '@src/components/pages/donation_form/AddressTypeIds'; -import { computed, ComputedRef, ref, Ref } from 'vue'; +import { computed, ComputedRef, ref, Ref, watch } from 'vue'; +import { Validity } from '@src/view_models/Validity'; const trackFormSubmissionForAddressType = ( addressType: AddressTypeModel ) => { if ( addressType === AddressTypeModel.ANON ) { @@ -60,16 +61,17 @@ export function usePersonalDataSectionEventHandlers( if ( !store.getters[ 'address/requiredFieldsAreValid' ] ) { addressDataIsValid.value = false; - return; } if ( isDirectDebit.value && !store.getters[ 'bankdata/bankDataIsValid' ] ) { bankDataIsValid.value = false; - return; } if ( !store.getters[ 'payment/paymentDataIsValid' ] ) { paymentDataIsValid.value = false; + } + + if ( !addressDataIsValid.value || !bankDataIsValid.value || !paymentDataIsValid.value ) { return; } @@ -97,6 +99,13 @@ export function usePersonalDataSectionEventHandlers( } } ); + watch( () => store.state.payment.values.type, ( newType: string ) => { + if ( newType !== 'BEZ' ) { + bankDataIsValid.value = true; + store.dispatch( action( 'bankdata', 'setBankDataValidity' ), Validity.VALID ); + } + } ); + return { submit, submitValuesForm, diff --git a/tests/unit/components/pages/donation_form/single_page_form/DonationForm.spec.ts b/tests/unit/components/pages/donation_form/single_page_form/DonationForm.spec.ts index c7530158c..16a44dcd9 100644 --- a/tests/unit/components/pages/donation_form/single_page_form/DonationForm.spec.ts +++ b/tests/unit/components/pages/donation_form/single_page_form/DonationForm.spec.ts @@ -37,7 +37,7 @@ describe( 'DonationForm.vue', () => { validateBankDataUrl: '', validateLegacyBankDataUrl: '', salutations: [], - addressValidationPatterns: {} as AddressValidation, + addressValidationPatterns: { postcode: '' } as AddressValidation, usesContentCards: true, }, global: { diff --git a/tests/unit/components/pages/donation_form/single_page_form/PersonalDataSection.spec.ts b/tests/unit/components/pages/donation_form/single_page_form/PersonalDataSection.spec.ts index 1c8c86cf2..eaa248844 100644 --- a/tests/unit/components/pages/donation_form/single_page_form/PersonalDataSection.spec.ts +++ b/tests/unit/components/pages/donation_form/single_page_form/PersonalDataSection.spec.ts @@ -1,7 +1,6 @@ import { flushPromises, mount, VueWrapper } from '@vue/test-utils'; import axios from 'axios'; -import PersonalDataSection from '@src/components/pages/donation_form/singlePageFormSections/PersonalDataSection.vue'; import { createStore } from '@src/store/donation_store'; import { action } from '@src/store/util'; import { AddressTypeModel } from '@src/view_models/AddressTypeModel'; @@ -14,6 +13,7 @@ import { nextTick } from 'vue'; import AddressTypeBasic from '@src/components/pages/donation_form/AddressTypeBasic.vue'; import { Validity } from '@src/view_models/Validity'; import { Salutation } from '@src/view_models/Salutation'; +import PersonalDataSection from '@src/components/pages/donation_form/singlePageFormSections/PersonalDataSection.vue'; import { FakeBankValidationResource } from '@test/unit/TestDoubles/FakeBankValidationResource'; import BankFields from '@src/components/shared/BankFields.vue'; @@ -72,7 +72,7 @@ describe( 'PersonalDataSection.vue', () => { return { wrapper, store }; }; - const setPaymentType = ( store: Store, paymentType: string ): Promise => { + const setPaymentTypeAndInitializeOtherPaymentValues = ( store: Store, paymentType: string ): Promise => { return store.dispatch( action( 'payment', 'initializePayment' ), { allowedIntervals: [ 0 ], allowedPaymentTypes: [ paymentType ], @@ -90,7 +90,7 @@ describe( 'PersonalDataSection.vue', () => { expect( wrapper.findComponent( BankFields ).exists() ).toBeFalsy(); - await setPaymentType( store, 'BEZ' ); + await setPaymentTypeAndInitializeOtherPaymentValues( store, 'BEZ' ); expect( wrapper.findComponent( BankFields ).exists() ).toBeTruthy(); } ); @@ -98,11 +98,11 @@ describe( 'PersonalDataSection.vue', () => { it( 'hides bank data fields if payment type is not direct debit', async () => { const { wrapper, store } = getWrapper(); - await setPaymentType( store, 'BEZ' ); + await setPaymentTypeAndInitializeOtherPaymentValues( store, 'BEZ' ); expect( wrapper.findComponent( BankFields ).exists() ).toBeTruthy(); - await setPaymentType( store, 'UEB' ); + await setPaymentTypeAndInitializeOtherPaymentValues( store, 'UEB' ); expect( wrapper.findComponent( BankFields ).exists() ).toBeFalsy(); } ); @@ -121,13 +121,13 @@ describe( 'PersonalDataSection.vue', () => { it( 'scrolls to payment section when button for changing payment data is clicked', async () => { const scrollElement = { scrollIntoView: jest.fn() }; + Object.defineProperty( document, 'getElementById', { writable: true, configurable: true, value: () => scrollElement } ); + const { wrapper } = getWrapper(); await wrapper.find( '#previous-btn' ).trigger( 'click' ); - await nextTick(); - // TODO test that payment section got scrolled to - expect( scrollElement.scrollIntoView ).toHaveBeenCalledTimes( 1 ); + expect( scrollElement.scrollIntoView ).toHaveBeenCalledWith( { behavior: 'smooth' } ); } ); it( 'shows and hides the error summary', async () => { @@ -135,14 +135,14 @@ describe( 'PersonalDataSection.vue', () => { const { wrapper, store } = getWrapper(); + await setPaymentTypeAndInitializeOtherPaymentValues( store, 'UEB' ); + await wrapper.find( '#submit-btn' ).trigger( 'click' ); await nextTick(); await nextTick(); expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); - await setPaymentType( store, 'UEB' ); - await wrapper.find( '#addressType-0' ).trigger( 'change' ); await wrapper.find( '#person-salutation-0' ).trigger( 'change' ); @@ -179,7 +179,7 @@ describe( 'PersonalDataSection.vue', () => { const { wrapper, store } = getWrapper(); - await setPaymentType( store, 'BEZ' ); + await setPaymentTypeAndInitializeOtherPaymentValues( store, 'BEZ' ); await wrapper.find( '#submit-btn' ).trigger( 'click' ); await nextTick(); @@ -234,7 +234,7 @@ describe( 'PersonalDataSection.vue', () => { const { wrapper, store } = getWrapper(); - await setPaymentType( store, 'BEZ' ); + await setPaymentTypeAndInitializeOtherPaymentValues( store, 'BEZ' ); if ( addressTypeSelector !== '' ) { await wrapper.find( addressTypeSelector ).trigger( 'change' ); @@ -282,7 +282,7 @@ describe( 'PersonalDataSection.vue', () => { it( 'submits the form', async () => { const store = createStore(); - await setPaymentType( store, 'UEB' ); + await setPaymentTypeAndInitializeOtherPaymentValues( store, 'UEB' ); await store.dispatch( action( 'address', 'initializeAddress' ), { addressType: AddressTypeModel.ANON, newsletter: true, diff --git a/tests/unit/components/pages/donation_form/single_page_form/PersonalDataSectionDonationReceipt.spec.ts b/tests/unit/components/pages/donation_form/single_page_form/PersonalDataSectionDonationReceipt.spec.ts index 7ae8a5746..f94c61e60 100644 --- a/tests/unit/components/pages/donation_form/single_page_form/PersonalDataSectionDonationReceipt.spec.ts +++ b/tests/unit/components/pages/donation_form/single_page_form/PersonalDataSectionDonationReceipt.spec.ts @@ -44,8 +44,8 @@ describe( 'PersonalDataSectionDonationReceipt.vue', () => { const wrapper = mount( PersonalDataSectionDonationReceipt, { props: { assetsPath: '', - validateAddressUrl: 'https://localhost:8082', - validateEmailUrl: 'https://localhost:8082', + validateAddressUrl: '', + validateEmailUrl: '', validateBankDataUrl: 'https://localhost:8082', validateLegacyBankDataUrl: 'https://localhost:8082', countries: [ testCountry ], @@ -108,26 +108,26 @@ describe( 'PersonalDataSectionDonationReceipt.vue', () => { it( 'scrolls to payment section when button for changing payment data is clicked', async () => { const scrollElement = { scrollIntoView: jest.fn() }; + Object.defineProperty( document, 'getElementById', { writable: true, configurable: true, value: () => scrollElement } ); + const { wrapper } = getWrapper(); await wrapper.find( '#previous-btn' ).trigger( 'click' ); - await nextTick(); - // TODO test that payment section got scrolled to - expect( scrollElement.scrollIntoView ).toHaveBeenCalled(); + expect( scrollElement.scrollIntoView ).toHaveBeenCalledWith( { behavior: 'smooth' } ); } ); it( 'shows and hides the error summary', async () => { const { wrapper, store } = getWrapper(); + await setPaymentType( store, 'UEB' ); + await wrapper.find( '#donation-form' ).trigger( 'submit' ); await nextTick(); await nextTick(); expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); - await setPaymentType( store, 'UEB' ); - await wrapper.find( '#donationReceipt-0' ).trigger( 'change' ); await wrapper.find( '#addressType-0' ).trigger( 'change' ); await wrapper.find( '#salutation-0' ).trigger( 'change' ); @@ -323,7 +323,7 @@ describe( 'PersonalDataSectionDonationReceipt.vue', () => { const { wrapper, store } = getWrapper(); store.dispatch = jest.fn().mockResolvedValue( true ); - await wrapper.find( '#submit-btn' ).trigger( 'click' ); + await wrapper.find( '#donation-form' ).trigger( 'submit' ); expect( store.dispatch ).toHaveBeenCalledWith( action( 'payment', 'markEmptyValuesAsInvalid' ) ); } ); diff --git a/tests/unit/components/pages/donation_form/single_page_form/PersonalDataSectionDonationReceiptStreetAutoComplete.spec.ts b/tests/unit/components/pages/donation_form/single_page_form/PersonalDataSectionDonationReceiptStreetAutoComplete.spec.ts index b275fd0fe..1506f1c9d 100644 --- a/tests/unit/components/pages/donation_form/single_page_form/PersonalDataSectionDonationReceiptStreetAutoComplete.spec.ts +++ b/tests/unit/components/pages/donation_form/single_page_form/PersonalDataSectionDonationReceiptStreetAutoComplete.spec.ts @@ -74,7 +74,7 @@ describe( 'PersonalDataSectionDonationReceipt.vue (With Street Autocomplete)', ( return { wrapper, store }; }; - const setPaymentType = ( store: Store, paymentType: string ): Promise => { + const setPaymentTypeAndInitializeOtherPaymentValues = ( store: Store, paymentType: string ): Promise => { return store.dispatch( action( 'payment', 'initializePayment' ), { allowedIntervals: [ 0 ], allowedPaymentTypes: [ paymentType ], @@ -92,7 +92,7 @@ describe( 'PersonalDataSectionDonationReceipt.vue (With Street Autocomplete)', ( expect( wrapper.findComponent( BankFields ).exists() ).toBeFalsy(); - await setPaymentType( store, 'BEZ' ); + await setPaymentTypeAndInitializeOtherPaymentValues( store, 'BEZ' ); expect( wrapper.findComponent( BankFields ).exists() ).toBeTruthy(); } ); @@ -100,37 +100,37 @@ describe( 'PersonalDataSectionDonationReceipt.vue (With Street Autocomplete)', ( it( 'hides bank data fields if payment type is not direct debit', async () => { const { wrapper, store } = getWrapper(); - await setPaymentType( store, 'BEZ' ); + await setPaymentTypeAndInitializeOtherPaymentValues( store, 'BEZ' ); expect( wrapper.findComponent( BankFields ).exists() ).toBeTruthy(); - await setPaymentType( store, 'UEB' ); + await setPaymentTypeAndInitializeOtherPaymentValues( store, 'UEB' ); expect( wrapper.findComponent( BankFields ).exists() ).toBeFalsy(); } ); it( 'scrolls to payment section when button for changing payment data is clicked', async () => { const scrollElement = { scrollIntoView: jest.fn() }; + Object.defineProperty( document, 'getElementById', { writable: true, configurable: true, value: () => scrollElement } ); + const { wrapper } = getWrapper(); await wrapper.find( '#previous-btn' ).trigger( 'click' ); - await nextTick(); - // TODO test that payment section got scrolled to - expect( scrollElement.scrollIntoView ).toHaveBeenCalled(); + expect( scrollElement.scrollIntoView ).toHaveBeenCalledWith( { behavior: 'smooth' } ); } ); it( 'shows and hides the error summary', async () => { const { wrapper, store } = getWrapper(); + await setPaymentTypeAndInitializeOtherPaymentValues( store, 'UEB' ); + await wrapper.find( '#donation-form' ).trigger( 'submit' ); await nextTick(); await nextTick(); expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); - await setPaymentType( store, 'UEB' ); - await wrapper.find( '#donationReceipt-0' ).trigger( 'change' ); await wrapper.find( '#addressType-0' ).trigger( 'change' ); await wrapper.find( '#salutation-0' ).trigger( 'change' ); @@ -164,7 +164,7 @@ describe( 'PersonalDataSectionDonationReceipt.vue (With Street Autocomplete)', ( const { wrapper, store } = getWrapper(); - await setPaymentType( store, 'BEZ' ); + await setPaymentTypeAndInitializeOtherPaymentValues( store, 'BEZ' ); await wrapper.find( '#donation-form' ).trigger( 'submit' ); await nextTick(); @@ -214,7 +214,7 @@ describe( 'PersonalDataSectionDonationReceipt.vue (With Street Autocomplete)', ( it( 'handles all error summary clicks when no donation receipt has been selected', async () => { const { wrapper, store } = getWrapper(); - await setPaymentType( store, 'BEZ' ); + await setPaymentTypeAndInitializeOtherPaymentValues( store, 'BEZ' ); await wrapper.find( '#donation-form' ).trigger( 'submit' ); await nextTick(); @@ -235,7 +235,7 @@ describe( 'PersonalDataSectionDonationReceipt.vue (With Street Autocomplete)', ( const { wrapper, store } = getWrapper(); - await setPaymentType( store, 'BEZ' ); + await setPaymentTypeAndInitializeOtherPaymentValues( store, 'BEZ' ); await wrapper.find( '#donationReceipt-0' ).trigger( 'change' ); @@ -265,7 +265,7 @@ describe( 'PersonalDataSectionDonationReceipt.vue (With Street Autocomplete)', ( const { wrapper, store } = getWrapper(); - await setPaymentType( store, 'BEZ' ); + await setPaymentTypeAndInitializeOtherPaymentValues( store, 'BEZ' ); await wrapper.find( '#donationReceipt-0' ).trigger( 'change' ); await wrapper.find( '#addressType-0' ).trigger( 'change' ); @@ -296,7 +296,7 @@ describe( 'PersonalDataSectionDonationReceipt.vue (With Street Autocomplete)', ( const { wrapper, store } = getWrapper(); - await setPaymentType( store, 'BEZ' ); + await setPaymentTypeAndInitializeOtherPaymentValues( store, 'BEZ' ); await wrapper.find( '#donationReceipt-0' ).trigger( 'change' ); @@ -326,14 +326,14 @@ describe( 'PersonalDataSectionDonationReceipt.vue (With Street Autocomplete)', ( const { wrapper, store } = getWrapper(); store.dispatch = jest.fn().mockResolvedValue( true ); - await wrapper.find( '#submit-btn' ).trigger( 'click' ); + await wrapper.find( '#donation-form' ).trigger( 'submit' ); expect( store.dispatch ).toHaveBeenCalledWith( action( 'payment', 'markEmptyValuesAsInvalid' ) ); } ); it( 'submits the form', async () => { const store = createStore(); - await setPaymentType( store, 'UEB' ); + await setPaymentTypeAndInitializeOtherPaymentValues( store, 'UEB' ); await store.dispatch( action( 'address', 'initializeAddress' ), { addressType: AddressTypeModel.PERSON, newsletter: true, diff --git a/tests/unit/components/pages/donation_form/single_page_form/PersonalDataSectionStreetAutoComplete.spec.ts b/tests/unit/components/pages/donation_form/single_page_form/PersonalDataSectionStreetAutoComplete.spec.ts index e7b30d87e..b7bc98804 100644 --- a/tests/unit/components/pages/donation_form/single_page_form/PersonalDataSectionStreetAutoComplete.spec.ts +++ b/tests/unit/components/pages/donation_form/single_page_form/PersonalDataSectionStreetAutoComplete.spec.ts @@ -47,8 +47,8 @@ describe( 'PersonalDataSection.vue (With Street Autocomplete)', () => { assetsPath: '', validateAddressUrl: '', validateEmailUrl: '', - validateBankDataUrl: 'https://localhost:8082', - validateLegacyBankDataUrl: 'https://localhost:8082', + validateBankDataUrl: '', + validateLegacyBankDataUrl: '', countries: [ testCountry ], salutations, trackingData: {} as TrackingData, @@ -75,7 +75,7 @@ describe( 'PersonalDataSection.vue (With Street Autocomplete)', () => { return { wrapper, store }; }; - const setPaymentType = ( store: Store, paymentType: string ): Promise => { + const setPaymentTypeAndInitializeOtherPaymentValues = ( store: Store, paymentType: string ): Promise => { return store.dispatch( action( 'payment', 'initializePayment' ), { allowedIntervals: [ 0 ], allowedPaymentTypes: [ paymentType ], @@ -93,7 +93,7 @@ describe( 'PersonalDataSection.vue (With Street Autocomplete)', () => { expect( wrapper.findComponent( BankFields ).exists() ).toBeFalsy(); - await setPaymentType( store, 'BEZ' ); + await setPaymentTypeAndInitializeOtherPaymentValues( store, 'BEZ' ); expect( wrapper.findComponent( BankFields ).exists() ).toBeTruthy(); } ); @@ -101,11 +101,11 @@ describe( 'PersonalDataSection.vue (With Street Autocomplete)', () => { it( 'hides bank data fields if payment type is not direct debit', async () => { const { wrapper, store } = getWrapper(); - await setPaymentType( store, 'BEZ' ); + await setPaymentTypeAndInitializeOtherPaymentValues( store, 'BEZ' ); expect( wrapper.findComponent( BankFields ).exists() ).toBeTruthy(); - await setPaymentType( store, 'UEB' ); + await setPaymentTypeAndInitializeOtherPaymentValues( store, 'UEB' ); expect( wrapper.findComponent( BankFields ).exists() ).toBeFalsy(); } ); @@ -122,18 +122,23 @@ describe( 'PersonalDataSection.vue (With Street Autocomplete)', () => { expect( store.dispatch ).toBeCalledWith( expectedAction, expectedPayload ); } ); - it( 'emits previous event', async () => { + it( 'scrolls to top when the donor clicks the previous button', async () => { + const scrollElement = { scrollIntoView: jest.fn() }; + Object.defineProperty( document, 'getElementById', { writable: true, configurable: true, value: () => scrollElement } ); + const { wrapper } = getWrapper(); await wrapper.find( '#previous-btn' ).trigger( 'click' ); - expect( wrapper.emitted( 'previous-page' ).length ).toStrictEqual( 1 ); + expect( scrollElement.scrollIntoView ).toHaveBeenCalledWith( { behavior: 'smooth' } ); } ); it( 'shows and hides the error summary', async () => { jest.useFakeTimers(); - const { wrapper } = getWrapper(); + const { wrapper, store } = getWrapper(); + + await setPaymentTypeAndInitializeOtherPaymentValues( store, 'UEB' ); await wrapper.find( '#submit-btn' ).trigger( 'click' ); await nextTick(); @@ -177,7 +182,7 @@ describe( 'PersonalDataSection.vue (With Street Autocomplete)', () => { const { wrapper, store } = getWrapper(); - await setPaymentType( store, 'BEZ' ); + await setPaymentTypeAndInitializeOtherPaymentValues( store, 'BEZ' ); await wrapper.find( '#submit-btn' ).trigger( 'click' ); await nextTick(); @@ -232,7 +237,7 @@ describe( 'PersonalDataSection.vue (With Street Autocomplete)', () => { const { wrapper, store } = getWrapper(); - await setPaymentType( store, 'BEZ' ); + await setPaymentTypeAndInitializeOtherPaymentValues( store, 'BEZ' ); if ( addressTypeSelector !== '' ) { await wrapper.find( addressTypeSelector ).trigger( 'change' ); @@ -269,8 +274,18 @@ describe( 'PersonalDataSection.vue (With Street Autocomplete)', () => { expect( wrapper.find( '.address-type-person' ).exists() ).toBeTruthy(); } ); + it( 'validates the payment section input on page submit', async () => { + const { wrapper, store } = getWrapper(); + store.dispatch = jest.fn().mockResolvedValue( true ); + + await wrapper.find( '#submit-btn' ).trigger( 'click' ); + + expect( store.dispatch ).toHaveBeenCalledWith( action( 'payment', 'markEmptyValuesAsInvalid' ) ); + } ); + it( 'submits the form', async () => { const store = createStore(); + await setPaymentTypeAndInitializeOtherPaymentValues( store, 'UEB' ); await store.dispatch( action( 'address', 'initializeAddress' ), { addressType: AddressTypeModel.ANON, newsletter: true,