diff --git a/src/components/pages/DonationForm.vue b/src/components/pages/DonationForm.vue
index 64728c8c4..00c59f115 100644
--- a/src/components/pages/DonationForm.vue
+++ b/src/components/pages/DonationForm.vue
@@ -1,68 +1,22 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/src/components/pages/UpdateAddress.vue b/src/components/pages/UpdateAddress.vue
index d2dc5846d..8471a5eb7 100644
--- a/src/components/pages/UpdateAddress.vue
+++ b/src/components/pages/UpdateAddress.vue
@@ -116,13 +116,13 @@ import NameFields from '@src/components/shared/NameFields.vue';
import PostalAddressFields from '@src/components/shared/PostalAddressFields.vue';
import FormButton from '@src/components/shared/form_elements/FormButton.vue';
import CheckboxField from '@src/components/shared/form_fields/CheckboxField.vue';
-import { useAddressTypeFunctions } from '@src/components/pages/donation_form/AddressTypeFunctions';
-import { useReceiptModel } from '@src/components/pages/donation_form/useReceiptModel';
+import { useAddressTypeFunctions } from '@src/components/shared/composables/useAddressTypeFunctions';
import ErrorSummary from '@src/components/shared/validation_summary/ErrorSummary.vue';
import ServerMessage from '@src/components/shared/ServerMessage.vue';
import { addressTypeName } from '@src/view_models/AddressTypeModel';
import { UpdateAddressResponse } from '@src/api/UpdateAddressResponse';
import { AddressChangeResource } from '@src/api/AddressChangeResource';
+import { useReceiptModel } from '@src/components/shared/composables/useReceiptModel';
defineOptions( {
name: 'UpdateAddress',
diff --git a/src/components/pages/donation_confirmation/AddressUpdateForm.vue b/src/components/pages/donation_confirmation/AddressUpdateForm.vue
index b89a52d34..c4b12be5e 100644
--- a/src/components/pages/donation_confirmation/AddressUpdateForm.vue
+++ b/src/components/pages/donation_confirmation/AddressUpdateForm.vue
@@ -116,7 +116,7 @@ import ValueEqualsPlaceholderWarning from '@src/components/shared/ValueEqualsPla
import NameFields from '@src/components/shared/NameFields.vue';
import RadioField from '@src/components/shared/form_fields/RadioField.vue';
import PostalAddressFields from '@src/components/shared/PostalAddressFields.vue';
-import { useAddressTypeFunctions } from '@src/components/pages/donation_form/AddressTypeFunctions';
+import { useAddressTypeFunctions } from '@src/components/shared/composables/useAddressTypeFunctions';
import { MAILING_LIST_ADDRESS_PAGE } from '@src/config';
import AddressUpdateFormErrorSummaries
from '@src/components/pages/donation_confirmation/AddressUpdateFormErrorSummaries.vue';
diff --git a/src/components/pages/donation_form/AddressForms.vue b/src/components/pages/donation_form/AddressForms.vue
index e778c9c7f..7596ab5bb 100644
--- a/src/components/pages/donation_form/AddressForms.vue
+++ b/src/components/pages/donation_form/AddressForms.vue
@@ -15,30 +15,15 @@
field-id-namespace="person"
v-on:field-changed="onFieldChange"
/>
-
-
-
-
-
-
-
-
+
diff --git a/src/components/pages/donation_form/FormSections/PersonalDataSectionDonationReceipt.vue b/src/components/pages/donation_form/FormSections/PersonalDataSectionDonationReceipt.vue
index 84b2372f3..660ca1d93 100644
--- a/src/components/pages/donation_form/FormSections/PersonalDataSectionDonationReceipt.vue
+++ b/src/components/pages/donation_form/FormSections/PersonalDataSectionDonationReceipt.vue
@@ -6,7 +6,7 @@
>
{{ $t( 'donation_form_section_address_tagline' ) }}
-
-
diff --git a/src/components/pages/donation_form/PaymentSummary.vue b/src/components/pages/donation_form/PaymentSummary.vue
index 65fa132f3..fd932fd54 100644
--- a/src/components/pages/donation_form/PaymentSummary.vue
+++ b/src/components/pages/donation_form/PaymentSummary.vue
@@ -51,7 +51,7 @@ const summaryWithoutPaymentType = computed( () => {
margin: 0 0 map.get( units.$spacing, 'large' );
@include breakpoints.tablet-up {
- margin: 0 ( -( map.get( units.$spacing, 'xx-small' ) ) ) map.get( units.$spacing, 'large' );
+ margin: 0 0 map.get( units.$spacing, 'large' );
}
&-text {
diff --git a/src/components/pages/donation_form/StreetAutocomplete/PostalAddressFields.vue b/src/components/pages/donation_form/PostalAddressFields.vue
similarity index 100%
rename from src/components/pages/donation_form/StreetAutocomplete/PostalAddressFields.vue
rename to src/components/pages/donation_form/PostalAddressFields.vue
diff --git a/src/components/pages/donation_form/StreetAutocomplete/ErrorSummary.vue b/src/components/pages/donation_form/StreetAutocomplete/ErrorSummary.vue
deleted file mode 100644
index ddb5e3664..000000000
--- a/src/components/pages/donation_form/StreetAutocomplete/ErrorSummary.vue
+++ /dev/null
@@ -1,222 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/src/components/pages/donation_form/SubPages/DonationForm.vue b/src/components/pages/donation_form/SubPages/DonationForm.vue
new file mode 100644
index 000000000..944eedc27
--- /dev/null
+++ b/src/components/pages/donation_form/SubPages/DonationForm.vue
@@ -0,0 +1,141 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t( 'donation_form_section_back' ) }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/pages/donation_form/SubPages/DonationFormReceipt.vue b/src/components/pages/donation_form/SubPages/DonationFormReceipt.vue
new file mode 100644
index 000000000..1d4becdb3
--- /dev/null
+++ b/src/components/pages/donation_form/SubPages/DonationFormReceipt.vue
@@ -0,0 +1,147 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t( 'donation_form_section_back' ) }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/shared/FormSummary.vue b/src/components/shared/FormSummary.vue
index f490770c8..b8fedcaac 100644
--- a/src/components/shared/FormSummary.vue
+++ b/src/components/shared/FormSummary.vue
@@ -37,7 +37,6 @@ withDefaults( defineProps(), {
@include breakpoints.tablet-up {
padding: map.get( units.$spacing, 'small' );
- margin: 0 ( -( map.get( units.$spacing, 'small' ) ) );
}
&-content {
diff --git a/src/components/shared/SalutationLocaleAdjuster.ts b/src/components/shared/SalutationLocaleAdjuster.ts
deleted file mode 100644
index ebddaeacf..000000000
--- a/src/components/shared/SalutationLocaleAdjuster.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { Salutation } from '@src/view_models/Salutation';
-
-/*
-* This is used when a user changes language on the address form
-* It takes the old salutation and looks to see if there's a locale
-* for it. If you're thinking of improving it, please don't. There
-* is already a proposal for improving it here:
-*
-* https://phabricator.wikimedia.org/T317388
-*/
-
-const salutationValueTranslations: Record = {
- 'Herr': 'Mr',
- 'Frau': 'Ms',
- 'Mr': 'Herr',
- 'Ms': 'Frau',
- 'No Salutation': 'Keine Anrede',
- 'Keine Anrede': 'No Salutation',
-};
-
-export const adjustSalutationLocaleIfNeeded = ( salutations: Array, salutation: string ): string => {
- if ( salutation === '' ) {
- return '';
- }
-
- const currentSalutation = salutations.find( s => s.value === salutation );
-
- if ( currentSalutation !== undefined ) {
- return salutation;
- }
-
- return salutationValueTranslations[ salutation ] ?? '';
-};
diff --git a/src/components/pages/donation_form/AddressTypeFunctions.ts b/src/components/shared/composables/useAddressTypeFunctions.ts
similarity index 100%
rename from src/components/pages/donation_form/AddressTypeFunctions.ts
rename to src/components/shared/composables/useAddressTypeFunctions.ts
diff --git a/src/components/pages/donation_form/useReceiptModel.ts b/src/components/shared/composables/useReceiptModel.ts
similarity index 100%
rename from src/components/pages/donation_form/useReceiptModel.ts
rename to src/components/shared/composables/useReceiptModel.ts
diff --git a/src/pages/donation_form.ts b/src/pages/donation_form.ts
index 9be8c1d1f..481a9307d 100644
--- a/src/pages/donation_form.ts
+++ b/src/pages/donation_form.ts
@@ -67,6 +67,10 @@ dataPersister.initialize( persistenceItems ).then( () => {
action( 'address', 'initializeAddress' ),
createInitialDonationAddressValues( dataPersister, pageData.applicationVars.initialFormValues )
),
+ store.dispatch(
+ action( 'address', 'adjustSalutationLocale' ),
+ { salutations: pageData.applicationVars.salutations, salutation: store.state.address.values.salutation }
+ ),
] ).then( () => {
// ignoring result of initializeAddress
const app = createVueApp(
diff --git a/src/store/address/actions.ts b/src/store/address/actions.ts
index 00e856e2e..d8801a500 100644
--- a/src/store/address/actions.ts
+++ b/src/store/address/actions.ts
@@ -9,6 +9,8 @@ import {
import { ValidationResponse } from '@src/store/ValidationResponse';
import { AddressTypeModel, addressTypeName } from '@src/view_models/AddressTypeModel';
import { Validity } from '@src/view_models/Validity';
+import { Salutation } from '@src/view_models/Salutation';
+import { salutationValueTranslations } from '@src/view_models/salutationValueTranslations';
export const actions = {
validateAddressField( context: ActionContext, field: InputField ) {
@@ -112,5 +114,24 @@ export const actions = {
}
context.commit( 'INITIALIZE_ADDRESS', initialValues.fields );
},
+ /*
+ * This is used when a user changes language on the address form
+ * It takes the old salutation and looks to see if there's a locale
+ * for it. If you're thinking of improving it, please don't. There
+ * is already a proposal for improving it here:
+ *
+ * https://phabricator.wikimedia.org/T317388
+ */
+ adjustSalutationLocale( context: ActionContext, payload: { salutations: Salutation[], salutation: string } ): void {
+ if ( payload.salutation === '' ) {
+ return;
+ }
+ const currentSalutation = payload.salutations.find( s => s.value === payload.salutation );
+ if ( currentSalutation !== undefined ) {
+ context.commit( 'SET_SALUTATION', payload.salutation );
+ return;
+ }
+ context.commit( 'SET_SALUTATION', salutationValueTranslations[ payload.salutation ] );
+ },
};
diff --git a/src/store/address/mutations.ts b/src/store/address/mutations.ts
index 416e92db8..f6edb58f3 100644
--- a/src/store/address/mutations.ts
+++ b/src/store/address/mutations.ts
@@ -96,4 +96,7 @@ export const mutations: MutationTree = {
state.values[ field.name ] = field.value;
} );
},
+ SET_SALUTATION( state: AddressState, salutation: string ) {
+ state.values.salutation = salutation;
+ },
};
diff --git a/src/view_models/salutationValueTranslations.ts b/src/view_models/salutationValueTranslations.ts
new file mode 100644
index 000000000..cd6776338
--- /dev/null
+++ b/src/view_models/salutationValueTranslations.ts
@@ -0,0 +1,8 @@
+export const salutationValueTranslations: Record = {
+ 'Herr': 'Mr',
+ 'Frau': 'Ms',
+ 'Mr': 'Herr',
+ 'Ms': 'Frau',
+ 'No Salutation': 'Keine Anrede',
+ 'Keine Anrede': 'No Salutation',
+};
diff --git a/tests/unit/components/pages/donation_form/AddressForms.spec.ts b/tests/unit/components/pages/donation_form/AddressForms.spec.ts
index 520efcc66..497fa5e8b 100644
--- a/tests/unit/components/pages/donation_form/AddressForms.spec.ts
+++ b/tests/unit/components/pages/donation_form/AddressForms.spec.ts
@@ -55,7 +55,6 @@ describe( 'AddressForms.vue', () => {
countries: countries,
addressValidationPatterns: addressValidationPatterns,
addressType,
- isFullSelected: true,
trackingData: {
bannerImpressionCount: 1,
impressionCount: 5,
@@ -88,15 +87,13 @@ describe( 'AddressForms.vue', () => {
} );
each( [
- [ AddressTypeModel.ANON, false, 'address-type-anonymous' ],
- [ AddressTypeModel.EMAIL, false, 'address-type-email' ],
- [ AddressTypeModel.UNSET, false, 'address-type-unset' ],
- [ AddressTypeModel.UNSET, true, 'address-type-person' ],
- [ AddressTypeModel.PERSON, true, 'address-type-person' ],
- [ AddressTypeModel.COMPANY, true, 'address-type-company' ],
- ] ).test( 'adapts the class attribute', ( addressType, isFullSelected, expectedClass ) => {
+ [ AddressTypeModel.ANON, 'address-type-anonymous' ],
+ [ AddressTypeModel.EMAIL, 'address-type-email' ],
+ [ AddressTypeModel.UNSET, 'address-type-person' ],
+ [ AddressTypeModel.PERSON, 'address-type-person' ],
+ [ AddressTypeModel.COMPANY, 'address-type-company' ],
+ ] ).test( 'adapts the class attribute', ( addressType, expectedClass ) => {
const options = createOptionsForAddressType( addressType );
- options.props.isFullSelected = isFullSelected;
wrapper = mount( AddressForms, options );
expect( wrapper.classes() ).toContain( expectedClass );
} );
diff --git a/tests/unit/components/pages/donation_form/DonationForm.spec.ts b/tests/unit/components/pages/donation_form/DonationForm.spec.ts
index 97ef16edf..cf26051e1 100644
--- a/tests/unit/components/pages/donation_form/DonationForm.spec.ts
+++ b/tests/unit/components/pages/donation_form/DonationForm.spec.ts
@@ -1,8 +1,7 @@
import { flushPromises, mount, VueWrapper } from '@vue/test-utils';
-import DonationForm from '@src/components/pages/DonationForm.vue';
+import DonationForm from '@src/components/pages/donation_form/SubPages/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 { nextTick } from 'vue';
import axios from 'axios';
@@ -84,14 +83,19 @@ describe( 'DonationForm.vue', () => {
provide: {
bankValidationResource: newSucceedingBankValidationResource(),
},
- components: {
- FeatureToggle: createFeatureToggle( [ 'campaigns.address_pages.legacy' ] ),
- },
},
attachTo: document.body,
} );
};
+ it( 'sets the correct default field values', async () => {
+ const wrapper = getWrapper();
+
+ expect( wrapper.find( '#interval-0' ).element.checked ).toBeTruthy();
+ expect( wrapper.find( '#receipt-option-person' ).element.checked ).toBeTruthy();
+ expect( wrapper.find( '#person-newsletter' ).element.checked ).toBeTruthy();
+ } );
+
it( 'handles the error summary when no address type was selected before submitting', async () => {
const wrapper = getWrapper();
@@ -410,4 +414,15 @@ describe( 'DonationForm.vue', () => {
expect( submitForm.element.submit ).toHaveBeenCalled();
} );
+
+ it( 'scrolls to payment section when button for changing payment data is clicked', async () => {
+ const scrollElement = { scrollIntoView: jest.fn() };
+ Object.defineProperty( document, 'getElementById', { writable: true, configurable: true, value: () => scrollElement } );
+
+ const wrapper = getWrapper();
+
+ await wrapper.find( '#previous-btn' ).trigger( 'click' );
+
+ expect( scrollElement.scrollIntoView ).toHaveBeenCalledWith( { behavior: 'smooth' } );
+ } );
} );
diff --git a/tests/unit/components/pages/donation_form/DonationFormAlternateOrder.spec.ts b/tests/unit/components/pages/donation_form/DonationFormAlternateOrder.spec.ts
deleted file mode 100644
index 3b94eee1e..000000000
--- a/tests/unit/components/pages/donation_form/DonationFormAlternateOrder.spec.ts
+++ /dev/null
@@ -1,413 +0,0 @@
-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 { nextTick } from 'vue';
-import axios from 'axios';
-import { newSucceedingBankValidationResource } from '@test/unit/TestDoubles/SucceedingBankValidationResource';
-import { IBAN } from '@test/data/bankdata';
-
-jest.mock( 'axios' );
-const mockedAxios = axios as jest.Mocked;
-
-declare global {
- namespace NodeJS {
- interface Global {
- window: Window;
- }
- }
-}
-
-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: newSucceedingBankValidationResource(),
- },
- 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, 'iban', 'iban-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( '#iban' ).setValue( IBAN );
- await wrapper.find( '#iban' ).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, 'iban', 'iban-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( '#iban' ).setValue( IBAN );
- await wrapper.find( '#iban' ).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, 'iban', 'iban-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( '#iban' ).setValue( IBAN );
- await wrapper.find( '#iban' ).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( '#iban' ).setValue( IBAN );
- await wrapper.find( '#iban' ).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
index 00c1d53ce..917a3cfb2 100644
--- a/tests/unit/components/pages/donation_form/DonationFormReceipt.spec.ts
+++ b/tests/unit/components/pages/donation_form/DonationFormReceipt.spec.ts
@@ -1,8 +1,7 @@
import { flushPromises, mount, VueWrapper } from '@vue/test-utils';
-import DonationForm from '@src/components/pages/DonationForm.vue';
+import DonationForm from '@src/components/pages/donation_form/SubPages/DonationFormReceipt.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 { nextTick } from 'vue';
import axios from 'axios';
@@ -28,7 +27,7 @@ const errorSummaryItemIsFunctional = ( wrapper: VueWrapper, formElement: st
return errorItemExists && formElementExists && scrollElementExists;
};
-describe( 'DonationForm.vue (with receipt question field)', () => {
+describe( 'DonationFormReciept.vue', () => {
beforeEach( () => {
global.window.scrollTo = jest.fn();
@@ -84,18 +83,24 @@ describe( 'DonationForm.vue (with receipt question field)', () => {
provide: {
bankValidationResource: newSucceedingBankValidationResource(),
},
- components: {
- FeatureToggle: createFeatureToggle( [ 'campaigns.address_pages.test_02' ] ),
- },
},
attachTo: document.body,
} );
};
+ it( 'sets the correct default field values', async () => {
+ const wrapper = getWrapper();
+
+ expect( wrapper.find( '#interval-0' ).element.checked ).toBeTruthy();
+ expect( wrapper.find( '#newsletter' ).element.checked ).toBeTruthy();
+ expect( wrapper.find( '#donationReceipt-0' ).element.checked ).toBeFalsy();
+ expect( wrapper.find( '#donationReceipt-1' ).element.checked ).toBeFalsy();
+ } );
+
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 wrapper.find( '#submit-btn' ).trigger( 'click' );
await nextTick();
await nextTick();
@@ -136,7 +141,7 @@ describe( 'DonationForm.vue (with receipt question field)', () => {
await wrapper.find( '#country' ).trigger( 'blur' );
await jest.runAllTimersAsync();
- await wrapper.find( '#donation-form' ).trigger( 'submit' );
+ await wrapper.find( '#submit-btn' ).trigger( 'click' );
await nextTick();
await nextTick();
@@ -144,7 +149,7 @@ describe( 'DonationForm.vue (with receipt question field)', () => {
// Make the IBAN field appear
await wrapper.find( 'input[name="paymentType"][value="BEZ"]' ).trigger( 'change' );
- await wrapper.find( '#donation-form' ).trigger( 'submit' );
+ await wrapper.find( '#submit-btn' ).trigger( 'click' );
await nextTick();
await nextTick();
@@ -204,7 +209,7 @@ describe( 'DonationForm.vue (with receipt question field)', () => {
await wrapper.find( '#country' ).trigger( 'blur' );
await jest.runAllTimersAsync();
- await wrapper.find( '#donation-form' ).trigger( 'submit' );
+ await wrapper.find( '#submit-btn' ).trigger( 'click' );
await nextTick();
await nextTick();
@@ -212,7 +217,7 @@ describe( 'DonationForm.vue (with receipt question field)', () => {
// Make the IBAN field appear
await wrapper.find( 'input[name="paymentType"][value="BEZ"]' ).trigger( 'change' );
- await wrapper.find( '#donation-form' ).trigger( 'submit' );
+ await wrapper.find( '#submit-btn' ).trigger( 'click' );
await nextTick();
await nextTick();
@@ -271,7 +276,7 @@ describe( 'DonationForm.vue (with receipt question field)', () => {
await wrapper.find( '#country' ).trigger( 'blur' );
await jest.runAllTimersAsync();
- await wrapper.find( '#donation-form' ).trigger( 'submit' );
+ await wrapper.find( '#submit-btn' ).trigger( 'click' );
await nextTick();
await nextTick();
@@ -279,7 +284,7 @@ describe( 'DonationForm.vue (with receipt question field)', () => {
// Make the IBAN field appear
await wrapper.find( 'input[name="paymentType"][value="BEZ"]' ).trigger( 'change' );
- await wrapper.find( '#donation-form' ).trigger( 'submit' );
+ await wrapper.find( '#submit-btn' ).trigger( 'click' );
await nextTick();
await nextTick();
@@ -335,7 +340,7 @@ describe( 'DonationForm.vue (with receipt question field)', () => {
mockedAxios.post.mockResolvedValue( { data: { status: 'OK' } } );
const wrapper = getWrapper();
- const submitForm = wrapper.find( '#donation-form-submit-values' );
+ const submitForm = wrapper.find( '#submit-form' );
submitForm.element.submit = jest.fn();
await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' );
@@ -372,7 +377,7 @@ describe( 'DonationForm.vue (with receipt question field)', () => {
await wrapper.find( '#country' ).setValue( countries[ 0 ].countryFullName );
await wrapper.find( '#country' ).trigger( 'blur' );
- await wrapper.find( '#donation-form' ).trigger( 'submit' );
+ await wrapper.find( '#submit-btn' ).trigger( 'click' );
await jest.runAllTimersAsync();
await flushPromises();
@@ -384,7 +389,7 @@ describe( 'DonationForm.vue (with receipt question field)', () => {
mockedAxios.post.mockResolvedValue( { data: { status: 'OK' } } );
const wrapper = getWrapper();
- const submitForm = wrapper.find( '#donation-form-submit-values' );
+ const submitForm = wrapper.find( '#submit-form' );
submitForm.element.submit = jest.fn();
await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' );
@@ -424,7 +429,7 @@ describe( 'DonationForm.vue (with receipt question field)', () => {
await wrapper.find( '#country' ).setValue( countries[ 0 ].countryFullName );
await wrapper.find( '#country' ).trigger( 'blur' );
- await wrapper.find( '#donation-form' ).trigger( 'submit' );
+ await wrapper.find( '#submit-btn' ).trigger( 'click' );
await jest.runAllTimersAsync();
await flushPromises();
@@ -436,7 +441,7 @@ describe( 'DonationForm.vue (with receipt question field)', () => {
mockedAxios.post.mockResolvedValue( { data: { status: 'OK' } } );
const wrapper = getWrapper();
- const submitForm = wrapper.find( '#donation-form-submit-values' );
+ const submitForm = wrapper.find( '#submit-form' );
submitForm.element.submit = jest.fn();
await wrapper.find( 'input[name="amount"][value="500"]' ).trigger( 'change' );
@@ -458,7 +463,7 @@ describe( 'DonationForm.vue (with receipt question field)', () => {
await wrapper.find( 'input[name="donationReceipt"][value="false"]' ).trigger( 'change' );
- await wrapper.find( '#donation-form' ).trigger( 'submit' );
+ await wrapper.find( '#submit-btn' ).trigger( 'click' );
await jest.runAllTimersAsync();
await flushPromises();
diff --git a/tests/unit/components/pages/donation_form/DonationFormReceiptAlternateOrder.spec.ts b/tests/unit/components/pages/donation_form/DonationFormReceiptAlternateOrder.spec.ts
deleted file mode 100644
index e56bf7d82..000000000
--- a/tests/unit/components/pages/donation_form/DonationFormReceiptAlternateOrder.spec.ts
+++ /dev/null
@@ -1,468 +0,0 @@
-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 { nextTick } from 'vue';
-import axios from 'axios';
-import { newSucceedingBankValidationResource } from '@test/unit/TestDoubles/SucceedingBankValidationResource';
-import { IBAN } from '@test/data/bankdata';
-
-jest.mock( 'axios' );
-const mockedAxios = axios as jest.Mocked;
-
-declare global {
- namespace NodeJS {
- interface Global {
- window: Window;
- }
- }
-}
-
-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: newSucceedingBankValidationResource(),
- },
- 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, 'iban', 'iban-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( '#iban' ).setValue( IBAN );
- await wrapper.find( '#iban' ).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, 'iban', 'iban-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( '#iban' ).setValue( IBAN );
- await wrapper.find( '#iban' ).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, 'iban', 'iban-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( '#iban' ).setValue( IBAN );
- await wrapper.find( '#iban' ).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( '#iban' ).setValue( IBAN );
- await wrapper.find( '#iban' ).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( '#iban' ).setValue( IBAN );
- await wrapper.find( '#iban' ).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( '#iban' ).setValue( IBAN );
- await wrapper.find( '#iban' ).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/DonationReceipt/AddressFields.spec.ts b/tests/unit/components/pages/donation_form/DonationReceipt/AddressFields.spec.ts
new file mode 100644
index 000000000..95b5eb38a
--- /dev/null
+++ b/tests/unit/components/pages/donation_form/DonationReceipt/AddressFields.spec.ts
@@ -0,0 +1,120 @@
+import { mount, VueWrapper } from '@vue/test-utils';
+import AddressFields from '@src/components/pages/donation_form/DonationReceipt/AddressFields.vue';
+import { AddressTypeModel } from '@src/view_models/AddressTypeModel';
+import { InitialAddressValues } from '@src/view_models/Address';
+import { Validity } from '@src/view_models/Validity';
+import { Store } from 'vuex';
+import { createStore } from '@src/store/donation_store';
+import { action } from '@src/store/util';
+import countries from '@test/data/countries';
+
+const initialValues: InitialAddressValues = {
+ addressType: AddressTypeModel.PERSON,
+ fields: [
+ { name: 'salutation', value: 'Herr', validity: Validity.RESTORED },
+ { name: 'title', value: 'Prof. Dr.', validity: Validity.RESTORED },
+ { name: 'companyName', value: 'ACME', validity: Validity.RESTORED },
+ { name: 'firstName', value: 'Wiley', validity: Validity.RESTORED },
+ { name: 'lastName', value: 'Coyote', validity: Validity.RESTORED },
+ { name: 'street', value: 'Desert Street', validity: Validity.RESTORED },
+ { name: 'city', value: 'The Desert', validity: Validity.RESTORED },
+ { name: 'postcode', value: '666', validity: Validity.RESTORED },
+ { name: 'country', value: 'ie', validity: Validity.RESTORED },
+ { name: 'email', value: 'wiley.coyote@wikimedia.de', validity: Validity.RESTORED },
+ ],
+ newsletter: false,
+ receipt: true,
+};
+
+describe( 'AddressFields.vue', () => {
+
+ const getWrapper = ( store: Store = createStore() ): VueWrapper => {
+ return mount( AddressFields, {
+ props: {
+ formData: {
+ salutation: { name: 'salutation', value: 'Herr', pattern: '', optionalField: false },
+ title: { name: 'title', value: 'Prof. Dr.', pattern: '', optionalField: true },
+ companyName: { name: 'companyName', value: 'ACME', pattern: '', optionalField: false },
+ firstName: { name: 'firstName', value: 'Wiley', pattern: '', optionalField: false },
+ lastName: { name: 'lastName', value: 'Coyote', pattern: '', optionalField: false },
+ street: { name: 'street', value: 'Desert Street', pattern: '', optionalField: false },
+ city: { name: 'city', value: 'The Desert', pattern: '', optionalField: false },
+ postcode: { name: 'postcode', value: '666', pattern: '', optionalField: false },
+ country: { name: 'country', value: 'IE', pattern: '', optionalField: false },
+ email: { name: 'email', value: 'wiley.coyote@wikimedia.de', pattern: '', optionalField: false },
+ },
+ showError: {
+ salutation: false,
+ title: false,
+ companyName: false,
+ firstName: false,
+ lastName: false,
+ street: false,
+ city: false,
+ postcode: false,
+ country: false,
+ email: false,
+ },
+ countries,
+ postCodeValidation: '',
+ },
+ global: {
+ plugins: [ store ],
+ },
+ } );
+ };
+
+ it( 'restores the country field when mounted', async () => {
+ const store = createStore();
+ await store.dispatch( action( 'address', 'initializeAddress' ), initialValues );
+
+ const wrapper = getWrapper( store );
+
+ expect( wrapper.find( '#country' ).element.value ).toStrictEqual( 'Ireland' );
+ } );
+
+ it( 'sets the post code validation pattern when the country field is changed', async () => {
+ jest.useFakeTimers();
+
+ const wrapper = getWrapper();
+
+ await wrapper.find( '#country' ).setValue( 'Ireland' );
+ await wrapper.find( '#country' ).trigger( 'blur' );
+ await jest.runAllTimersAsync();
+
+ expect( wrapper.props( 'formData' ).postcode.pattern ).toStrictEqual( '^[0-9]{11}$' );
+
+ await wrapper.find( '#country' ).setValue( 'Not a country' );
+ await wrapper.find( '#country' ).trigger( 'blur' );
+ await jest.runAllTimersAsync();
+
+ expect( wrapper.props( 'formData' ).postcode.pattern ).toStrictEqual( '' );
+ expect( wrapper.emitted( 'field-changed' ).length ).toStrictEqual( 4 );
+ expect( wrapper.emitted( 'field-changed' )[ 0 ][ 0 ] ).toStrictEqual( 'country' );
+ expect( wrapper.emitted( 'field-changed' )[ 1 ][ 0 ] ).toStrictEqual( 'postcode' );
+ expect( wrapper.emitted( 'field-changed' )[ 2 ][ 0 ] ).toStrictEqual( 'country' );
+ expect( wrapper.emitted( 'field-changed' )[ 3 ][ 0 ] ).toStrictEqual( 'postcode' );
+
+ jest.restoreAllMocks();
+ } );
+
+ it( 'emits field changes', async () => {
+ jest.useFakeTimers();
+
+ const wrapper = getWrapper();
+
+ await wrapper.find( '#street' ).setValue( 'Sesame' );
+ await wrapper.find( '#street' ).trigger( 'blur' );
+
+ await wrapper.find( '#city' ).setValue( 'Big City' );
+ await wrapper.find( '#city' ).trigger( 'blur' );
+
+ await jest.runAllTimersAsync();
+
+ expect( wrapper.emitted( 'field-changed' ).length ).toStrictEqual( 2 );
+ expect( wrapper.emitted( 'field-changed' )[ 0 ][ 0 ] ).toStrictEqual( 'street' );
+ expect( wrapper.emitted( 'field-changed' )[ 1 ][ 0 ] ).toStrictEqual( 'city' );
+
+ jest.restoreAllMocks();
+ } );
+} );
diff --git a/tests/unit/components/pages/donation_form/FormSections/PersonalDataSection.spec.ts b/tests/unit/components/pages/donation_form/FormSections/PersonalDataSection.spec.ts
index b856dbfd6..f9de967dd 100644
--- a/tests/unit/components/pages/donation_form/FormSections/PersonalDataSection.spec.ts
+++ b/tests/unit/components/pages/donation_form/FormSections/PersonalDataSection.spec.ts
@@ -1,17 +1,11 @@
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 AddressTypeBasic from '@src/components/pages/donation_form/AddressTypeBasic.vue';
import { Salutation } from '@src/view_models/Salutation';
import PersonalDataSection from '@src/components/pages/donation_form/FormSections/PersonalDataSection.vue';
-import { FakeBankValidationResource } from '@test/unit/TestDoubles/FakeBankValidationResource';
const testCountry = {
countryCode: 'de',
@@ -34,76 +28,50 @@ const salutations: Salutation[] = [
];
describe( 'PersonalDataSection.vue', () => {
- const getWrapper = ( store: Store = createStore() ): { wrapper: VueWrapper, store: Store } => {
- const wrapper = mount( PersonalDataSection, {
+ const getWrapper = (): VueWrapper => {
+ return mount( PersonalDataSection, {
props: {
- assetsPath: '',
- validateAddressUrl: 'https://localhost:8082',
- validateEmailUrl: 'https://localhost:8082',
- validateBankDataUrl: 'https://localhost:8082',
- validateLegacyBankDataUrl: 'https://localhost:8082',
countries: [ testCountry ],
salutations,
trackingData: {} as TrackingData,
campaignValues: {} as CampaignValues,
addressValidationPatterns: { postcode: '', country: null } as AddressValidation,
+ isDirectDebitPayment: false,
+ disabledAddressTypes: [],
+ addressType: AddressTypeModel.UNSET,
+ addressTypeIsInvalid: false,
},
global: {
- plugins: [ store ],
- stubs: {
- Address: true,
- },
- provide: {
- bankValidationResource: new FakeBankValidationResource(),
- },
- components: {
- FeatureToggle: createFeatureToggle( [ 'campaigns.address_type_steps.preselect' ] ),
- },
+ plugins: [ createStore() ],
},
} );
-
- return { wrapper, store };
};
- it( 'sets address type in store when it receives address-type event', () => {
- const { wrapper, store } = getWrapper();
-
- store.dispatch = jest.fn();
- const expectedAction = action( 'address', 'setAddressType' );
- const expectedPayload = AddressTypeModel.ANON;
+ it( 'emits when it receives address-type event', async () => {
+ const wrapper = getWrapper();
- wrapper.findComponent( AddressTypeBasic ).vm.$emit( 'address-type', AddressTypeModel.ANON );
+ await wrapper.find( '#addressType-1' ).trigger( 'change' );
+ await wrapper.find( '#addressType-2' ).trigger( 'change' );
- expect( store.dispatch ).toBeCalledWith( expectedAction, expectedPayload );
+ expect( wrapper.emitted( 'set-address-type' ).length ).toStrictEqual( 2 );
+ expect( wrapper.emitted( 'set-address-type' )[ 0 ][ 0 ] ).toStrictEqual( AddressTypeModel.COMPANY );
+ expect( wrapper.emitted( 'set-address-type' )[ 1 ][ 0 ] ).toStrictEqual( AddressTypeModel.ANON );
} );
- it( 'scrolls to payment section when button for changing payment data is clicked', async () => {
- const scrollElement = { scrollIntoView: jest.fn() };
- Object.defineProperty( document, 'getElementById', { writable: true, configurable: true, value: () => scrollElement } );
-
- const { wrapper } = getWrapper();
+ it( 'Shows the correct form when address type is changed', async () => {
+ const wrapper = getWrapper();
- await wrapper.find( '#previous-btn' ).trigger( 'click' );
-
- expect( scrollElement.scrollIntoView ).toHaveBeenCalledWith( { behavior: 'smooth' } );
- } );
-
- it( 'updates full selected', async () => {
- const { wrapper } = getWrapper();
-
- wrapper.findComponent( AddressTypeBasic ).vm.$emit( 'address-type', AddressTypeModel.PERSON );
- wrapper.findComponent( AddressTypeBasic ).vm.$emit( 'set-full-selected' );
- await nextTick();
+ await wrapper.setProps( { addressType: AddressTypeModel.PERSON } );
expect( wrapper.find( '.address-type-person' ).exists() ).toBeTruthy();
- } );
- it( 'validates the payment section input on page submit', async () => {
- const { wrapper, store } = getWrapper();
- store.dispatch = jest.fn().mockResolvedValue( true );
+ await wrapper.setProps( { addressType: AddressTypeModel.COMPANY } );
+
+ expect( wrapper.find( '.address-type-company' ).exists() ).toBeTruthy();
- await wrapper.find( '#submit-btn' ).trigger( 'click' );
+ await wrapper.setProps( { addressType: AddressTypeModel.ANON } );
- expect( store.dispatch ).toHaveBeenCalledWith( action( 'payment', 'markEmptyValuesAsInvalid' ) );
+ expect( wrapper.find( '.address-type-person' ).exists() ).toBeFalsy();
+ expect( wrapper.find( '.address-type-company' ).exists() ).toBeFalsy();
} );
} );
diff --git a/tests/unit/components/pages/donation_form/FormSections/PersonalDataSectionDonationReceipt.spec.ts b/tests/unit/components/pages/donation_form/FormSections/PersonalDataSectionDonationReceipt.spec.ts
index 807865273..3e069aa27 100644
--- a/tests/unit/components/pages/donation_form/FormSections/PersonalDataSectionDonationReceipt.spec.ts
+++ b/tests/unit/components/pages/donation_form/FormSections/PersonalDataSectionDonationReceipt.spec.ts
@@ -9,13 +9,12 @@ import { AddressValidation } from '@src/view_models/Validation';
import { Salutation } from '@src/view_models/Salutation';
import PersonalDataSectionDonationReceipt from '@src/components/pages/donation_form/FormSections/PersonalDataSectionDonationReceipt.vue';
import { FakeBankValidationResource } from '@test/unit/TestDoubles/FakeBankValidationResource';
-
-const testCountry = {
- countryCode: 'de',
- countryFullName: 'Germany',
- group: '',
- postCodeValidation: '',
-};
+import { AddressTypeModel } from '@src/view_models/AddressTypeModel';
+import { useReceiptModel } from '@src/components/pages/donation_form/DonationReceipt/useReceiptModel';
+import { InitialAddressValues } from '@src/view_models/Address';
+import { Validity } from '@src/view_models/Validity';
+import countries from '@test/data/countries';
+import { nextTick } from 'vue';
const salutations: Salutation[] = [
{
@@ -30,20 +29,38 @@ const salutations: Salutation[] = [
},
];
+const initialValues: InitialAddressValues = {
+ addressType: AddressTypeModel.PERSON,
+ fields: [
+ { name: 'salutation', value: 'Herr', validity: Validity.RESTORED },
+ { name: 'title', value: 'Prof. Dr.', validity: Validity.RESTORED },
+ { name: 'companyName', value: 'ACME', validity: Validity.RESTORED },
+ { name: 'firstName', value: 'Wiley', validity: Validity.RESTORED },
+ { name: 'lastName', value: 'Coyote', validity: Validity.RESTORED },
+ { name: 'country', value: 'IE', validity: Validity.RESTORED },
+ { name: 'city', value: 'The Desert', validity: Validity.RESTORED },
+ { name: 'postcode', value: '666', validity: Validity.RESTORED },
+ { name: 'street', value: 'Desert Street', validity: Validity.RESTORED },
+ { name: 'email', value: 'wiley.coyote@wikimedia.de', validity: Validity.RESTORED },
+ ],
+ newsletter: false,
+ receipt: true,
+};
+
describe( 'PersonalDataSectionDonationReceipt.vue', () => {
- const getWrapper = ( store: Store = createStore() ): { wrapper: VueWrapper, store: Store } => {
- const wrapper = mount( PersonalDataSectionDonationReceipt, {
+ const getWrapper = ( store: Store = createStore() ): VueWrapper => {
+ return mount( PersonalDataSectionDonationReceipt, {
props: {
- assetsPath: '',
- validateAddressUrl: '',
- validateEmailUrl: '',
- validateBankDataUrl: 'https://localhost:8082',
- validateLegacyBankDataUrl: 'https://localhost:8082',
- countries: [ testCountry ],
+ countries: countries,
salutations,
trackingData: {} as TrackingData,
campaignValues: {} as CampaignValues,
- addressValidationPatterns: { postcode: '' } as AddressValidation,
+ addressValidationPatterns: { postcode: '', salutation: '' } as AddressValidation,
+ isDirectDebitPayment: false,
+ disabledAddressTypes: [],
+ addressType: AddressTypeModel.UNSET,
+ receiptModel: useReceiptModel( store ),
+ addressTypeIsInvalid: false,
},
global: {
plugins: [ store ],
@@ -58,27 +75,36 @@ describe( 'PersonalDataSectionDonationReceipt.vue', () => {
},
},
} );
-
- return { wrapper, store };
};
- it( 'scrolls to payment section when button for changing payment data is clicked', async () => {
- const scrollElement = { scrollIntoView: jest.fn() };
- Object.defineProperty( document, 'getElementById', { writable: true, configurable: true, value: () => scrollElement } );
+ it( 'initialises the address form data when mounted', async () => {
+ const store = createStore();
+ await store.dispatch( action( 'address', 'initializeAddress' ), initialValues );
+ store.dispatch = jest.fn().mockResolvedValue( true );
- const { wrapper } = getWrapper();
+ const wrapper = getWrapper( store );
- await wrapper.find( '#previous-btn' ).trigger( 'click' );
+ await nextTick();
- expect( scrollElement.scrollIntoView ).toHaveBeenCalledWith( { behavior: 'smooth' } );
+ expect( wrapper.find( '#salutation-0' ).element.checked ).toBeTruthy();
+ expect( wrapper.find( '#title' ).element.value ).toStrictEqual( 'Prof. Dr.' );
+ expect( wrapper.find( '#first-name' ).element.value ).toStrictEqual( 'Wiley' );
+ expect( wrapper.find( '#last-name' ).element.value ).toStrictEqual( 'Coyote' );
+ expect( wrapper.find( '#email' ).element.value ).toStrictEqual( 'wiley.coyote@wikimedia.de' );
+ expect( wrapper.find( '#addressType-0' ).element.checked ).toBeTruthy();
+ expect( wrapper.find( '#country' ).element.value ).toStrictEqual( 'Ireland' );
+ expect( wrapper.find( '#city' ).element.value ).toStrictEqual( 'The Desert' );
+ expect( wrapper.find( '#post-code' ).element.value ).toStrictEqual( '666' );
+ expect( wrapper.find( '#street' ).element.value ).toStrictEqual( 'Desert Street' );
} );
- it( 'validates the payment section input on page submit', async () => {
- const { wrapper, store } = getWrapper();
- store.dispatch = jest.fn().mockResolvedValue( true );
+ it( 'shows the address fields when the donor wants a receipt', async () => {
+ const wrapper = getWrapper();
+
+ expect( wrapper.find( '.address-section' ).exists() ).toBeFalsy();
- await wrapper.find( '#donation-form' ).trigger( 'submit' );
+ await wrapper.find( '#donationReceipt-0' ).trigger( 'change' );
- expect( store.dispatch ).toHaveBeenCalledWith( action( 'payment', 'markEmptyValuesAsInvalid' ) );
+ expect( wrapper.find( '.address-section' ).exists() ).toBeTruthy();
} );
} );
diff --git a/tests/unit/components/pages/donation_form/FormSections/PersonalDataSectionDonationReceiptStreetAutoComplete.spec.ts b/tests/unit/components/pages/donation_form/FormSections/PersonalDataSectionDonationReceiptStreetAutoComplete.spec.ts
deleted file mode 100644
index 262c1391f..000000000
--- a/tests/unit/components/pages/donation_form/FormSections/PersonalDataSectionDonationReceiptStreetAutoComplete.spec.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-import { mount, VueWrapper } from '@vue/test-utils';
-import { createStore } from '@src/store/donation_store';
-import { action } from '@src/store/util';
-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 { Salutation } from '@src/view_models/Salutation';
-import PersonalDataSectionDonationReceipt from '@src/components/pages/donation_form/FormSections/PersonalDataSectionDonationReceipt.vue';
-import { FakeBankValidationResource } from '@test/unit/TestDoubles/FakeBankValidationResource';
-
-const testCountry = {
- countryCode: 'de',
- countryFullName: 'Germany',
- group: '',
- postCodeValidation: '',
-};
-
-const salutations: Salutation[] = [
- {
- label: 'Herr',
- value: 'Herr',
- display: 'Herr',
- greetings: {
- formal: 'Herr',
- informal: 'Herr',
- lastNameInformal: 'Herr',
- },
- },
-];
-
-describe( 'PersonalDataSectionDonationReceipt.vue (With Street Autocomplete)', () => {
- const getWrapper = ( store: Store = createStore() ): { wrapper: VueWrapper, store: Store } => {
- const wrapper = mount( PersonalDataSectionDonationReceipt, {
- props: {
- assetsPath: '',
- validateAddressUrl: '',
- validateEmailUrl: '',
- validateBankDataUrl: 'https://localhost:8082',
- validateLegacyBankDataUrl: 'https://localhost:8082',
- countries: [ testCountry ],
- salutations,
- trackingData: {} as TrackingData,
- campaignValues: {} as CampaignValues,
- addressValidationPatterns: { postcode: '' } as AddressValidation,
- },
- global: {
- plugins: [ store ],
- stubs: {
- Address: true,
- },
- provide: {
- bankValidationResource: new FakeBankValidationResource(),
- },
- components: {
- FeatureToggle: createFeatureToggle( [
- 'campaigns.address_type_steps.preselect',
- 'campaigns.address_field_order.new_order',
- ] ),
- },
- },
- } );
-
- return { wrapper, store };
- };
-
- it( 'scrolls to payment section when button for changing payment data is clicked', async () => {
- const scrollElement = { scrollIntoView: jest.fn() };
- Object.defineProperty( document, 'getElementById', { writable: true, configurable: true, value: () => scrollElement } );
-
- const { wrapper } = getWrapper();
-
- await wrapper.find( '#previous-btn' ).trigger( 'click' );
-
- expect( scrollElement.scrollIntoView ).toHaveBeenCalledWith( { behavior: 'smooth' } );
- } );
-
- it( 'validates the payment section input on page submit', async () => {
- const { wrapper, store } = getWrapper();
- store.dispatch = jest.fn().mockResolvedValue( true );
-
- await wrapper.find( '#donation-form' ).trigger( 'submit' );
-
- expect( store.dispatch ).toHaveBeenCalledWith( action( 'payment', 'markEmptyValuesAsInvalid' ) );
- } );
-} );
diff --git a/tests/unit/components/pages/donation_form/FormSections/PersonalDataSectionStreetAutoComplete.spec.ts b/tests/unit/components/pages/donation_form/FormSections/PersonalDataSectionStreetAutoComplete.spec.ts
deleted file mode 100644
index 6d5763605..000000000
--- a/tests/unit/components/pages/donation_form/FormSections/PersonalDataSectionStreetAutoComplete.spec.ts
+++ /dev/null
@@ -1,113 +0,0 @@
-import { mount, VueWrapper } from '@vue/test-utils';
-
-import PersonalDataSection from '@src/components/pages/donation_form/FormSections/PersonalDataSection.vue';
-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 AddressTypeBasic from '@src/components/pages/donation_form/AddressTypeBasic.vue';
-import { Salutation } from '@src/view_models/Salutation';
-import { FakeBankValidationResource } from '@test/unit/TestDoubles/FakeBankValidationResource';
-
-const testCountry = {
- countryCode: 'de',
- countryFullName: 'Germany',
- group: '',
- postCodeValidation: '',
-};
-
-const salutations: Salutation[] = [
- {
- label: 'Herr',
- value: 'Herr',
- display: 'Herr',
- greetings: {
- formal: 'Herr',
- informal: 'Herr',
- lastNameInformal: 'Herr',
- },
- },
-];
-
-describe( 'PersonalDataSection.vue (With Street Autocomplete)', () => {
- const getWrapper = ( store: Store = createStore() ): { wrapper: VueWrapper, store: Store } => {
- const wrapper = mount( PersonalDataSection, {
- props: {
- assetsPath: '',
- validateAddressUrl: '',
- validateEmailUrl: '',
- validateBankDataUrl: '',
- validateLegacyBankDataUrl: '',
- countries: [ testCountry ],
- salutations,
- trackingData: {} as TrackingData,
- campaignValues: {} as CampaignValues,
- addressValidationPatterns: { postcode: '', country: null } as AddressValidation,
- },
- global: {
- plugins: [ store ],
- stubs: {
- Address: true,
- },
- provide: {
- bankValidationResource: new FakeBankValidationResource(),
- },
- components: {
- FeatureToggle: createFeatureToggle( [
- 'campaigns.address_type_steps.preselect',
- 'campaigns.address_field_order.new_order',
- ] ),
- },
- },
- } );
-
- return { wrapper, store };
- };
-
- it( 'sets address type in store when it receives address-type event', () => {
- const { wrapper, store } = getWrapper();
-
- store.dispatch = jest.fn();
- const expectedAction = action( 'address', 'setAddressType' );
- const expectedPayload = AddressTypeModel.ANON;
-
- wrapper.findComponent( AddressTypeBasic ).vm.$emit( 'address-type', AddressTypeModel.ANON );
-
- expect( store.dispatch ).toBeCalledWith( expectedAction, expectedPayload );
- } );
-
- it( 'scrolls to top when the donor clicks the previous button', async () => {
- const scrollElement = { scrollIntoView: jest.fn() };
- Object.defineProperty( document, 'getElementById', { writable: true, configurable: true, value: () => scrollElement } );
-
- const { wrapper } = getWrapper();
-
- await wrapper.find( '#previous-btn' ).trigger( 'click' );
-
- expect( scrollElement.scrollIntoView ).toHaveBeenCalledWith( { behavior: 'smooth' } );
- } );
-
- it( 'updates full selected', async () => {
- const { wrapper } = getWrapper();
-
- wrapper.findComponent( AddressTypeBasic ).vm.$emit( 'address-type', AddressTypeModel.PERSON );
- wrapper.findComponent( AddressTypeBasic ).vm.$emit( 'set-full-selected' );
- await nextTick();
-
- expect( wrapper.find( '.address-type-person' ).exists() ).toBeTruthy();
- } );
-
- it( 'validates the payment section input on page submit', async () => {
- const { wrapper, store } = getWrapper();
- store.dispatch = jest.fn().mockResolvedValue( true );
-
- await wrapper.find( '#submit-btn' ).trigger( 'click' );
-
- expect( store.dispatch ).toHaveBeenCalledWith( action( 'payment', 'markEmptyValuesAsInvalid' ) );
- } );
-} );
diff --git a/tests/unit/store/address_store.spec.ts b/tests/unit/store/address_store.spec.ts
index 20d76b282..74ae1475c 100644
--- a/tests/unit/store/address_store.spec.ts
+++ b/tests/unit/store/address_store.spec.ts
@@ -490,6 +490,44 @@ describe( 'Address', () => {
} );
} );
+ describe( 'Actions/adjustSalutationLocale', () => {
+ it( 'does not adjust when salutation is empty', () => {
+ const commit = jest.fn();
+ const action = actions.adjustSalutationLocale as any;
+ const salutations = [ { value: 'Mr' }, { value: 'Ms' } ];
+
+ action( { commit }, { salutations, salutation: '' } );
+
+ expect( commit ).not.toHaveBeenCalled();
+ } );
+
+ it( 'adjusts the salutation when it finds it in the server salutations array', () => {
+ const commit = jest.fn();
+ const action = actions.adjustSalutationLocale as any;
+ const salutations = [ { value: 'Mr' }, { value: 'Ms' } ];
+
+ action( { commit }, { salutations, salutation: 'Mr' } );
+
+ expect( commit ).toHaveBeenCalledWith(
+ 'SET_SALUTATION',
+ 'Mr'
+ );
+ } );
+
+ it( 'adjusts the salutation when it finds it in the local translations array', () => {
+ const commit = jest.fn();
+ const action = actions.adjustSalutationLocale as any;
+ const salutations = [ { value: 'Mr' }, { value: 'Ms' } ];
+
+ action( { commit }, { salutations, salutation: 'No Salutation' } );
+
+ expect( commit ).toHaveBeenCalledWith(
+ 'SET_SALUTATION',
+ 'Keine Anrede'
+ );
+ } );
+ } );
+
describe( 'Mutations/VALIDATE_INPUT', () => {
it( 'sets validity to valid for optional unfilled fields', () => {
const inputField = {