diff --git a/src/components/pages/donation_form/DonationReceipt/usePersonalDataSectionEventHandlers.ts b/src/components/pages/donation_form/DonationReceipt/usePersonalDataSectionEventHandlers.ts index 958814e6c..66f5f987c 100644 --- a/src/components/pages/donation_form/DonationReceipt/usePersonalDataSectionEventHandlers.ts +++ b/src/components/pages/donation_form/DonationReceipt/usePersonalDataSectionEventHandlers.ts @@ -76,7 +76,7 @@ export function usePersonalDataSectionEventHandlers( } } ); - store.watch( ( state, getters ) => getters[ 'payment/requiredFieldsAreValid' ], ( isValid: boolean ) => { + store.watch( ( state, getters ) => getters[ 'payment/paymentDataIsValid' ], ( isValid: boolean ) => { if ( !paymentDataIsValid.value && isValid ) { paymentDataIsValid.value = true; } diff --git a/src/components/pages/donation_form/singlePageFormSections/PersonalDataSection.vue b/src/components/pages/donation_form/singlePageFormSections/PersonalDataSection.vue index 3f28596e5..5c37d14d7 100644 --- a/src/components/pages/donation_form/singlePageFormSections/PersonalDataSection.vue +++ b/src/components/pages/donation_form/singlePageFormSections/PersonalDataSection.vue @@ -23,10 +23,6 @@ :initial-address-type="addressType" :address-type-is-invalid="addressTypeIsInvalid" /> -
{{ $t( 'donation_addresstype_option_anonymous_disclaimer' ) }} -
getters[ 'payment/requiredFieldsAreValid' ], ( isValid: boolean ) => { + store.watch( ( state, getters ) => getters[ 'payment/paymentDataIsValid' ], ( isValid: boolean ) => { if ( !paymentDataIsValid.value && isValid ) { paymentDataIsValid.value = true; } diff --git a/src/components/shared/form_fields/CountryAutocompleteField.vue b/src/components/shared/form_fields/CountryAutocompleteField.vue index 525ca4a28..ab97aa6d6 100644 --- a/src/components/shared/form_fields/CountryAutocompleteField.vue +++ b/src/components/shared/form_fields/CountryAutocompleteField.vue @@ -160,7 +160,7 @@ const onBlur = ( selectedCountry: Country ) => { autocompleteIsActive.value = false; if ( !itemWasJustSelectedFromList ) { - emit( 'field-changed', selectedCountry ); + emit( 'field-changed', selectedCountry ?? '' ); } itemWasJustSelectedFromList = false; }, 200 ); diff --git a/tests/unit/components/pages/donation_form/DonationForm.spec.ts b/tests/unit/components/pages/donation_form/DonationForm.spec.ts index f251c8eea..735b48355 100644 --- a/tests/unit/components/pages/donation_form/DonationForm.spec.ts +++ b/tests/unit/components/pages/donation_form/DonationForm.spec.ts @@ -1,12 +1,15 @@ -import { mount, VueWrapper } from '@vue/test-utils'; +import { flushPromises, mount, VueWrapper } from '@vue/test-utils'; import DonationForm from '@src/components/pages/DonationForm.vue'; import countries from '@test/data/countries'; import { AddressValidation } from '@src/view_models/Validation'; import { createFeatureToggle } from '@src/util/createFeatureToggle'; -import PaymentSection from '@src/components/pages/donation_form/singlePageFormSections/PaymentSection.vue'; -import PersonalDataSection from '@src/components/pages/donation_form/singlePageFormSections/PersonalDataSection.vue'; -import { Store } from 'vuex'; -import { createStore, StoreKey } from '@src/store/donation_store'; +import { createStore } from '@src/store/donation_store'; +import { FakeBankValidationResource } from '@test/unit/TestDoubles/FakeBankValidationResource'; +import { nextTick } from 'vue'; +import axios from 'axios'; + +jest.mock( 'axios' ); +const mockedAxios = axios as jest.Mocked; declare global { namespace NodeJS { @@ -16,17 +19,34 @@ declare global { } } +const IBAN = 'DE12500105170648489890'; + +const errorSummaryItemIsFunctional = ( wrapper: VueWrapper, formElement: string, scrollElement: string ): boolean => { + const errorItemExists = wrapper.find( `.error-summary a[href="#${formElement}"]` ).exists(); + const formElementExists = wrapper.find( `#${formElement}` ).exists(); + const scrollElementExists = wrapper.find( `#${scrollElement}` ).exists(); + + return errorItemExists && formElementExists && scrollElementExists; +}; + describe( 'DonationForm.vue', () => { beforeEach( () => { global.window.scrollTo = jest.fn(); + jest.useFakeTimers(); } ); - const getWrapper = ( store: Store = createStore() ): { wrapper: VueWrapper, store: Store } => { - const wrapper = mount( DonationForm, { + afterEach( () => { + jest.clearAllMocks(); + document.getElementsByTagName( 'html' )[ 0 ].innerHTML = ''; + } ); + + const getWrapper = (): VueWrapper => { + const store = createStore(); + return mount( DonationForm, { props: { assetsPath: '', - paymentAmounts: [ 5 ], + paymentAmounts: [ 500, 1000, 2000 ], paymentIntervals: [ 0, 1, 3, 6, 12 ], paymentTypes: [ 'BEZ', 'PPL', 'UEB', 'BTC' ], validateAddressUrl: 'https://example.com/address-check', @@ -36,25 +56,359 @@ describe( 'DonationForm.vue', () => { validateEmailUrl: '', validateBankDataUrl: '', validateLegacyBankDataUrl: '', - salutations: [], - addressValidationPatterns: { postcode: '' } as AddressValidation, + salutations: [ + { + label: 'Mr', + value: 'Mr', + display: 'Mr', + greetings: { + formal: 'Mr', + informal: 'Mr', + lastNameInformal: 'Mr', + }, + }, + { + label: 'Ms', + value: 'Ms', + display: 'Ms', + greetings: { + formal: 'Ms', + informal: 'Ms', + lastNameInformal: 'Ms', + }, + }, + ], + addressValidationPatterns: { postcode: '', country: null } as AddressValidation, }, global: { plugins: [ store ], provide: { - [ StoreKey as symbol ]: store, + bankValidationResource: new FakeBankValidationResource(), }, components: { FeatureToggle: createFeatureToggle( [ 'campaigns.address_pages.legacy' ] ), }, }, + attachTo: document.body, } ); - return { wrapper, store }; }; - it( 'displays payment section and address data section', () => { - const wrapper = getWrapper().wrapper; - expect( wrapper.findComponent( PaymentSection ).exists() ).toBe( true ); - expect( wrapper.findComponent( PersonalDataSection ).exists() ).toBe( true ); + it( 'handles the error summary when no address type was selected before submitting', async () => { + const wrapper = getWrapper(); + + await wrapper.find( '#person-country' ).setValue( 'I am clearly not a country' ); + await wrapper.find( '#person-country' ).trigger( 'blur' ); + await jest.runAllTimersAsync(); + + await wrapper.find( '#submit-btn' ).trigger( 'click' ); + await nextTick(); + await nextTick(); + + expect( errorSummaryItemIsFunctional( wrapper, 'paymentType-0', 'payment-form-type-scroll-target' ) ).toBeTruthy(); + + // Make the IBAN field appear + await wrapper.find( 'input[name="paymentType"][value="BEZ"]' ).trigger( 'change' ); + await wrapper.find( '#submit-btn' ).trigger( 'click' ); + await nextTick(); + await nextTick(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'amount-500', 'payment-form-amount-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'account-number', 'account-number-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'addressType-0', 'address-type-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-salutation-0', 'person-salutation-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-first-name', 'person-first-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-last-name', 'person-last-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-street', 'person-street-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-post-code', 'person-post-code-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-city', 'person-city-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-country', 'person-country-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-email', 'person-email-scroll-target' ) ).toBeTruthy(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="addressType"][value="0"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="salutation"][value="Mr"]' ).trigger( 'change' ); + + await wrapper.find( '#account-number' ).setValue( IBAN ); + await wrapper.find( '#account-number' ).trigger( 'blur' ); + + await wrapper.find( '#person-first-name' ).setValue( 'first-name' ); + await wrapper.find( '#person-first-name' ).trigger( 'blur' ); + + await wrapper.find( '#person-last-name' ).setValue( 'last-name' ); + await wrapper.find( '#person-last-name' ).trigger( 'blur' ); + + await wrapper.find( '#person-street' ).setValue( 'street' ); + await wrapper.find( '#person-street' ).trigger( 'blur' ); + + await wrapper.find( '#person-post-code' ).setValue( '12345' ); + await wrapper.find( '#person-post-code' ).trigger( 'blur' ); + + await wrapper.find( '#person-city' ).setValue( 'city' ); + await wrapper.find( '#person-city' ).trigger( 'blur' ); + + await wrapper.find( '#person-country' ).setValue( countries[ 0 ].countryFullName ); + await wrapper.find( '#person-country' ).trigger( 'blur' ); + + await wrapper.find( '#person-email' ).setValue( 'joe@dolan.com' ); + await wrapper.find( '#person-email' ).trigger( 'blur' ); + + await jest.runAllTimersAsync(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeFalsy(); + } ); + + it( 'handles the error summary when person address type was selected before submitting', async () => { + const wrapper = getWrapper(); + + await wrapper.find( 'input[name="addressType"][value="0"]' ).trigger( 'change' ); + await wrapper.find( '#person-country' ).setValue( 'I am clearly not a country' ); + await wrapper.find( '#person-country' ).trigger( 'blur' ); + await jest.runAllTimersAsync(); + + await wrapper.find( '#submit-btn' ).trigger( 'click' ); + await nextTick(); + await nextTick(); + + expect( errorSummaryItemIsFunctional( wrapper, 'paymentType-0', 'payment-form-type-scroll-target' ) ).toBeTruthy(); + + // Make the IBAN field appear + await wrapper.find( 'input[name="paymentType"][value="BEZ"]' ).trigger( 'change' ); + await wrapper.find( '#submit-btn' ).trigger( 'click' ); + await nextTick(); + await nextTick(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'amount-500', 'payment-form-amount-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'account-number', 'account-number-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-salutation-0', 'person-salutation-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-first-name', 'person-first-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-last-name', 'person-last-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-street', 'person-street-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-post-code', 'person-post-code-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-city', 'person-city-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-country', 'person-country-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-email', 'person-email-scroll-target' ) ).toBeTruthy(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="salutation"][value="Mr"]' ).trigger( 'change' ); + + await wrapper.find( '#account-number' ).setValue( IBAN ); + await wrapper.find( '#account-number' ).trigger( 'blur' ); + + await wrapper.find( '#person-first-name' ).setValue( 'first-name' ); + await wrapper.find( '#person-first-name' ).trigger( 'blur' ); + + await wrapper.find( '#person-last-name' ).setValue( 'last-name' ); + await wrapper.find( '#person-last-name' ).trigger( 'blur' ); + + await wrapper.find( '#person-street' ).setValue( 'street' ); + await wrapper.find( '#person-street' ).trigger( 'blur' ); + + await wrapper.find( '#person-post-code' ).setValue( '12345' ); + await wrapper.find( '#person-post-code' ).trigger( 'blur' ); + + await wrapper.find( '#person-city' ).setValue( 'city' ); + await wrapper.find( '#person-city' ).trigger( 'blur' ); + + await wrapper.find( '#person-country' ).setValue( countries[ 0 ].countryFullName ); + await wrapper.find( '#person-country' ).trigger( 'blur' ); + + await wrapper.find( '#person-email' ).setValue( 'joe@dolan.com' ); + await wrapper.find( '#person-email' ).trigger( 'blur' ); + + await jest.runAllTimersAsync(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeFalsy(); + } ); + + it( 'handles the error summary when company address type was selected before submitting', async () => { + const wrapper = getWrapper(); + + await wrapper.find( 'input[name="addressType"][value="1"]' ).trigger( 'change' ); + await wrapper.find( '#company-country' ).setValue( 'I am clearly not a country' ); + await wrapper.find( '#company-country' ).trigger( 'blur' ); + await jest.runAllTimersAsync(); + + await wrapper.find( '#submit-btn' ).trigger( 'click' ); + await nextTick(); + await nextTick(); + + expect( errorSummaryItemIsFunctional( wrapper, 'paymentType-0', 'payment-form-type-scroll-target' ) ).toBeTruthy(); + + // Make the IBAN field appear + await wrapper.find( 'input[name="paymentType"][value="BEZ"]' ).trigger( 'change' ); + await wrapper.find( '#submit-btn' ).trigger( 'click' ); + await nextTick(); + await nextTick(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'amount-500', 'payment-form-amount-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'account-number', 'account-number-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'company-company-name', 'company-company-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'company-street', 'company-street-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'company-post-code', 'company-post-code-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'company-city', 'company-city-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'company-country', 'company-country-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'company-email', 'company-email-scroll-target' ) ).toBeTruthy(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="paymentType"][value="PPL"]' ).trigger( 'change' ); + + await wrapper.find( 'input[name="salutation"][value="Mr"]' ).trigger( 'change' ); + + await wrapper.find( '#company-company-name' ).setValue( 'company-name' ); + await wrapper.find( '#company-company-name' ).trigger( 'blur' ); + + await wrapper.find( '#company-street' ).setValue( 'street' ); + await wrapper.find( '#company-street' ).trigger( 'blur' ); + + await wrapper.find( '#company-post-code' ).setValue( '12345' ); + await wrapper.find( '#company-post-code' ).trigger( 'blur' ); + + await wrapper.find( '#company-city' ).setValue( 'city' ); + await wrapper.find( '#company-city' ).trigger( 'blur' ); + + await wrapper.find( '#company-country' ).setValue( countries[ 0 ].countryFullName ); + await wrapper.find( '#company-country' ).trigger( 'blur' ); + + await wrapper.find( '#company-email' ).setValue( 'joe@dolan.com' ); + await wrapper.find( '#company-email' ).trigger( 'blur' ); + + await jest.runAllTimersAsync(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeFalsy(); + } ); + + it( 'handles the error summary when without address type was selected before submitting', async () => { + const wrapper = getWrapper(); + + await wrapper.find( 'input[name="addressType"][value="4"]' ).trigger( 'change' ); + + await wrapper.find( '#submit-btn' ).trigger( 'click' ); + await nextTick(); + await nextTick(); + await flushPromises(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'amount-500', 'payment-form-amount-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'paymentType-0', 'payment-form-type-scroll-target' ) ).toBeTruthy(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="paymentType"][value="PPL"]' ).trigger( 'change' ); + + await jest.runAllTimersAsync(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeFalsy(); + } ); + + it( 'submits the form for a person', async () => { + mockedAxios.post.mockResolvedValue( { data: { status: 'OK' } } ); + const wrapper = getWrapper(); + + const submitForm = wrapper.find( '#submit-form' ); + submitForm.element.submit = jest.fn(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="paymentType"][value="BEZ"]' ).trigger( 'change' ); + + await wrapper.find( '#account-number' ).setValue( IBAN ); + await wrapper.find( '#account-number' ).trigger( 'blur' ); + + await wrapper.find( 'input[name="addressType"][value="0"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="salutation"][value="Mr"]' ).trigger( 'change' ); + + await wrapper.find( '#person-first-name' ).setValue( 'first-name' ); + await wrapper.find( '#person-first-name' ).trigger( 'blur' ); + + await wrapper.find( '#person-last-name' ).setValue( 'last-name' ); + await wrapper.find( '#person-last-name' ).trigger( 'blur' ); + + await wrapper.find( '#person-street' ).setValue( 'street' ); + await wrapper.find( '#person-street' ).trigger( 'blur' ); + + await wrapper.find( '#person-post-code' ).setValue( '12345' ); + await wrapper.find( '#person-post-code' ).trigger( 'blur' ); + + await wrapper.find( '#person-city' ).setValue( 'city' ); + await wrapper.find( '#person-city' ).trigger( 'blur' ); + + await jest.runAllTimersAsync(); + + await wrapper.find( '#person-country' ).setValue( countries[ 0 ].countryFullName ); + await wrapper.find( '#person-country' ).trigger( 'blur' ); + + await wrapper.find( '#person-email' ).setValue( 'joe@dolan.com' ); + await wrapper.find( '#person-email' ).trigger( 'blur' ); + + await wrapper.find( '#submit-btn' ).trigger( 'click' ); + + await jest.runAllTimersAsync(); + await flushPromises(); + + expect( submitForm.element.submit ).toHaveBeenCalled(); + } ); + + it( 'submits the form for a company', async () => { + mockedAxios.post.mockResolvedValue( { data: { status: 'OK' } } ); + const wrapper = getWrapper(); + + const submitForm = wrapper.find( '#submit-form' ); + submitForm.element.submit = jest.fn(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="paymentType"][value="BEZ"]' ).trigger( 'change' ); + + await wrapper.find( '#account-number' ).setValue( IBAN ); + await wrapper.find( '#account-number' ).trigger( 'blur' ); + + await wrapper.find( 'input[name="addressType"][value="1"]' ).trigger( 'change' ); + + await wrapper.find( '#company-company-name' ).setValue( 'company-name' ); + await wrapper.find( '#company-company-name' ).trigger( 'blur' ); + + await wrapper.find( '#company-street' ).setValue( 'street' ); + await wrapper.find( '#company-street' ).trigger( 'blur' ); + + await wrapper.find( '#company-post-code' ).setValue( '12345' ); + await wrapper.find( '#company-post-code' ).trigger( 'blur' ); + + await wrapper.find( '#company-city' ).setValue( 'city' ); + await wrapper.find( '#company-city' ).trigger( 'blur' ); + + await jest.runAllTimersAsync(); + + await wrapper.find( '#company-country' ).setValue( countries[ 0 ].countryFullName ); + await wrapper.find( '#company-country' ).trigger( 'blur' ); + + await wrapper.find( '#company-email' ).setValue( 'joe@dolan.com' ); + await wrapper.find( '#company-email' ).trigger( 'blur' ); + + await wrapper.find( '#submit-btn' ).trigger( 'click' ); + + await jest.runAllTimersAsync(); + await flushPromises(); + + expect( submitForm.element.submit ).toHaveBeenCalled(); + } ); + + it( 'submits the form for anonymous', async () => { + mockedAxios.post.mockResolvedValue( { data: { status: 'OK' } } ); + const wrapper = getWrapper(); + + const submitForm = wrapper.find( '#submit-form' ); + submitForm.element.submit = jest.fn(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="paymentType"][value="PPL"]' ).trigger( 'change' ); + + await wrapper.find( 'input[name="addressType"][value="4"]' ).trigger( 'change' ); + + await wrapper.find( '#submit-btn' ).trigger( 'click' ); + + await jest.runAllTimersAsync(); + await flushPromises(); + + expect( submitForm.element.submit ).toHaveBeenCalled(); } ); } ); diff --git a/tests/unit/components/pages/donation_form/DonationFormAlternateOrder.spec.ts b/tests/unit/components/pages/donation_form/DonationFormAlternateOrder.spec.ts new file mode 100644 index 000000000..ce34c66e1 --- /dev/null +++ b/tests/unit/components/pages/donation_form/DonationFormAlternateOrder.spec.ts @@ -0,0 +1,414 @@ +import { flushPromises, mount, VueWrapper } from '@vue/test-utils'; +import DonationForm from '@src/components/pages/DonationForm.vue'; +import countries from '@test/data/countries'; +import { AddressValidation } from '@src/view_models/Validation'; +import { createFeatureToggle } from '@src/util/createFeatureToggle'; +import { createStore } from '@src/store/donation_store'; +import { FakeBankValidationResource } from '@test/unit/TestDoubles/FakeBankValidationResource'; +import { nextTick } from 'vue'; +import axios from 'axios'; + +jest.mock( 'axios' ); +const mockedAxios = axios as jest.Mocked; + +declare global { + namespace NodeJS { + interface Global { + window: Window; + } + } +} + +const IBAN = 'DE12500105170648489890'; + +const errorSummaryItemIsFunctional = ( wrapper: VueWrapper, formElement: string, scrollElement: string ): boolean => { + const errorItemExists = wrapper.find( `.error-summary a[href="#${formElement}"]` ).exists(); + const formElementExists = wrapper.find( `#${formElement}` ).exists(); + const scrollElementExists = wrapper.find( `#${scrollElement}` ).exists(); + + return errorItemExists && formElementExists && scrollElementExists; +}; + +describe( 'DonationForm.vue (alternate order for street autocomplete)', () => { + + beforeEach( () => { + global.window.scrollTo = jest.fn(); + jest.useFakeTimers(); + } ); + + afterEach( () => { + jest.clearAllMocks(); + document.getElementsByTagName( 'html' )[ 0 ].innerHTML = ''; + } ); + + const getWrapper = (): VueWrapper => { + const store = createStore(); + return mount( DonationForm, { + props: { + assetsPath: '', + paymentAmounts: [ 500, 1000, 2000 ], + paymentIntervals: [ 0, 1, 3, 6, 12 ], + paymentTypes: [ 'BEZ', 'PPL', 'UEB', 'BTC' ], + validateAddressUrl: 'https://example.com/address-check', + countries: countries, + trackingData: { bannerImpressionCount: 0, impressionCount: 0 }, + campaignValues: { campaign: 'nicholas', keyword: 'cage' }, + validateEmailUrl: '', + validateBankDataUrl: '', + validateLegacyBankDataUrl: '', + salutations: [ + { + label: 'Mr', + value: 'Mr', + display: 'Mr', + greetings: { + formal: 'Mr', + informal: 'Mr', + lastNameInformal: 'Mr', + }, + }, + { + label: 'Ms', + value: 'Ms', + display: 'Ms', + greetings: { + formal: 'Ms', + informal: 'Ms', + lastNameInformal: 'Ms', + }, + }, + ], + addressValidationPatterns: { postcode: '', country: null } as AddressValidation, + }, + global: { + plugins: [ store ], + provide: { + bankValidationResource: new FakeBankValidationResource(), + }, + components: { + FeatureToggle: createFeatureToggle( [ 'campaigns.address_pages.legacy', 'campaigns.address_field_order.new_order' ] ), + }, + }, + attachTo: document.body, + } ); + }; + + it( 'handles the error summary when no address type was selected before submitting', async () => { + const wrapper = getWrapper(); + + await wrapper.find( '#person-country' ).setValue( 'I am clearly not a country' ); + await wrapper.find( '#person-country' ).trigger( 'blur' ); + await jest.runAllTimersAsync(); + + await wrapper.find( '#submit-btn' ).trigger( 'click' ); + await nextTick(); + await nextTick(); + + expect( errorSummaryItemIsFunctional( wrapper, 'paymentType-0', 'payment-form-type-scroll-target' ) ).toBeTruthy(); + + // Make the IBAN field appear + await wrapper.find( 'input[name="paymentType"][value="BEZ"]' ).trigger( 'change' ); + await wrapper.find( '#submit-btn' ).trigger( 'click' ); + await nextTick(); + await nextTick(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'amount-500', 'payment-form-amount-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'account-number', 'account-number-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'addressType-0', 'address-type-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-salutation-0', 'person-salutation-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-first-name', 'person-first-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-last-name', 'person-last-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-street', 'person-street-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-post-code', 'person-post-code-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-city', 'person-city-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-country', 'person-country-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-email', 'person-email-scroll-target' ) ).toBeTruthy(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="addressType"][value="0"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="salutation"][value="Mr"]' ).trigger( 'change' ); + + await wrapper.find( '#account-number' ).setValue( IBAN ); + await wrapper.find( '#account-number' ).trigger( 'blur' ); + + await wrapper.find( '#person-first-name' ).setValue( 'first-name' ); + await wrapper.find( '#person-first-name' ).trigger( 'blur' ); + + await wrapper.find( '#person-last-name' ).setValue( 'last-name' ); + await wrapper.find( '#person-last-name' ).trigger( 'blur' ); + + await wrapper.find( '#person-street' ).setValue( 'street' ); + await wrapper.find( '#person-street' ).trigger( 'blur' ); + + await wrapper.find( '#person-post-code' ).setValue( '12345' ); + await wrapper.find( '#person-post-code' ).trigger( 'blur' ); + + await wrapper.find( '#person-city' ).setValue( 'city' ); + await wrapper.find( '#person-city' ).trigger( 'blur' ); + + await wrapper.find( '#person-country' ).setValue( countries[ 0 ].countryFullName ); + await wrapper.find( '#person-country' ).trigger( 'blur' ); + + await wrapper.find( '#person-email' ).setValue( 'joe@dolan.com' ); + await wrapper.find( '#person-email' ).trigger( 'blur' ); + + await jest.runAllTimersAsync(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeFalsy(); + } ); + + it( 'handles the error summary when person address type was selected before submitting', async () => { + const wrapper = getWrapper(); + + await wrapper.find( 'input[name="addressType"][value="0"]' ).trigger( 'change' ); + await wrapper.find( '#person-country' ).setValue( 'I am clearly not a country' ); + await wrapper.find( '#person-country' ).trigger( 'blur' ); + await jest.runAllTimersAsync(); + + await wrapper.find( '#submit-btn' ).trigger( 'click' ); + await nextTick(); + await nextTick(); + + expect( errorSummaryItemIsFunctional( wrapper, 'paymentType-0', 'payment-form-type-scroll-target' ) ).toBeTruthy(); + + // Make the IBAN field appear + await wrapper.find( 'input[name="paymentType"][value="BEZ"]' ).trigger( 'change' ); + await wrapper.find( '#submit-btn' ).trigger( 'click' ); + await nextTick(); + await nextTick(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'amount-500', 'payment-form-amount-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'account-number', 'account-number-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-salutation-0', 'person-salutation-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-first-name', 'person-first-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-last-name', 'person-last-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-street', 'person-street-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-post-code', 'person-post-code-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-city', 'person-city-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-country', 'person-country-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'person-email', 'person-email-scroll-target' ) ).toBeTruthy(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="salutation"][value="Mr"]' ).trigger( 'change' ); + + await wrapper.find( '#account-number' ).setValue( IBAN ); + await wrapper.find( '#account-number' ).trigger( 'blur' ); + + await wrapper.find( '#person-first-name' ).setValue( 'first-name' ); + await wrapper.find( '#person-first-name' ).trigger( 'blur' ); + + await wrapper.find( '#person-last-name' ).setValue( 'last-name' ); + await wrapper.find( '#person-last-name' ).trigger( 'blur' ); + + await wrapper.find( '#person-street' ).setValue( 'street' ); + await wrapper.find( '#person-street' ).trigger( 'blur' ); + + await wrapper.find( '#person-post-code' ).setValue( '12345' ); + await wrapper.find( '#person-post-code' ).trigger( 'blur' ); + + await wrapper.find( '#person-city' ).setValue( 'city' ); + await wrapper.find( '#person-city' ).trigger( 'blur' ); + + await wrapper.find( '#person-country' ).setValue( countries[ 0 ].countryFullName ); + await wrapper.find( '#person-country' ).trigger( 'blur' ); + + await wrapper.find( '#person-email' ).setValue( 'joe@dolan.com' ); + await wrapper.find( '#person-email' ).trigger( 'blur' ); + + await jest.runAllTimersAsync(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeFalsy(); + } ); + + it( 'handles the error summary when company address type was selected before submitting', async () => { + const wrapper = getWrapper(); + + await wrapper.find( 'input[name="addressType"][value="1"]' ).trigger( 'change' ); + await wrapper.find( '#company-country' ).setValue( 'I am clearly not a country' ); + await wrapper.find( '#company-country' ).trigger( 'blur' ); + await jest.runAllTimersAsync(); + + await wrapper.find( '#submit-btn' ).trigger( 'click' ); + await nextTick(); + await nextTick(); + + expect( errorSummaryItemIsFunctional( wrapper, 'paymentType-0', 'payment-form-type-scroll-target' ) ).toBeTruthy(); + + // Make the IBAN field appear + await wrapper.find( 'input[name="paymentType"][value="BEZ"]' ).trigger( 'change' ); + await wrapper.find( '#submit-btn' ).trigger( 'click' ); + await nextTick(); + await nextTick(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'amount-500', 'payment-form-amount-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'account-number', 'account-number-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'company-company-name', 'company-company-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'company-street', 'company-street-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'company-post-code', 'company-post-code-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'company-city', 'company-city-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'company-country', 'company-country-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'company-email', 'company-email-scroll-target' ) ).toBeTruthy(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="paymentType"][value="PPL"]' ).trigger( 'change' ); + + await wrapper.find( 'input[name="salutation"][value="Mr"]' ).trigger( 'change' ); + + await wrapper.find( '#company-company-name' ).setValue( 'company-name' ); + await wrapper.find( '#company-company-name' ).trigger( 'blur' ); + + await wrapper.find( '#company-street' ).setValue( 'street' ); + await wrapper.find( '#company-street' ).trigger( 'blur' ); + + await wrapper.find( '#company-post-code' ).setValue( '12345' ); + await wrapper.find( '#company-post-code' ).trigger( 'blur' ); + + await wrapper.find( '#company-city' ).setValue( 'city' ); + await wrapper.find( '#company-city' ).trigger( 'blur' ); + + await wrapper.find( '#company-country' ).setValue( countries[ 0 ].countryFullName ); + await wrapper.find( '#company-country' ).trigger( 'blur' ); + + await wrapper.find( '#company-email' ).setValue( 'joe@dolan.com' ); + await wrapper.find( '#company-email' ).trigger( 'blur' ); + + await jest.runAllTimersAsync(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeFalsy(); + } ); + + it( 'handles the error summary when without address type was selected before submitting', async () => { + const wrapper = getWrapper(); + + await wrapper.find( 'input[name="addressType"][value="4"]' ).trigger( 'change' ); + + await wrapper.find( '#submit-btn' ).trigger( 'click' ); + await nextTick(); + await nextTick(); + await flushPromises(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'amount-500', 'payment-form-amount-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'paymentType-0', 'payment-form-type-scroll-target' ) ).toBeTruthy(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="paymentType"][value="PPL"]' ).trigger( 'change' ); + + await jest.runAllTimersAsync(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeFalsy(); + } ); + + it( 'submits the form for a person', async () => { + mockedAxios.post.mockResolvedValue( { data: { status: 'OK' } } ); + const wrapper = getWrapper(); + + const submitForm = wrapper.find( '#submit-form' ); + submitForm.element.submit = jest.fn(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="paymentType"][value="BEZ"]' ).trigger( 'change' ); + + await wrapper.find( '#account-number' ).setValue( IBAN ); + await wrapper.find( '#account-number' ).trigger( 'blur' ); + + await wrapper.find( 'input[name="addressType"][value="0"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="salutation"][value="Mr"]' ).trigger( 'change' ); + + await wrapper.find( '#person-first-name' ).setValue( 'first-name' ); + await wrapper.find( '#person-first-name' ).trigger( 'blur' ); + + await wrapper.find( '#person-last-name' ).setValue( 'last-name' ); + await wrapper.find( '#person-last-name' ).trigger( 'blur' ); + + await wrapper.find( '#person-street' ).setValue( 'street' ); + await wrapper.find( '#person-street' ).trigger( 'blur' ); + + await wrapper.find( '#person-post-code' ).setValue( '12345' ); + await wrapper.find( '#person-post-code' ).trigger( 'blur' ); + + await wrapper.find( '#person-city' ).setValue( 'city' ); + await wrapper.find( '#person-city' ).trigger( 'blur' ); + + await jest.runAllTimersAsync(); + + await wrapper.find( '#person-country' ).setValue( countries[ 0 ].countryFullName ); + await wrapper.find( '#person-country' ).trigger( 'blur' ); + + await wrapper.find( '#person-email' ).setValue( 'joe@dolan.com' ); + await wrapper.find( '#person-email' ).trigger( 'blur' ); + + await wrapper.find( '#submit-btn' ).trigger( 'click' ); + + await jest.runAllTimersAsync(); + await flushPromises(); + + expect( submitForm.element.submit ).toHaveBeenCalled(); + } ); + + it( 'submits the form for a company', async () => { + mockedAxios.post.mockResolvedValue( { data: { status: 'OK' } } ); + const wrapper = getWrapper(); + + const submitForm = wrapper.find( '#submit-form' ); + submitForm.element.submit = jest.fn(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="paymentType"][value="BEZ"]' ).trigger( 'change' ); + + await wrapper.find( '#account-number' ).setValue( IBAN ); + await wrapper.find( '#account-number' ).trigger( 'blur' ); + + await wrapper.find( 'input[name="addressType"][value="1"]' ).trigger( 'change' ); + + await wrapper.find( '#company-company-name' ).setValue( 'company-name' ); + await wrapper.find( '#company-company-name' ).trigger( 'blur' ); + + await wrapper.find( '#company-street' ).setValue( 'street' ); + await wrapper.find( '#company-street' ).trigger( 'blur' ); + + await wrapper.find( '#company-post-code' ).setValue( '12345' ); + await wrapper.find( '#company-post-code' ).trigger( 'blur' ); + + await wrapper.find( '#company-city' ).setValue( 'city' ); + await wrapper.find( '#company-city' ).trigger( 'blur' ); + + await jest.runAllTimersAsync(); + + await wrapper.find( '#company-country' ).setValue( countries[ 0 ].countryFullName ); + await wrapper.find( '#company-country' ).trigger( 'blur' ); + + await wrapper.find( '#company-email' ).setValue( 'joe@dolan.com' ); + await wrapper.find( '#company-email' ).trigger( 'blur' ); + + await wrapper.find( '#submit-btn' ).trigger( 'click' ); + + await jest.runAllTimersAsync(); + await flushPromises(); + + expect( submitForm.element.submit ).toHaveBeenCalled(); + } ); + + it( 'submits the form for anonymous', async () => { + mockedAxios.post.mockResolvedValue( { data: { status: 'OK' } } ); + const wrapper = getWrapper(); + + const submitForm = wrapper.find( '#submit-form' ); + submitForm.element.submit = jest.fn(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="paymentType"][value="PPL"]' ).trigger( 'change' ); + + await wrapper.find( 'input[name="addressType"][value="4"]' ).trigger( 'change' ); + + await wrapper.find( '#submit-btn' ).trigger( 'click' ); + + await jest.runAllTimersAsync(); + await flushPromises(); + + expect( submitForm.element.submit ).toHaveBeenCalled(); + } ); +} ); diff --git a/tests/unit/components/pages/donation_form/DonationFormReceipt.spec.ts b/tests/unit/components/pages/donation_form/DonationFormReceipt.spec.ts new file mode 100644 index 000000000..9618cfff8 --- /dev/null +++ b/tests/unit/components/pages/donation_form/DonationFormReceipt.spec.ts @@ -0,0 +1,469 @@ +import { flushPromises, mount, VueWrapper } from '@vue/test-utils'; +import DonationForm from '@src/components/pages/DonationForm.vue'; +import countries from '@test/data/countries'; +import { AddressValidation } from '@src/view_models/Validation'; +import { createFeatureToggle } from '@src/util/createFeatureToggle'; +import { createStore } from '@src/store/donation_store'; +import { FakeBankValidationResource } from '@test/unit/TestDoubles/FakeBankValidationResource'; +import { nextTick } from 'vue'; +import axios from 'axios'; + +jest.mock( 'axios' ); +const mockedAxios = axios as jest.Mocked; + +declare global { + namespace NodeJS { + interface Global { + window: Window; + } + } +} + +const IBAN = 'DE12500105170648489890'; + +const errorSummaryItemIsFunctional = ( wrapper: VueWrapper, formElement: string, scrollElement: string ): boolean => { + const errorItemExists = wrapper.find( `.error-summary a[href="#${formElement}"]` ).exists(); + const formElementExists = wrapper.find( `#${formElement}` ).exists(); + const scrollElementExists = wrapper.find( `#${scrollElement}` ).exists(); + + return errorItemExists && formElementExists && scrollElementExists; +}; + +describe( 'DonationForm.vue (with receipt question field)', () => { + + beforeEach( () => { + global.window.scrollTo = jest.fn(); + jest.useFakeTimers(); + } ); + + afterEach( () => { + jest.clearAllMocks(); + document.getElementsByTagName( 'html' )[ 0 ].innerHTML = ''; + } ); + + const getWrapper = (): VueWrapper => { + const store = createStore(); + return mount( DonationForm, { + props: { + assetsPath: '', + paymentAmounts: [ 500, 1000, 2000 ], + paymentIntervals: [ 0, 1, 3, 6, 12 ], + paymentTypes: [ 'BEZ', 'PPL', 'UEB', 'BTC' ], + validateAddressUrl: 'https://example.com/address-check', + countries: countries, + trackingData: { bannerImpressionCount: 0, impressionCount: 0 }, + campaignValues: { campaign: 'nicholas', keyword: 'cage' }, + validateEmailUrl: '', + validateBankDataUrl: '', + validateLegacyBankDataUrl: '', + salutations: [ + { + label: 'Mr', + value: 'Mr', + display: 'Mr', + greetings: { + formal: 'Mr', + informal: 'Mr', + lastNameInformal: 'Mr', + }, + }, + { + label: 'Ms', + value: 'Ms', + display: 'Ms', + greetings: { + formal: 'Ms', + informal: 'Ms', + lastNameInformal: 'Ms', + }, + }, + ], + addressValidationPatterns: { postcode: '', country: null } as AddressValidation, + }, + global: { + plugins: [ store ], + provide: { + bankValidationResource: new FakeBankValidationResource(), + }, + components: { + FeatureToggle: createFeatureToggle( [ 'campaigns.address_pages.test_02' ] ), + }, + }, + attachTo: document.body, + } ); + }; + + it( 'handles the error summary when no receipt option was selected before submitting', async () => { + const wrapper = getWrapper(); + + await wrapper.find( '#donation-form' ).trigger( 'submit' ); + await nextTick(); + await nextTick(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'amount-500', 'payment-form-amount-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'paymentType-0', 'payment-form-type-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'salutation-0', 'salutation-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'first-name', 'first-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'last-name', 'last-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'email', 'email-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'donationReceipt-0', 'receipt-scroll-target' ) ).toBeTruthy(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="paymentType"][value="PPL"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="salutation"][value="Mr"]' ).trigger( 'change' ); + + await wrapper.find( '#first-name' ).setValue( 'first-name' ); + await wrapper.find( '#first-name' ).trigger( 'blur' ); + + await wrapper.find( '#last-name' ).setValue( 'last-name' ); + await wrapper.find( '#last-name' ).trigger( 'blur' ); + + await wrapper.find( '#email' ).setValue( 'joe@dolan.com' ); + await wrapper.find( '#email' ).trigger( 'blur' ); + + await wrapper.find( 'input[name="donationReceipt"][value="false"]' ).trigger( 'change' ); + + await jest.runAllTimersAsync(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeFalsy(); + } ); + + it( 'handles the error summary when only receipt option yes was selected selected before submitting', async () => { + const wrapper = getWrapper(); + + await wrapper.find( 'input[name="donationReceipt"][value="true"]' ).trigger( 'change' ); + await wrapper.find( '#country' ).setValue( 'I am clearly not a country' ); + await wrapper.find( '#country' ).trigger( 'blur' ); + await jest.runAllTimersAsync(); + + await wrapper.find( '#donation-form' ).trigger( 'submit' ); + await nextTick(); + await nextTick(); + + expect( errorSummaryItemIsFunctional( wrapper, 'paymentType-0', 'payment-form-type-scroll-target' ) ).toBeTruthy(); + + // Make the IBAN field appear + await wrapper.find( 'input[name="paymentType"][value="BEZ"]' ).trigger( 'change' ); + await wrapper.find( '#donation-form' ).trigger( 'submit' ); + await nextTick(); + await nextTick(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'amount-500', 'payment-form-amount-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'account-number', 'account-number-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'salutation-0', 'salutation-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'first-name', 'first-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'last-name', 'last-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'email', 'email-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'addressType-0', 'address-type-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'street', 'street-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'post-code', 'post-code-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'city', 'city-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'country', 'country-scroll-target' ) ).toBeTruthy(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="salutation"][value="Mr"]' ).trigger( 'change' ); + + await wrapper.find( '#account-number' ).setValue( IBAN ); + await wrapper.find( '#account-number' ).trigger( 'blur' ); + + await wrapper.find( '#first-name' ).setValue( 'first-name' ); + await wrapper.find( '#first-name' ).trigger( 'blur' ); + + await wrapper.find( '#last-name' ).setValue( 'last-name' ); + await wrapper.find( '#last-name' ).trigger( 'blur' ); + + await wrapper.find( 'input[name="addressTypeSelector"][value="0"]' ).trigger( 'change' ); + + await wrapper.find( '#street' ).setValue( 'street' ); + await wrapper.find( '#street' ).trigger( 'blur' ); + + await wrapper.find( '#post-code' ).setValue( '12345' ); + await wrapper.find( '#post-code' ).trigger( 'blur' ); + + await wrapper.find( '#city' ).setValue( 'city' ); + await wrapper.find( '#city' ).trigger( 'blur' ); + + await wrapper.find( '#country' ).setValue( countries[ 0 ].countryFullName ); + await wrapper.find( '#country' ).trigger( 'blur' ); + + await wrapper.find( '#email' ).setValue( 'joe@dolan.com' ); + await wrapper.find( '#email' ).trigger( 'blur' ); + + await jest.runAllTimersAsync(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeFalsy(); + } ); + + it( 'handles the error summary when person address type was selected selected before submitting', async () => { + const wrapper = getWrapper(); + + await wrapper.find( 'input[name="donationReceipt"][value="true"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="addressTypeSelector"][value="0"]' ).trigger( 'change' ); + await wrapper.find( '#country' ).setValue( 'I am clearly not a country' ); + await wrapper.find( '#country' ).trigger( 'blur' ); + await jest.runAllTimersAsync(); + + await wrapper.find( '#donation-form' ).trigger( 'submit' ); + await nextTick(); + await nextTick(); + + expect( errorSummaryItemIsFunctional( wrapper, 'paymentType-0', 'payment-form-type-scroll-target' ) ).toBeTruthy(); + + // Make the IBAN field appear + await wrapper.find( 'input[name="paymentType"][value="BEZ"]' ).trigger( 'change' ); + await wrapper.find( '#donation-form' ).trigger( 'submit' ); + await nextTick(); + await nextTick(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'amount-500', 'payment-form-amount-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'account-number', 'account-number-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'salutation-0', 'salutation-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'first-name', 'first-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'last-name', 'last-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'email', 'email-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'street', 'street-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'post-code', 'post-code-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'city', 'city-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'country', 'country-scroll-target' ) ).toBeTruthy(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="salutation"][value="Mr"]' ).trigger( 'change' ); + + await wrapper.find( '#account-number' ).setValue( IBAN ); + await wrapper.find( '#account-number' ).trigger( 'blur' ); + + await wrapper.find( '#first-name' ).setValue( 'first-name' ); + await wrapper.find( '#first-name' ).trigger( 'blur' ); + + await wrapper.find( '#last-name' ).setValue( 'last-name' ); + await wrapper.find( '#last-name' ).trigger( 'blur' ); + + await wrapper.find( '#street' ).setValue( 'street' ); + await wrapper.find( '#street' ).trigger( 'blur' ); + + await wrapper.find( '#post-code' ).setValue( '12345' ); + await wrapper.find( '#post-code' ).trigger( 'blur' ); + + await wrapper.find( '#city' ).setValue( 'city' ); + await wrapper.find( '#city' ).trigger( 'blur' ); + + await wrapper.find( '#country' ).setValue( countries[ 0 ].countryFullName ); + await wrapper.find( '#country' ).trigger( 'blur' ); + + await wrapper.find( '#email' ).setValue( 'joe@dolan.com' ); + await wrapper.find( '#email' ).trigger( 'blur' ); + + await jest.runAllTimersAsync(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeFalsy(); + } ); + + it( 'handles the error summary when company address type was selected before submitting', async () => { + const wrapper = getWrapper(); + + await wrapper.find( 'input[name="donationReceipt"][value="true"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="addressTypeSelector"][value="2"]' ).trigger( 'change' ); + await nextTick(); + + await wrapper.find( '#country' ).setValue( 'I am clearly not a country' ); + await wrapper.find( '#country' ).trigger( 'blur' ); + await jest.runAllTimersAsync(); + + await wrapper.find( '#donation-form' ).trigger( 'submit' ); + await nextTick(); + await nextTick(); + + expect( errorSummaryItemIsFunctional( wrapper, 'paymentType-0', 'payment-form-type-scroll-target' ) ).toBeTruthy(); + + // Make the IBAN field appear + await wrapper.find( 'input[name="paymentType"][value="BEZ"]' ).trigger( 'change' ); + await wrapper.find( '#donation-form' ).trigger( 'submit' ); + await nextTick(); + await nextTick(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'amount-500', 'payment-form-amount-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'account-number', 'account-number-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'salutation-0', 'salutation-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'first-name', 'first-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'last-name', 'last-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'email', 'email-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'company-name', 'company-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'street', 'street-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'post-code', 'post-code-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'city', 'city-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'country', 'country-scroll-target' ) ).toBeTruthy(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="salutation"][value="Mr"]' ).trigger( 'change' ); + + await wrapper.find( '#account-number' ).setValue( IBAN ); + await wrapper.find( '#account-number' ).trigger( 'blur' ); + + await wrapper.find( '#first-name' ).setValue( 'first-name' ); + await wrapper.find( '#first-name' ).trigger( 'blur' ); + + await wrapper.find( '#last-name' ).setValue( 'last-name' ); + await wrapper.find( '#last-name' ).trigger( 'blur' ); + + await wrapper.find( '#company-name' ).setValue( 'company-name' ); + await wrapper.find( '#company-name' ).trigger( 'blur' ); + + await wrapper.find( '#street' ).setValue( 'street' ); + await wrapper.find( '#street' ).trigger( 'blur' ); + + await wrapper.find( '#post-code' ).setValue( '12345' ); + await wrapper.find( '#post-code' ).trigger( 'blur' ); + + await wrapper.find( '#city' ).setValue( 'city' ); + await wrapper.find( '#city' ).trigger( 'blur' ); + + await wrapper.find( '#country' ).setValue( countries[ 0 ].countryFullName ); + await wrapper.find( '#country' ).trigger( 'blur' ); + + await wrapper.find( '#email' ).setValue( 'joe@dolan.com' ); + await wrapper.find( '#email' ).trigger( 'blur' ); + + await jest.runAllTimersAsync(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeFalsy(); + } ); + + it( 'submits the form for a person', async () => { + mockedAxios.post.mockResolvedValue( { data: { status: 'OK' } } ); + const wrapper = getWrapper(); + + const submitForm = wrapper.find( '#donation-form-submit-values' ); + submitForm.element.submit = jest.fn(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="paymentType"][value="BEZ"]' ).trigger( 'change' ); + + await wrapper.find( '#account-number' ).setValue( IBAN ); + await wrapper.find( '#account-number' ).trigger( 'blur' ); + + await wrapper.find( 'input[name="salutation"][value="Mr"]' ).trigger( 'change' ); + + await wrapper.find( '#first-name' ).setValue( 'first-name' ); + await wrapper.find( '#first-name' ).trigger( 'blur' ); + + await wrapper.find( '#last-name' ).setValue( 'last-name' ); + await wrapper.find( '#last-name' ).trigger( 'blur' ); + + await wrapper.find( '#email' ).setValue( 'joe@dolan.com' ); + await wrapper.find( '#email' ).trigger( 'blur' ); + + await wrapper.find( 'input[name="donationReceipt"][value="true"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="addressTypeSelector"][value="0"]' ).trigger( 'change' ); + + await wrapper.find( '#street' ).setValue( 'street' ); + await wrapper.find( '#street' ).trigger( 'blur' ); + + await wrapper.find( '#post-code' ).setValue( '12345' ); + await wrapper.find( '#post-code' ).trigger( 'blur' ); + + await wrapper.find( '#city' ).setValue( 'city' ); + await wrapper.find( '#city' ).trigger( 'blur' ); + + await jest.runAllTimersAsync(); + + await wrapper.find( '#country' ).setValue( countries[ 0 ].countryFullName ); + await wrapper.find( '#country' ).trigger( 'blur' ); + + await wrapper.find( '#donation-form' ).trigger( 'submit' ); + + await jest.runAllTimersAsync(); + await flushPromises(); + + expect( submitForm.element.submit ).toHaveBeenCalled(); + } ); + + it( 'submits the form for a company', async () => { + mockedAxios.post.mockResolvedValue( { data: { status: 'OK' } } ); + const wrapper = getWrapper(); + + const submitForm = wrapper.find( '#donation-form-submit-values' ); + submitForm.element.submit = jest.fn(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="paymentType"][value="BEZ"]' ).trigger( 'change' ); + + await wrapper.find( '#account-number' ).setValue( IBAN ); + await wrapper.find( '#account-number' ).trigger( 'blur' ); + + await wrapper.find( 'input[name="salutation"][value="Mr"]' ).trigger( 'change' ); + + await wrapper.find( '#first-name' ).setValue( 'first-name' ); + await wrapper.find( '#first-name' ).trigger( 'blur' ); + + await wrapper.find( '#last-name' ).setValue( 'last-name' ); + await wrapper.find( '#last-name' ).trigger( 'blur' ); + + await wrapper.find( '#email' ).setValue( 'joe@dolan.com' ); + await wrapper.find( '#email' ).trigger( 'blur' ); + + await wrapper.find( 'input[name="donationReceipt"][value="true"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="addressTypeSelector"][value="2"]' ).trigger( 'change' ); + + await wrapper.find( '#company-name' ).setValue( 'company-name' ); + await wrapper.find( '#company-name' ).trigger( 'blur' ); + + await wrapper.find( '#street' ).setValue( 'street' ); + await wrapper.find( '#street' ).trigger( 'blur' ); + + await wrapper.find( '#post-code' ).setValue( '12345' ); + await wrapper.find( '#post-code' ).trigger( 'blur' ); + + await wrapper.find( '#city' ).setValue( 'city' ); + await wrapper.find( '#city' ).trigger( 'blur' ); + + await jest.runAllTimersAsync(); + + await wrapper.find( '#country' ).setValue( countries[ 0 ].countryFullName ); + await wrapper.find( '#country' ).trigger( 'blur' ); + + await wrapper.find( '#donation-form' ).trigger( 'submit' ); + + await jest.runAllTimersAsync(); + await flushPromises(); + + expect( submitForm.element.submit ).toHaveBeenCalled(); + } ); + + it( 'submits the form for anonymous', async () => { + mockedAxios.post.mockResolvedValue( { data: { status: 'OK' } } ); + const wrapper = getWrapper(); + + const submitForm = wrapper.find( '#donation-form-submit-values' ); + submitForm.element.submit = jest.fn(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="paymentType"][value="BEZ"]' ).trigger( 'change' ); + + await wrapper.find( '#account-number' ).setValue( IBAN ); + await wrapper.find( '#account-number' ).trigger( 'blur' ); + + await wrapper.find( 'input[name="salutation"][value="Mr"]' ).trigger( 'change' ); + + await wrapper.find( '#first-name' ).setValue( 'first-name' ); + await wrapper.find( '#first-name' ).trigger( 'blur' ); + + await wrapper.find( '#last-name' ).setValue( 'last-name' ); + await wrapper.find( '#last-name' ).trigger( 'blur' ); + + await wrapper.find( '#email' ).setValue( 'joe@dolan.com' ); + await wrapper.find( '#email' ).trigger( 'blur' ); + + await wrapper.find( 'input[name="donationReceipt"][value="false"]' ).trigger( 'change' ); + + await wrapper.find( '#donation-form' ).trigger( 'submit' ); + + await jest.runAllTimersAsync(); + await flushPromises(); + + expect( submitForm.element.submit ).toHaveBeenCalled(); + } ); +} ); diff --git a/tests/unit/components/pages/donation_form/DonationFormReceiptAlternateOrder.spec.ts b/tests/unit/components/pages/donation_form/DonationFormReceiptAlternateOrder.spec.ts new file mode 100644 index 000000000..1f099a457 --- /dev/null +++ b/tests/unit/components/pages/donation_form/DonationFormReceiptAlternateOrder.spec.ts @@ -0,0 +1,469 @@ +import { flushPromises, mount, VueWrapper } from '@vue/test-utils'; +import DonationForm from '@src/components/pages/DonationForm.vue'; +import countries from '@test/data/countries'; +import { AddressValidation } from '@src/view_models/Validation'; +import { createFeatureToggle } from '@src/util/createFeatureToggle'; +import { createStore } from '@src/store/donation_store'; +import { FakeBankValidationResource } from '@test/unit/TestDoubles/FakeBankValidationResource'; +import { nextTick } from 'vue'; +import axios from 'axios'; + +jest.mock( 'axios' ); +const mockedAxios = axios as jest.Mocked; + +declare global { + namespace NodeJS { + interface Global { + window: Window; + } + } +} + +const IBAN = 'DE12500105170648489890'; + +const errorSummaryItemIsFunctional = ( wrapper: VueWrapper, formElement: string, scrollElement: string ): boolean => { + const errorItemExists = wrapper.find( `.error-summary a[href="#${formElement}"]` ).exists(); + const formElementExists = wrapper.find( `#${formElement}` ).exists(); + const scrollElementExists = wrapper.find( `#${scrollElement}` ).exists(); + + return errorItemExists && formElementExists && scrollElementExists; +}; + +describe( 'DonationForm.vue (with receipt question field and alternate order)', () => { + + beforeEach( () => { + global.window.scrollTo = jest.fn(); + jest.useFakeTimers(); + } ); + + afterEach( () => { + jest.clearAllMocks(); + document.getElementsByTagName( 'html' )[ 0 ].innerHTML = ''; + } ); + + const getWrapper = (): VueWrapper => { + const store = createStore(); + return mount( DonationForm, { + props: { + assetsPath: '', + paymentAmounts: [ 500, 1000, 2000 ], + paymentIntervals: [ 0, 1, 3, 6, 12 ], + paymentTypes: [ 'BEZ', 'PPL', 'UEB', 'BTC' ], + validateAddressUrl: 'https://example.com/address-check', + countries: countries, + trackingData: { bannerImpressionCount: 0, impressionCount: 0 }, + campaignValues: { campaign: 'nicholas', keyword: 'cage' }, + validateEmailUrl: '', + validateBankDataUrl: '', + validateLegacyBankDataUrl: '', + salutations: [ + { + label: 'Mr', + value: 'Mr', + display: 'Mr', + greetings: { + formal: 'Mr', + informal: 'Mr', + lastNameInformal: 'Mr', + }, + }, + { + label: 'Ms', + value: 'Ms', + display: 'Ms', + greetings: { + formal: 'Ms', + informal: 'Ms', + lastNameInformal: 'Ms', + }, + }, + ], + addressValidationPatterns: { postcode: '', country: null } as AddressValidation, + }, + global: { + plugins: [ store ], + provide: { + bankValidationResource: new FakeBankValidationResource(), + }, + components: { + FeatureToggle: createFeatureToggle( [ 'campaigns.address_pages.test_02', 'campaigns.address_field_order.new_order' ] ), + }, + }, + attachTo: document.body, + } ); + }; + + it( 'handles the error summary when no receipt option was selected before submitting', async () => { + const wrapper = getWrapper(); + + await wrapper.find( '#donation-form' ).trigger( 'submit' ); + await nextTick(); + await nextTick(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'amount-500', 'payment-form-amount-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'paymentType-0', 'payment-form-type-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'salutation-0', 'salutation-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'first-name', 'first-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'last-name', 'last-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'email', 'email-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'donationReceipt-0', 'receipt-scroll-target' ) ).toBeTruthy(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="paymentType"][value="PPL"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="salutation"][value="Mr"]' ).trigger( 'change' ); + + await wrapper.find( '#first-name' ).setValue( 'first-name' ); + await wrapper.find( '#first-name' ).trigger( 'blur' ); + + await wrapper.find( '#last-name' ).setValue( 'last-name' ); + await wrapper.find( '#last-name' ).trigger( 'blur' ); + + await wrapper.find( '#email' ).setValue( 'joe@dolan.com' ); + await wrapper.find( '#email' ).trigger( 'blur' ); + + await wrapper.find( 'input[name="donationReceipt"][value="false"]' ).trigger( 'change' ); + + await jest.runAllTimersAsync(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeFalsy(); + } ); + + it( 'handles the error summary when only receipt option yes was selected before submitting', async () => { + const wrapper = getWrapper(); + + await wrapper.find( 'input[name="donationReceipt"][value="true"]' ).trigger( 'change' ); + await wrapper.find( '#country' ).setValue( 'I am clearly not a country' ); + await wrapper.find( '#country' ).trigger( 'blur' ); + await jest.runAllTimersAsync(); + + await wrapper.find( '#donation-form' ).trigger( 'submit' ); + await nextTick(); + await nextTick(); + + expect( errorSummaryItemIsFunctional( wrapper, 'paymentType-0', 'payment-form-type-scroll-target' ) ).toBeTruthy(); + + // Make the IBAN field appear + await wrapper.find( 'input[name="paymentType"][value="BEZ"]' ).trigger( 'change' ); + await wrapper.find( '#donation-form' ).trigger( 'submit' ); + await nextTick(); + await nextTick(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'amount-500', 'payment-form-amount-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'account-number', 'account-number-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'salutation-0', 'salutation-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'first-name', 'first-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'last-name', 'last-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'email', 'email-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'addressType-0', 'address-type-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'street', 'street-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'post-code', 'post-code-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'city', 'city-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'country', 'country-scroll-target' ) ).toBeTruthy(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="salutation"][value="Mr"]' ).trigger( 'change' ); + + await wrapper.find( '#account-number' ).setValue( IBAN ); + await wrapper.find( '#account-number' ).trigger( 'blur' ); + + await wrapper.find( '#first-name' ).setValue( 'first-name' ); + await wrapper.find( '#first-name' ).trigger( 'blur' ); + + await wrapper.find( '#last-name' ).setValue( 'last-name' ); + await wrapper.find( '#last-name' ).trigger( 'blur' ); + + await wrapper.find( 'input[name="addressTypeSelector"][value="0"]' ).trigger( 'change' ); + + await wrapper.find( '#street' ).setValue( 'street' ); + await wrapper.find( '#street' ).trigger( 'blur' ); + + await wrapper.find( '#post-code' ).setValue( '12345' ); + await wrapper.find( '#post-code' ).trigger( 'blur' ); + + await wrapper.find( '#city' ).setValue( 'city' ); + await wrapper.find( '#city' ).trigger( 'blur' ); + + await wrapper.find( '#country' ).setValue( countries[ 0 ].countryFullName ); + await wrapper.find( '#country' ).trigger( 'blur' ); + + await wrapper.find( '#email' ).setValue( 'joe@dolan.com' ); + await wrapper.find( '#email' ).trigger( 'blur' ); + + await jest.runAllTimersAsync(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeFalsy(); + } ); + + it( 'handles the error summary when person address type was selected before submitting', async () => { + const wrapper = getWrapper(); + + await wrapper.find( 'input[name="donationReceipt"][value="true"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="addressTypeSelector"][value="0"]' ).trigger( 'change' ); + await wrapper.find( '#country' ).setValue( 'I am clearly not a country' ); + await wrapper.find( '#country' ).trigger( 'blur' ); + await jest.runAllTimersAsync(); + + await wrapper.find( '#donation-form' ).trigger( 'submit' ); + await nextTick(); + await nextTick(); + + expect( errorSummaryItemIsFunctional( wrapper, 'paymentType-0', 'payment-form-type-scroll-target' ) ).toBeTruthy(); + + // Make the IBAN field appear + await wrapper.find( 'input[name="paymentType"][value="BEZ"]' ).trigger( 'change' ); + await wrapper.find( '#donation-form' ).trigger( 'submit' ); + await nextTick(); + await nextTick(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'amount-500', 'payment-form-amount-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'account-number', 'account-number-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'salutation-0', 'salutation-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'first-name', 'first-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'last-name', 'last-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'email', 'email-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'street', 'street-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'post-code', 'post-code-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'city', 'city-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'country', 'country-scroll-target' ) ).toBeTruthy(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="salutation"][value="Mr"]' ).trigger( 'change' ); + + await wrapper.find( '#account-number' ).setValue( IBAN ); + await wrapper.find( '#account-number' ).trigger( 'blur' ); + + await wrapper.find( '#first-name' ).setValue( 'first-name' ); + await wrapper.find( '#first-name' ).trigger( 'blur' ); + + await wrapper.find( '#last-name' ).setValue( 'last-name' ); + await wrapper.find( '#last-name' ).trigger( 'blur' ); + + await wrapper.find( '#street' ).setValue( 'street' ); + await wrapper.find( '#street' ).trigger( 'blur' ); + + await wrapper.find( '#post-code' ).setValue( '12345' ); + await wrapper.find( '#post-code' ).trigger( 'blur' ); + + await wrapper.find( '#city' ).setValue( 'city' ); + await wrapper.find( '#city' ).trigger( 'blur' ); + + await wrapper.find( '#country' ).setValue( countries[ 0 ].countryFullName ); + await wrapper.find( '#country' ).trigger( 'blur' ); + + await wrapper.find( '#email' ).setValue( 'joe@dolan.com' ); + await wrapper.find( '#email' ).trigger( 'blur' ); + + await jest.runAllTimersAsync(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeFalsy(); + } ); + + it( 'handles the error summary when company address type was selected before submitting', async () => { + const wrapper = getWrapper(); + + await wrapper.find( 'input[name="donationReceipt"][value="true"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="addressTypeSelector"][value="2"]' ).trigger( 'change' ); + await nextTick(); + + await wrapper.find( '#country' ).setValue( 'I am clearly not a country' ); + await wrapper.find( '#country' ).trigger( 'blur' ); + await jest.runAllTimersAsync(); + + await wrapper.find( '#donation-form' ).trigger( 'submit' ); + await nextTick(); + await nextTick(); + + expect( errorSummaryItemIsFunctional( wrapper, 'paymentType-0', 'payment-form-type-scroll-target' ) ).toBeTruthy(); + + // Make the IBAN field appear + await wrapper.find( 'input[name="paymentType"][value="BEZ"]' ).trigger( 'change' ); + await wrapper.find( '#donation-form' ).trigger( 'submit' ); + await nextTick(); + await nextTick(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'amount-500', 'payment-form-amount-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'account-number', 'account-number-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'salutation-0', 'salutation-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'first-name', 'first-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'last-name', 'last-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'email', 'email-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'company-name', 'company-name-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'street', 'street-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'post-code', 'post-code-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'city', 'city-scroll-target' ) ).toBeTruthy(); + expect( errorSummaryItemIsFunctional( wrapper, 'country', 'country-scroll-target' ) ).toBeTruthy(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="salutation"][value="Mr"]' ).trigger( 'change' ); + + await wrapper.find( '#account-number' ).setValue( IBAN ); + await wrapper.find( '#account-number' ).trigger( 'blur' ); + + await wrapper.find( '#first-name' ).setValue( 'first-name' ); + await wrapper.find( '#first-name' ).trigger( 'blur' ); + + await wrapper.find( '#last-name' ).setValue( 'last-name' ); + await wrapper.find( '#last-name' ).trigger( 'blur' ); + + await wrapper.find( '#company-name' ).setValue( 'company-name' ); + await wrapper.find( '#company-name' ).trigger( 'blur' ); + + await wrapper.find( '#street' ).setValue( 'street' ); + await wrapper.find( '#street' ).trigger( 'blur' ); + + await wrapper.find( '#post-code' ).setValue( '12345' ); + await wrapper.find( '#post-code' ).trigger( 'blur' ); + + await wrapper.find( '#city' ).setValue( 'city' ); + await wrapper.find( '#city' ).trigger( 'blur' ); + + await wrapper.find( '#country' ).setValue( countries[ 0 ].countryFullName ); + await wrapper.find( '#country' ).trigger( 'blur' ); + + await wrapper.find( '#email' ).setValue( 'joe@dolan.com' ); + await wrapper.find( '#email' ).trigger( 'blur' ); + + await jest.runAllTimersAsync(); + + expect( wrapper.find( '.error-summary' ).exists() ).toBeFalsy(); + } ); + + it( 'submits the form for a person', async () => { + mockedAxios.post.mockResolvedValue( { data: { status: 'OK' } } ); + const wrapper = getWrapper(); + + const submitForm = wrapper.find( '#donation-form-submit-values' ); + submitForm.element.submit = jest.fn(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="paymentType"][value="BEZ"]' ).trigger( 'change' ); + + await wrapper.find( '#account-number' ).setValue( IBAN ); + await wrapper.find( '#account-number' ).trigger( 'blur' ); + + await wrapper.find( 'input[name="salutation"][value="Mr"]' ).trigger( 'change' ); + + await wrapper.find( '#first-name' ).setValue( 'first-name' ); + await wrapper.find( '#first-name' ).trigger( 'blur' ); + + await wrapper.find( '#last-name' ).setValue( 'last-name' ); + await wrapper.find( '#last-name' ).trigger( 'blur' ); + + await wrapper.find( '#email' ).setValue( 'joe@dolan.com' ); + await wrapper.find( '#email' ).trigger( 'blur' ); + + await wrapper.find( 'input[name="donationReceipt"][value="true"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="addressTypeSelector"][value="0"]' ).trigger( 'change' ); + + await wrapper.find( '#street' ).setValue( 'street' ); + await wrapper.find( '#street' ).trigger( 'blur' ); + + await wrapper.find( '#post-code' ).setValue( '12345' ); + await wrapper.find( '#post-code' ).trigger( 'blur' ); + + await wrapper.find( '#city' ).setValue( 'city' ); + await wrapper.find( '#city' ).trigger( 'blur' ); + + await jest.runAllTimersAsync(); + + await wrapper.find( '#country' ).setValue( countries[ 0 ].countryFullName ); + await wrapper.find( '#country' ).trigger( 'blur' ); + + await wrapper.find( '#donation-form' ).trigger( 'submit' ); + + await jest.runAllTimersAsync(); + await flushPromises(); + + expect( submitForm.element.submit ).toHaveBeenCalled(); + } ); + + it( 'submits the form for a company', async () => { + mockedAxios.post.mockResolvedValue( { data: { status: 'OK' } } ); + const wrapper = getWrapper(); + + const submitForm = wrapper.find( '#donation-form-submit-values' ); + submitForm.element.submit = jest.fn(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="paymentType"][value="BEZ"]' ).trigger( 'change' ); + + await wrapper.find( '#account-number' ).setValue( IBAN ); + await wrapper.find( '#account-number' ).trigger( 'blur' ); + + await wrapper.find( 'input[name="salutation"][value="Mr"]' ).trigger( 'change' ); + + await wrapper.find( '#first-name' ).setValue( 'first-name' ); + await wrapper.find( '#first-name' ).trigger( 'blur' ); + + await wrapper.find( '#last-name' ).setValue( 'last-name' ); + await wrapper.find( '#last-name' ).trigger( 'blur' ); + + await wrapper.find( '#email' ).setValue( 'joe@dolan.com' ); + await wrapper.find( '#email' ).trigger( 'blur' ); + + await wrapper.find( 'input[name="donationReceipt"][value="true"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="addressTypeSelector"][value="2"]' ).trigger( 'change' ); + + await wrapper.find( '#company-name' ).setValue( 'company-name' ); + await wrapper.find( '#company-name' ).trigger( 'blur' ); + + await wrapper.find( '#street' ).setValue( 'street' ); + await wrapper.find( '#street' ).trigger( 'blur' ); + + await wrapper.find( '#post-code' ).setValue( '12345' ); + await wrapper.find( '#post-code' ).trigger( 'blur' ); + + await wrapper.find( '#city' ).setValue( 'city' ); + await wrapper.find( '#city' ).trigger( 'blur' ); + + await jest.runAllTimersAsync(); + + await wrapper.find( '#country' ).setValue( countries[ 0 ].countryFullName ); + await wrapper.find( '#country' ).trigger( 'blur' ); + + await wrapper.find( '#donation-form' ).trigger( 'submit' ); + + await jest.runAllTimersAsync(); + await flushPromises(); + + expect( submitForm.element.submit ).toHaveBeenCalled(); + } ); + + it( 'submits the form for anonymous', async () => { + mockedAxios.post.mockResolvedValue( { data: { status: 'OK' } } ); + const wrapper = getWrapper(); + + const submitForm = wrapper.find( '#donation-form-submit-values' ); + submitForm.element.submit = jest.fn(); + + await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' ); + await wrapper.find( 'input[name="paymentType"][value="BEZ"]' ).trigger( 'change' ); + + await wrapper.find( '#account-number' ).setValue( IBAN ); + await wrapper.find( '#account-number' ).trigger( 'blur' ); + + await wrapper.find( 'input[name="salutation"][value="Mr"]' ).trigger( 'change' ); + + await wrapper.find( '#first-name' ).setValue( 'first-name' ); + await wrapper.find( '#first-name' ).trigger( 'blur' ); + + await wrapper.find( '#last-name' ).setValue( 'last-name' ); + await wrapper.find( '#last-name' ).trigger( 'blur' ); + + await wrapper.find( '#email' ).setValue( 'joe@dolan.com' ); + await wrapper.find( '#email' ).trigger( 'blur' ); + + await wrapper.find( 'input[name="donationReceipt"][value="false"]' ).trigger( 'change' ); + + await wrapper.find( '#donation-form' ).trigger( 'submit' ); + + await jest.runAllTimersAsync(); + await flushPromises(); + + expect( submitForm.element.submit ).toHaveBeenCalled(); + } ); +} ); 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 eaa248844..809f299ec 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,6 +1,4 @@ -import { flushPromises, mount, VueWrapper } from '@vue/test-utils'; - -import axios from 'axios'; +import { mount, VueWrapper } from '@vue/test-utils'; import { createStore } from '@src/store/donation_store'; import { action } from '@src/store/util'; import { AddressTypeModel } from '@src/view_models/AddressTypeModel'; @@ -11,7 +9,6 @@ import { CampaignValues } from '@src/view_models/CampaignValues'; import { AddressValidation } from '@src/view_models/Validation'; 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'; @@ -37,9 +34,6 @@ const salutations: Salutation[] = [ }, ]; -jest.mock( 'axios' ); -const mockedAxios = axios as jest.Mocked; - describe( 'PersonalDataSection.vue', () => { const getWrapper = ( store: Store = createStore() ): { wrapper: VueWrapper, store: Store } => { const wrapper = mount( PersonalDataSection, { @@ -130,137 +124,6 @@ describe( 'PersonalDataSection.vue', () => { expect( scrollElement.scrollIntoView ).toHaveBeenCalledWith( { behavior: 'smooth' } ); } ); - it( 'shows and hides the error summary', async () => { - jest.useFakeTimers(); - - 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 wrapper.find( '#addressType-0' ).trigger( 'change' ); - await wrapper.find( '#person-salutation-0' ).trigger( 'change' ); - - await wrapper.find( '#person-first-name' ).setValue( 'first-name' ); - await wrapper.find( '#person-first-name' ).trigger( 'blur' ); - - await wrapper.find( '#person-last-name' ).setValue( 'last-name' ); - await wrapper.find( '#person-last-name' ).trigger( 'blur' ); - - await wrapper.find( '#person-street' ).setValue( 'street' ); - await wrapper.find( '#person-street' ).trigger( 'blur' ); - - await wrapper.find( '#person-post-code' ).setValue( 'post-code' ); - await wrapper.find( '#person-post-code' ).trigger( 'blur' ); - - await wrapper.find( '#person-city' ).setValue( 'city' ); - await wrapper.find( '#person-city' ).trigger( 'blur' ); - - await wrapper.find( '#person-country' ).setValue( 'country' ); - await wrapper.find( '#person-country' ).trigger( 'blur' ); - - await wrapper.find( '#person-email' ).setValue( 'joe@dolan.com' ); - await wrapper.find( '#person-email' ).trigger( 'blur' ); - - await jest.runAllTimersAsync(); - - expect( wrapper.find( '.error-summary' ).exists() ).toBeFalsy(); - - jest.clearAllMocks(); - } ); - - it( 'shows and hides the error summary when payment data is invalid', async () => { - jest.useFakeTimers(); - - const { wrapper, store } = getWrapper(); - - await setPaymentTypeAndInitializeOtherPaymentValues( store, 'BEZ' ); - - await wrapper.find( '#submit-btn' ).trigger( 'click' ); - await nextTick(); - await nextTick(); - - expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); - - await wrapper.find( '#addressType-0' ).trigger( 'change' ); - await wrapper.find( '#person-salutation-0' ).trigger( 'change' ); - - await wrapper.find( '#person-first-name' ).setValue( 'first-name' ); - await wrapper.find( '#person-first-name' ).trigger( 'blur' ); - - await wrapper.find( '#person-last-name' ).setValue( 'last-name' ); - await wrapper.find( '#person-last-name' ).trigger( 'blur' ); - - await wrapper.find( '#person-street' ).setValue( 'street' ); - await wrapper.find( '#person-street' ).trigger( 'blur' ); - - await wrapper.find( '#person-post-code' ).setValue( 'post-code' ); - await wrapper.find( '#person-post-code' ).trigger( 'blur' ); - - await wrapper.find( '#person-city' ).setValue( 'city' ); - await wrapper.find( '#person-city' ).trigger( 'blur' ); - - await jest.runAllTimersAsync(); - - await wrapper.find( '#person-country' ).setValue( 'country' ); - await wrapper.find( '#person-country' ).trigger( 'blur' ); - - await wrapper.find( '#person-email' ).setValue( 'joe@dolan.com' ); - await wrapper.find( '#person-email' ).trigger( 'blur' ); - - expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); - - await wrapper.find( '#account-number' ).setValue( 'DE12500105170648489890' ); - await wrapper.find( '#account-number' ).trigger( 'blur' ); - - await flushPromises(); - - expect( wrapper.find( '.error-summary' ).exists() ).toBeFalsy(); - - jest.clearAllMocks(); - } ); - - test.each( [ - [ '', 10 ], - [ '#addressType-0', 9 ], - [ '#addressType-1', 7 ], - ] )( 'focuses inputs on error summary clicks', async ( addressTypeSelector: string, numberOfErrors: number ) => { - jest.useFakeTimers(); - - const { wrapper, store } = getWrapper(); - - await setPaymentTypeAndInitializeOtherPaymentValues( store, 'BEZ' ); - - if ( addressTypeSelector !== '' ) { - await wrapper.find( addressTypeSelector ).trigger( 'change' ); - } - - await wrapper.find( '#person-country' ).setValue( 'I am clearly not a country' ); - await wrapper.find( '#person-country' ).trigger( 'blur' ); - - await jest.runAllTimersAsync(); - - await wrapper.find( '#submit-btn' ).trigger( 'click' ); - await nextTick(); - await nextTick(); - - const errorLinks = wrapper.findAll( '.error-summary-list a' ); - - expect( errorLinks.length ).toStrictEqual( numberOfErrors ); - - errorLinks.forEach( x => { - expect( wrapper.find( x.attributes( 'href' ) ).exists() ).toBeTruthy(); - expect( wrapper.find( '#' + x.attributes( 'data-scroll-element' ) ).exists() ).toBeTruthy(); - } ); - - jest.clearAllMocks(); - } ); - it( 'updates full selected', async () => { const { wrapper } = getWrapper(); @@ -279,38 +142,4 @@ describe( 'PersonalDataSection.vue', () => { 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, - receipt: true, - fields: [ - { name: 'salutation', value: 'Mr', validity: Validity.RESTORED }, - { name: 'title', value: 'Dr', validity: Validity.RESTORED }, - { name: 'firstName', value: 'value', validity: Validity.RESTORED }, - { name: 'lastName', value: 'value', validity: Validity.RESTORED }, - { name: 'street', value: 'value', validity: Validity.RESTORED }, - { name: 'postcode', value: '12345', validity: Validity.RESTORED }, - { name: 'city', value: 'value', validity: Validity.RESTORED }, - { name: 'country', value: 'value', validity: Validity.RESTORED }, - { name: 'email', value: 'value@gmail.com', validity: Validity.RESTORED }, - { name: 'companyName', value: 'value', validity: Validity.RESTORED }, - ], - } ); - - mockedAxios.post.mockResolvedValue( { data: { status: 'OK' } } ); - const { wrapper } = getWrapper( store ); - - const submitForm = wrapper.find( '#submit-form' ); - submitForm.element.submit = jest.fn(); - - await wrapper.find( '#submit-btn' ).trigger( 'click' ); - await flushPromises(); - - expect( submitForm.element.submit ).toHaveBeenCalled(); - } ); - } ); 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 f94c61e60..625ce312a 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 @@ -1,16 +1,11 @@ -import { flushPromises, mount, VueWrapper } from '@vue/test-utils'; - -import axios from 'axios'; +import { mount, VueWrapper } from '@vue/test-utils'; import { createStore } from '@src/store/donation_store'; import { action } from '@src/store/util'; -import { AddressTypeModel } from '@src/view_models/AddressTypeModel'; import { createFeatureToggle } from '@src/util/createFeatureToggle'; import { Store } from 'vuex'; import { TrackingData } from '@src/view_models/TrackingData'; import { CampaignValues } from '@src/view_models/CampaignValues'; import { AddressValidation } from '@src/view_models/Validation'; -import { nextTick } from 'vue'; -import { Validity } from '@src/view_models/Validity'; import { Salutation } from '@src/view_models/Salutation'; import PersonalDataSectionDonationReceipt from '@src/components/pages/donation_form/singlePageFormSections/PersonalDataSectionDonationReceipt.vue'; import BankFields from '@src/components/shared/BankFields.vue'; @@ -36,9 +31,6 @@ const salutations: Salutation[] = [ }, ]; -jest.mock( 'axios' ); -const mockedAxios = axios as jest.Mocked; - describe( 'PersonalDataSectionDonationReceipt.vue', () => { const getWrapper = ( store: Store = createStore() ): { wrapper: VueWrapper, store: Store } => { const wrapper = mount( PersonalDataSectionDonationReceipt, { @@ -117,208 +109,6 @@ describe( 'PersonalDataSectionDonationReceipt.vue', () => { 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 wrapper.find( '#donationReceipt-0' ).trigger( 'change' ); - await wrapper.find( '#addressType-0' ).trigger( 'change' ); - await wrapper.find( '#salutation-0' ).trigger( 'change' ); - - await wrapper.find( '#first-name' ).setValue( 'first-name' ); - await wrapper.find( '#first-name' ).trigger( 'blur' ); - - await wrapper.find( '#last-name' ).setValue( 'last-name' ); - await wrapper.find( '#last-name' ).trigger( 'blur' ); - - await wrapper.find( '#street' ).setValue( 'street' ); - await wrapper.find( '#street' ).trigger( 'blur' ); - - await wrapper.find( '#post-code' ).setValue( 'post-code' ); - await wrapper.find( '#post-code' ).trigger( 'blur' ); - - await wrapper.find( '#city' ).setValue( 'city' ); - await wrapper.find( '#city' ).trigger( 'blur' ); - - await wrapper.find( '#country' ).setValue( 'country' ); - await wrapper.find( '#country' ).trigger( 'blur' ); - - await wrapper.find( '#email' ).setValue( 'joe@dolan.com' ); - await wrapper.find( '#email' ).trigger( 'blur' ); - - expect( wrapper.find( '.error-summary' ).exists() ).toBeFalsy(); - } ); - - it( 'shows and hides the error summary when payment data is invalid', async () => { - jest.useFakeTimers(); - - const { wrapper, store } = getWrapper(); - - await setPaymentType( store, 'BEZ' ); - - await wrapper.find( '#donation-form' ).trigger( 'submit' ); - await nextTick(); - await nextTick(); - - expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); - - await wrapper.find( '#donationReceipt-0' ).trigger( 'change' ); - await wrapper.find( '#addressType-0' ).trigger( 'change' ); - await wrapper.find( '#salutation-0' ).trigger( 'change' ); - - await wrapper.find( '#first-name' ).setValue( 'first-name' ); - await wrapper.find( '#first-name' ).trigger( 'blur' ); - - await wrapper.find( '#last-name' ).setValue( 'last-name' ); - await wrapper.find( '#last-name' ).trigger( 'blur' ); - - await wrapper.find( '#street' ).setValue( 'street' ); - await wrapper.find( '#street' ).trigger( 'blur' ); - - await wrapper.find( '#post-code' ).setValue( 'post-code' ); - await wrapper.find( '#post-code' ).trigger( 'blur' ); - - await wrapper.find( '#city' ).setValue( 'city' ); - await wrapper.find( '#city' ).trigger( 'blur' ); - - await jest.runAllTimersAsync(); - - await wrapper.find( '#country' ).setValue( 'country' ); - await wrapper.find( '#country' ).trigger( 'blur' ); - - await wrapper.find( '#email' ).setValue( 'joe@dolan.com' ); - await wrapper.find( '#email' ).trigger( 'blur' ); - - expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); - - await wrapper.find( '#account-number' ).setValue( 'DE12500105170648489890' ); - await wrapper.find( '#account-number' ).trigger( 'blur' ); - - await flushPromises(); - - expect( wrapper.find( '.error-summary' ).exists() ).toBeFalsy(); - - jest.clearAllMocks(); - } ); - - it( 'handles all error summary clicks when no donation receipt has been selected', async () => { - const { wrapper, store } = getWrapper(); - - await setPaymentType( store, 'BEZ' ); - - await wrapper.find( '#donation-form' ).trigger( 'submit' ); - await nextTick(); - await nextTick(); - - const errorLinks = wrapper.findAll( '.error-summary-list a' ); - - expect( errorLinks.length ).toStrictEqual( 6 ); - - errorLinks.forEach( x => { - expect( wrapper.find( x.attributes( 'href' ) ).exists() ).toBeTruthy(); - expect( wrapper.find( '#' + x.attributes( 'data-scroll-element' ) ).exists() ).toBeTruthy(); - } ); - } ); - - it( 'handles all error summary clicks when donation receipt has been selected', async () => { - jest.useFakeTimers(); - - const { wrapper, store } = getWrapper(); - - await setPaymentType( store, 'BEZ' ); - - await wrapper.find( '#donationReceipt-0' ).trigger( 'change' ); - - await wrapper.find( '#country' ).setValue( 'I am clearly not a country' ); - await wrapper.find( '#country' ).trigger( 'blur' ); - - await jest.runAllTimersAsync(); - - await wrapper.find( '#donation-form' ).trigger( 'submit' ); - await nextTick(); - await nextTick(); - - const errorLinks = wrapper.findAll( '.error-summary-list a' ); - - expect( errorLinks.length ).toStrictEqual( 9 ); - - errorLinks.forEach( x => { - expect( wrapper.find( x.attributes( 'href' ) ).exists() ).toBeTruthy(); - expect( wrapper.find( '#' + x.attributes( 'data-scroll-element' ) ).exists() ).toBeTruthy(); - } ); - - jest.clearAllMocks(); - } ); - - it( 'handles all error summary clicks when address type is person', async () => { - jest.useFakeTimers(); - - const { wrapper, store } = getWrapper(); - - await setPaymentType( store, 'BEZ' ); - - await wrapper.find( '#donationReceipt-0' ).trigger( 'change' ); - await wrapper.find( '#addressType-0' ).trigger( 'change' ); - - await wrapper.find( '#country' ).setValue( 'I am clearly not a country' ); - await wrapper.find( '#country' ).trigger( 'blur' ); - - await jest.runAllTimersAsync(); - - await wrapper.find( '#donation-form' ).trigger( 'submit' ); - await nextTick(); - await nextTick(); - - const errorLinks = wrapper.findAll( '.error-summary-list a' ); - - expect( errorLinks.length ).toStrictEqual( 8 ); - - errorLinks.forEach( x => { - expect( wrapper.find( x.attributes( 'href' ) ).exists() ).toBeTruthy(); - expect( wrapper.find( '#' + x.attributes( 'data-scroll-element' ) ).exists() ).toBeTruthy(); - } ); - - jest.clearAllMocks(); - } ); - - it( 'handles all error summary clicks when address type is company', async () => { - jest.useFakeTimers(); - - const { wrapper, store } = getWrapper(); - - await setPaymentType( store, 'BEZ' ); - - await wrapper.find( '#donationReceipt-0' ).trigger( 'change' ); - - await wrapper.find( '#country' ).setValue( 'I am clearly not a country' ); - await wrapper.find( '#country' ).trigger( 'blur' ); - - await jest.runAllTimersAsync(); - - await wrapper.find( '#addressType-0' ).trigger( 'change' ); - await wrapper.find( '#donation-form' ).trigger( 'submit' ); - await nextTick(); - await nextTick(); - - const errorLinks = wrapper.findAll( '.error-summary-list a' ); - - expect( errorLinks.length ).toStrictEqual( 8 ); - - errorLinks.forEach( x => { - expect( wrapper.find( x.attributes( 'href' ) ).exists() ).toBeTruthy(); - expect( wrapper.find( '#' + x.attributes( 'data-scroll-element' ) ).exists() ).toBeTruthy(); - } ); - - jest.clearAllMocks(); - } ); - it( 'validates the payment section input on page submit', async () => { const { wrapper, store } = getWrapper(); store.dispatch = jest.fn().mockResolvedValue( true ); @@ -327,38 +117,4 @@ describe( 'PersonalDataSectionDonationReceipt.vue', () => { expect( store.dispatch ).toHaveBeenCalledWith( action( 'payment', 'markEmptyValuesAsInvalid' ) ); } ); - - it( 'submits the form', async () => { - const store = createStore(); - await setPaymentType( store, 'UEB' ); - await store.dispatch( action( 'address', 'initializeAddress' ), { - addressType: AddressTypeModel.PERSON, - newsletter: true, - receipt: true, - fields: [ - { name: 'salutation', value: 'Mr', validity: Validity.RESTORED }, - { name: 'title', value: 'Dr', validity: Validity.RESTORED }, - { name: 'firstName', value: 'value', validity: Validity.RESTORED }, - { name: 'lastName', value: 'value', validity: Validity.RESTORED }, - { name: 'street', value: 'value', validity: Validity.RESTORED }, - { name: 'postcode', value: '12345', validity: Validity.RESTORED }, - { name: 'city', value: 'value', validity: Validity.RESTORED }, - { name: 'country', value: 'value', validity: Validity.RESTORED }, - { name: 'email', value: 'value@gmail.com', validity: Validity.RESTORED }, - { name: 'companyName', value: 'value', validity: Validity.RESTORED }, - ], - } ); - - mockedAxios.post.mockResolvedValue( { data: { status: 'OK' } } ); - const { wrapper } = getWrapper( store ); - - const submitForm = wrapper.find( '#donation-form-submit-values' ); - submitForm.element.submit = jest.fn(); - - await wrapper.find( '#donation-form' ).trigger( 'submit' ); - await flushPromises(); - - expect( submitForm.element.submit ).toHaveBeenCalled(); - } ); - } ); 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 1506f1c9d..ba8f28bd5 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 @@ -1,16 +1,11 @@ -import { flushPromises, mount, VueWrapper } from '@vue/test-utils'; - -import axios from 'axios'; +import { mount, VueWrapper } from '@vue/test-utils'; import { createStore } from '@src/store/donation_store'; import { action } from '@src/store/util'; -import { AddressTypeModel } from '@src/view_models/AddressTypeModel'; import { createFeatureToggle } from '@src/util/createFeatureToggle'; import { Store } from 'vuex'; import { TrackingData } from '@src/view_models/TrackingData'; import { CampaignValues } from '@src/view_models/CampaignValues'; import { AddressValidation } from '@src/view_models/Validation'; -import { nextTick } from 'vue'; -import { Validity } from '@src/view_models/Validity'; import { Salutation } from '@src/view_models/Salutation'; import PersonalDataSectionDonationReceipt from '@src/components/pages/donation_form/singlePageFormSections/PersonalDataSectionDonationReceipt.vue'; import BankFields from '@src/components/shared/BankFields.vue'; @@ -36,9 +31,6 @@ const salutations: Salutation[] = [ }, ]; -jest.mock( 'axios' ); -const mockedAxios = axios as jest.Mocked; - describe( 'PersonalDataSectionDonationReceipt.vue (With Street Autocomplete)', () => { const getWrapper = ( store: Store = createStore() ): { wrapper: VueWrapper, store: Store } => { const wrapper = mount( PersonalDataSectionDonationReceipt, { @@ -120,208 +112,6 @@ describe( 'PersonalDataSectionDonationReceipt.vue (With Street Autocomplete)', ( 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 wrapper.find( '#donationReceipt-0' ).trigger( 'change' ); - await wrapper.find( '#addressType-0' ).trigger( 'change' ); - await wrapper.find( '#salutation-0' ).trigger( 'change' ); - - await wrapper.find( '#first-name' ).setValue( 'first-name' ); - await wrapper.find( '#first-name' ).trigger( 'blur' ); - - await wrapper.find( '#last-name' ).setValue( 'last-name' ); - await wrapper.find( '#last-name' ).trigger( 'blur' ); - - await wrapper.find( '#street' ).setValue( 'street' ); - await wrapper.find( '#street' ).trigger( 'blur' ); - - await wrapper.find( '#post-code' ).setValue( 'post-code' ); - await wrapper.find( '#post-code' ).trigger( 'blur' ); - - await wrapper.find( '#city' ).setValue( 'city' ); - await wrapper.find( '#city' ).trigger( 'blur' ); - - await wrapper.find( '#country' ).setValue( 'country' ); - await wrapper.find( '#country' ).trigger( 'blur' ); - - await wrapper.find( '#email' ).setValue( 'joe@dolan.com' ); - await wrapper.find( '#email' ).trigger( 'blur' ); - - expect( wrapper.find( '.error-summary' ).exists() ).toBeFalsy(); - } ); - - it( 'shows and hides the error summary when payment data is invalid', async () => { - jest.useFakeTimers(); - - const { wrapper, store } = getWrapper(); - - await setPaymentTypeAndInitializeOtherPaymentValues( store, 'BEZ' ); - - await wrapper.find( '#donation-form' ).trigger( 'submit' ); - await nextTick(); - await nextTick(); - - expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); - - await wrapper.find( '#donationReceipt-0' ).trigger( 'change' ); - await wrapper.find( '#addressType-0' ).trigger( 'change' ); - await wrapper.find( '#salutation-0' ).trigger( 'change' ); - - await wrapper.find( '#first-name' ).setValue( 'first-name' ); - await wrapper.find( '#first-name' ).trigger( 'blur' ); - - await wrapper.find( '#last-name' ).setValue( 'last-name' ); - await wrapper.find( '#last-name' ).trigger( 'blur' ); - - await wrapper.find( '#street' ).setValue( 'street' ); - await wrapper.find( '#street' ).trigger( 'blur' ); - - await wrapper.find( '#post-code' ).setValue( 'post-code' ); - await wrapper.find( '#post-code' ).trigger( 'blur' ); - - await wrapper.find( '#city' ).setValue( 'city' ); - await wrapper.find( '#city' ).trigger( 'blur' ); - - await jest.runAllTimersAsync(); - - await wrapper.find( '#country' ).setValue( 'country' ); - await wrapper.find( '#country' ).trigger( 'blur' ); - - await wrapper.find( '#email' ).setValue( 'joe@dolan.com' ); - await wrapper.find( '#email' ).trigger( 'blur' ); - - expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); - - await wrapper.find( '#account-number' ).setValue( 'DE12500105170648489890' ); - await wrapper.find( '#account-number' ).trigger( 'blur' ); - - await flushPromises(); - - expect( wrapper.find( '.error-summary' ).exists() ).toBeFalsy(); - - jest.clearAllMocks(); - } ); - - it( 'handles all error summary clicks when no donation receipt has been selected', async () => { - const { wrapper, store } = getWrapper(); - - await setPaymentTypeAndInitializeOtherPaymentValues( store, 'BEZ' ); - - await wrapper.find( '#donation-form' ).trigger( 'submit' ); - await nextTick(); - await nextTick(); - - const errorLinks = wrapper.findAll( '.error-summary-list a' ); - - expect( errorLinks.length ).toStrictEqual( 6 ); - - errorLinks.forEach( x => { - expect( wrapper.find( x.attributes( 'href' ) ).exists() ).toBeTruthy(); - expect( wrapper.find( '#' + x.attributes( 'data-scroll-element' ) ).exists() ).toBeTruthy(); - } ); - } ); - - it( 'handles all error summary clicks when donation receipt has been selected', async () => { - jest.useFakeTimers(); - - const { wrapper, store } = getWrapper(); - - await setPaymentTypeAndInitializeOtherPaymentValues( store, 'BEZ' ); - - await wrapper.find( '#donationReceipt-0' ).trigger( 'change' ); - - await wrapper.find( '#country' ).setValue( 'I am clearly not a country' ); - await wrapper.find( '#country' ).trigger( 'blur' ); - - await jest.runAllTimersAsync(); - - await wrapper.find( '#donation-form' ).trigger( 'submit' ); - await nextTick(); - await nextTick(); - - const errorLinks = wrapper.findAll( '.error-summary-list a' ); - - expect( errorLinks.length ).toStrictEqual( 9 ); - - errorLinks.forEach( x => { - expect( wrapper.find( x.attributes( 'href' ) ).exists() ).toBeTruthy(); - expect( wrapper.find( '#' + x.attributes( 'data-scroll-element' ) ).exists() ).toBeTruthy(); - } ); - - jest.clearAllMocks(); - } ); - - it( 'handles all error summary clicks when address type is person', async () => { - jest.useFakeTimers(); - - const { wrapper, store } = getWrapper(); - - await setPaymentTypeAndInitializeOtherPaymentValues( store, 'BEZ' ); - - await wrapper.find( '#donationReceipt-0' ).trigger( 'change' ); - await wrapper.find( '#addressType-0' ).trigger( 'change' ); - - await wrapper.find( '#country' ).setValue( 'I am clearly not a country' ); - await wrapper.find( '#country' ).trigger( 'blur' ); - - await jest.runAllTimersAsync(); - - await wrapper.find( '#donation-form' ).trigger( 'submit' ); - await nextTick(); - await nextTick(); - - const errorLinks = wrapper.findAll( '.error-summary-list a' ); - - expect( errorLinks.length ).toStrictEqual( 8 ); - - errorLinks.forEach( x => { - expect( wrapper.find( x.attributes( 'href' ) ).exists() ).toBeTruthy(); - expect( wrapper.find( '#' + x.attributes( 'data-scroll-element' ) ).exists() ).toBeTruthy(); - } ); - - jest.clearAllMocks(); - } ); - - it( 'handles all error summary clicks when address type is company', async () => { - jest.useFakeTimers(); - - const { wrapper, store } = getWrapper(); - - await setPaymentTypeAndInitializeOtherPaymentValues( store, 'BEZ' ); - - await wrapper.find( '#donationReceipt-0' ).trigger( 'change' ); - - await wrapper.find( '#country' ).setValue( 'I am clearly not a country' ); - await wrapper.find( '#country' ).trigger( 'blur' ); - - await jest.runAllTimersAsync(); - - await wrapper.find( '#addressType-0' ).trigger( 'change' ); - await wrapper.find( '#donation-form' ).trigger( 'submit' ); - await nextTick(); - await nextTick(); - - const errorLinks = wrapper.findAll( '.error-summary-list a' ); - - expect( errorLinks.length ).toStrictEqual( 8 ); - - errorLinks.forEach( x => { - expect( wrapper.find( x.attributes( 'href' ) ).exists() ).toBeTruthy(); - expect( wrapper.find( '#' + x.attributes( 'data-scroll-element' ) ).exists() ).toBeTruthy(); - } ); - - jest.clearAllMocks(); - } ); - it( 'validates the payment section input on page submit', async () => { const { wrapper, store } = getWrapper(); store.dispatch = jest.fn().mockResolvedValue( true ); @@ -330,38 +120,4 @@ describe( 'PersonalDataSectionDonationReceipt.vue (With Street Autocomplete)', ( 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.PERSON, - newsletter: true, - receipt: true, - fields: [ - { name: 'salutation', value: 'Mr', validity: Validity.RESTORED }, - { name: 'title', value: 'Dr', validity: Validity.RESTORED }, - { name: 'firstName', value: 'value', validity: Validity.RESTORED }, - { name: 'lastName', value: 'value', validity: Validity.RESTORED }, - { name: 'street', value: 'value', validity: Validity.RESTORED }, - { name: 'postcode', value: '12345', validity: Validity.RESTORED }, - { name: 'city', value: 'value', validity: Validity.RESTORED }, - { name: 'country', value: 'value', validity: Validity.RESTORED }, - { name: 'email', value: 'value@gmail.com', validity: Validity.RESTORED }, - { name: 'companyName', value: 'value', validity: Validity.RESTORED }, - ], - } ); - - mockedAxios.post.mockResolvedValue( { data: { status: 'OK' } } ); - const { wrapper } = getWrapper( store ); - - const submitForm = wrapper.find( '#donation-form-submit-values' ); - submitForm.element.submit = jest.fn(); - - await wrapper.find( '#donation-form' ).trigger( 'submit' ); - await flushPromises(); - - expect( submitForm.element.submit ).toHaveBeenCalled(); - } ); - } ); 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 b7bc98804..0cd1c298b 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 @@ -1,6 +1,5 @@ -import { flushPromises, mount, VueWrapper } from '@vue/test-utils'; +import { 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'; @@ -12,7 +11,6 @@ import { CampaignValues } from '@src/view_models/CampaignValues'; import { AddressValidation } from '@src/view_models/Validation'; 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 { FakeBankValidationResource } from '@test/unit/TestDoubles/FakeBankValidationResource'; import BankFields from '@src/components/shared/BankFields.vue'; @@ -37,9 +35,6 @@ const salutations: Salutation[] = [ }, ]; -jest.mock( 'axios' ); -const mockedAxios = axios as jest.Mocked; - describe( 'PersonalDataSection.vue (With Street Autocomplete)', () => { const getWrapper = ( store: Store = createStore() ): { wrapper: VueWrapper, store: Store } => { const wrapper = mount( PersonalDataSection, { @@ -133,137 +128,6 @@ describe( 'PersonalDataSection.vue (With Street Autocomplete)', () => { expect( scrollElement.scrollIntoView ).toHaveBeenCalledWith( { behavior: 'smooth' } ); } ); - it( 'shows and hides the error summary', async () => { - jest.useFakeTimers(); - - 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 wrapper.find( '#addressType-0' ).trigger( 'change' ); - await wrapper.find( '#person-salutation-0' ).trigger( 'change' ); - - await wrapper.find( '#person-first-name' ).setValue( 'first-name' ); - await wrapper.find( '#person-first-name' ).trigger( 'blur' ); - - await wrapper.find( '#person-last-name' ).setValue( 'last-name' ); - await wrapper.find( '#person-last-name' ).trigger( 'blur' ); - - await wrapper.find( '#person-street' ).setValue( 'street' ); - await wrapper.find( '#person-street' ).trigger( 'blur' ); - - await wrapper.find( '#person-post-code' ).setValue( 'post-code' ); - await wrapper.find( '#person-post-code' ).trigger( 'blur' ); - - await wrapper.find( '#person-city' ).setValue( 'city' ); - await wrapper.find( '#person-city' ).trigger( 'blur' ); - - await wrapper.find( '#person-country' ).setValue( 'country' ); - await wrapper.find( '#person-country' ).trigger( 'blur' ); - - await wrapper.find( '#person-email' ).setValue( 'joe@dolan.com' ); - await wrapper.find( '#person-email' ).trigger( 'blur' ); - - await jest.runAllTimersAsync(); - - expect( wrapper.find( '.error-summary' ).exists() ).toBeFalsy(); - - jest.clearAllMocks(); - } ); - - it( 'shows and hides the error summary when payment data is invalid', async () => { - jest.useFakeTimers(); - - const { wrapper, store } = getWrapper(); - - await setPaymentTypeAndInitializeOtherPaymentValues( store, 'BEZ' ); - - await wrapper.find( '#submit-btn' ).trigger( 'click' ); - await nextTick(); - await nextTick(); - - expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); - - await wrapper.find( '#addressType-0' ).trigger( 'change' ); - await wrapper.find( '#person-salutation-0' ).trigger( 'change' ); - - await wrapper.find( '#person-first-name' ).setValue( 'first-name' ); - await wrapper.find( '#person-first-name' ).trigger( 'blur' ); - - await wrapper.find( '#person-last-name' ).setValue( 'last-name' ); - await wrapper.find( '#person-last-name' ).trigger( 'blur' ); - - await wrapper.find( '#person-street' ).setValue( 'street' ); - await wrapper.find( '#person-street' ).trigger( 'blur' ); - - await wrapper.find( '#person-post-code' ).setValue( 'post-code' ); - await wrapper.find( '#person-post-code' ).trigger( 'blur' ); - - await wrapper.find( '#person-city' ).setValue( 'city' ); - await wrapper.find( '#person-city' ).trigger( 'blur' ); - - await jest.runAllTimersAsync(); - - await wrapper.find( '#person-country' ).setValue( 'country' ); - await wrapper.find( '#person-country' ).trigger( 'blur' ); - - await wrapper.find( '#person-email' ).setValue( 'joe@dolan.com' ); - await wrapper.find( '#person-email' ).trigger( 'blur' ); - - expect( wrapper.find( '.error-summary' ).exists() ).toBeTruthy(); - - await wrapper.find( '#account-number' ).setValue( 'DE12500105170648489890' ); - await wrapper.find( '#account-number' ).trigger( 'blur' ); - - await flushPromises(); - - expect( wrapper.find( '.error-summary' ).exists() ).toBeFalsy(); - - jest.clearAllMocks(); - } ); - - test.each( [ - [ '', 10 ], - [ '#addressType-0', 9 ], - [ '#addressType-1', 7 ], - ] )( 'focuses inputs on error summary clicks', async ( addressTypeSelector: string, numberOfErrors: number ) => { - jest.useFakeTimers(); - - const { wrapper, store } = getWrapper(); - - await setPaymentTypeAndInitializeOtherPaymentValues( store, 'BEZ' ); - - if ( addressTypeSelector !== '' ) { - await wrapper.find( addressTypeSelector ).trigger( 'change' ); - } - - await wrapper.find( '#person-country' ).setValue( 'I am clearly not a country' ); - await wrapper.find( '#person-country' ).trigger( 'blur' ); - - await jest.runAllTimersAsync(); - - await wrapper.find( '#submit-btn' ).trigger( 'click' ); - await nextTick(); - await nextTick(); - - const errorLinks = wrapper.findAll( '.error-summary-list a' ); - - expect( errorLinks.length ).toStrictEqual( numberOfErrors ); - - errorLinks.forEach( x => { - expect( wrapper.find( x.attributes( 'href' ) ).exists() ).toBeTruthy(); - expect( wrapper.find( '#' + x.attributes( 'data-scroll-element' ) ).exists() ).toBeTruthy(); - } ); - - jest.clearAllMocks(); - } ); - it( 'updates full selected', async () => { const { wrapper } = getWrapper(); @@ -282,38 +146,4 @@ describe( 'PersonalDataSection.vue (With Street Autocomplete)', () => { 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, - receipt: true, - fields: [ - { name: 'salutation', value: 'Mr', validity: Validity.RESTORED }, - { name: 'title', value: 'Dr', validity: Validity.RESTORED }, - { name: 'firstName', value: 'value', validity: Validity.RESTORED }, - { name: 'lastName', value: 'value', validity: Validity.RESTORED }, - { name: 'street', value: 'value', validity: Validity.RESTORED }, - { name: 'postcode', value: '12345', validity: Validity.RESTORED }, - { name: 'city', value: 'value', validity: Validity.RESTORED }, - { name: 'country', value: 'value', validity: Validity.RESTORED }, - { name: 'email', value: 'value@gmail.com', validity: Validity.RESTORED }, - { name: 'companyName', value: 'value', validity: Validity.RESTORED }, - ], - } ); - - mockedAxios.post.mockResolvedValue( { data: { status: 'OK' } } ); - const { wrapper } = getWrapper( store ); - - const submitForm = wrapper.find( '#submit-form' ); - submitForm.element.submit = jest.fn(); - - await wrapper.find( '#submit-btn' ).trigger( 'click' ); - await flushPromises(); - - expect( submitForm.element.submit ).toHaveBeenCalled(); - } ); - } );