From 9c75f0b7e35e0c0493fef0d735154543768b7f25 Mon Sep 17 00:00:00 2001 From: Abban Dunne Date: Wed, 18 Dec 2024 14:11:17 +0100 Subject: [PATCH] Add receipt option handling from backend If the application passes a receipt to the front end it will now be set in both forms. Ticket: https://phabricator.wikimedia.org/T382304 --- src/store/dataInitializers.ts | 4 ++- .../pages/donation_form/DonationForm.spec.ts | 23 ++++++++++++++--- .../donation_form/DonationFormReceipt.spec.ts | 25 ++++++++++++++++--- tests/unit/store/dataInitializers.spec.ts | 11 +++++++- 4 files changed, 55 insertions(+), 8 deletions(-) diff --git a/src/store/dataInitializers.ts b/src/store/dataInitializers.ts index b08746f7..b0de40d4 100644 --- a/src/store/dataInitializers.ts +++ b/src/store/dataInitializers.ts @@ -47,7 +47,9 @@ export const createInitialDonationAddressValues = ( dataPersister: DataPersister // reloading the page (and restoring from localStorage) happens less often than coming back from a banner addressType: replaceInitialValue( dataPersister.getValue( 'addressType' ), initialFormValues.addressType ), newsletter: replaceInitialValue( MAILING_LIST_ADDRESS_PAGE, dataPersister.getValue( 'newsletter' ) ), - receipt: replaceInitialValue( null, dataPersister.getValue( 'receipt' ) ), + // The receipt chosen by the user in the banner should override the choice made later, assuming that + // reloading the page (and restoring from localStorage) happens less often than coming back from a banner + receipt: replaceInitialValue( dataPersister.getValue( 'receipt' ), initialFormValues.receipt ), fields: addressPersistItems, }; }; diff --git a/tests/unit/components/pages/donation_form/DonationForm.spec.ts b/tests/unit/components/pages/donation_form/DonationForm.spec.ts index 1f705363..9043f9b2 100644 --- a/tests/unit/components/pages/donation_form/DonationForm.spec.ts +++ b/tests/unit/components/pages/donation_form/DonationForm.spec.ts @@ -7,6 +7,8 @@ import { nextTick } from 'vue'; import axios from 'axios'; import { newSucceedingBankValidationResource } from '@test/unit/TestDoubles/SucceedingBankValidationResource'; import { IBAN } from '@test/data/bankdata'; +import { action } from '@src/store/util'; +import { Store } from 'vuex'; jest.mock( 'axios' ); const mockedAxios = axios as jest.Mocked; @@ -39,8 +41,7 @@ describe( 'DonationForm.vue', () => { document.getElementsByTagName( 'html' )[ 0 ].innerHTML = ''; } ); - const getWrapper = (): VueWrapper => { - const store = createStore(); + const getWrapper = ( store: Store = null ): VueWrapper => { return mount( DonationForm, { props: { assetsPath: '', @@ -79,7 +80,7 @@ describe( 'DonationForm.vue', () => { addressValidationPatterns: { postcode: '', country: null } as AddressValidation, }, global: { - plugins: [ store ], + plugins: [ store ?? createStore() ], provide: { bankValidationResource: newSucceedingBankValidationResource(), }, @@ -96,6 +97,22 @@ describe( 'DonationForm.vue', () => { expect( wrapper.find( '#person-newsletter' ).element.checked ).toBeTruthy(); } ); + it( 'sets the correct receipt wanted field', async () => { + const store = createStore(); + await store.dispatch( action( 'address', 'initializeAddress' ), { receipt: true, fields: [] } ); + const wrapper = getWrapper( store ); + + expect( wrapper.find( '#receipt-option-person' ).element.checked ).toBeTruthy(); + } ); + + it( 'sets the correct receipt not wanted field', async () => { + const store = createStore(); + await store.dispatch( action( 'address', 'initializeAddress' ), { receipt: false, fields: [] } ); + const wrapper = getWrapper( store ); + + expect( wrapper.find( '#receipt-option-person' ).element.checked ).toBeFalsy(); + } ); + it( 'handles the error summary when no address type was selected before submitting', async () => { const wrapper = getWrapper(); diff --git a/tests/unit/components/pages/donation_form/DonationFormReceipt.spec.ts b/tests/unit/components/pages/donation_form/DonationFormReceipt.spec.ts index 9c5d3735..31f4169f 100644 --- a/tests/unit/components/pages/donation_form/DonationFormReceipt.spec.ts +++ b/tests/unit/components/pages/donation_form/DonationFormReceipt.spec.ts @@ -7,6 +7,8 @@ import { nextTick } from 'vue'; import axios from 'axios'; import { newSucceedingBankValidationResource } from '@test/unit/TestDoubles/SucceedingBankValidationResource'; import { IBAN } from '@test/data/bankdata'; +import { Store } from 'vuex'; +import { action } from '@src/store/util'; jest.mock( 'axios' ); const mockedAxios = axios as jest.Mocked; @@ -39,8 +41,7 @@ describe( 'DonationFormReciept.vue', () => { document.getElementsByTagName( 'html' )[ 0 ].innerHTML = ''; } ); - const getWrapper = (): VueWrapper => { - const store = createStore(); + const getWrapper = ( store: Store = null ): VueWrapper => { return mount( DonationForm, { props: { assetsPath: '', @@ -79,7 +80,7 @@ describe( 'DonationFormReciept.vue', () => { addressValidationPatterns: { postcode: '', country: null } as AddressValidation, }, global: { - plugins: [ store ], + plugins: [ store ?? createStore() ], provide: { bankValidationResource: newSucceedingBankValidationResource(), }, @@ -97,6 +98,24 @@ describe( 'DonationFormReciept.vue', () => { expect( wrapper.find( '#donationReceipt-1' ).element.checked ).toBeFalsy(); } ); + it( 'sets the correct receipt wanted field', async () => { + const store = createStore(); + await store.dispatch( action( 'address', 'initializeAddress' ), { receipt: true, fields: [] } ); + const wrapper = getWrapper( store ); + + expect( wrapper.find( '#donationReceipt-0' ).element.checked ).toBeTruthy(); + expect( wrapper.find( '#donationReceipt-1' ).element.checked ).toBeFalsy(); + } ); + + it( 'sets the correct receipt not wanted field', async () => { + const store = createStore(); + await store.dispatch( action( 'address', 'initializeAddress' ), { receipt: false, fields: [] } ); + const wrapper = getWrapper( store ); + + expect( wrapper.find( '#donationReceipt-0' ).element.checked ).toBeFalsy(); + expect( wrapper.find( '#donationReceipt-1' ).element.checked ).toBeTruthy(); + } ); + it( 'handles the error summary when no receipt option was selected before submitting', async () => { const wrapper = getWrapper(); diff --git a/tests/unit/store/dataInitializers.spec.ts b/tests/unit/store/dataInitializers.spec.ts index 272039cc..37ae7883 100644 --- a/tests/unit/store/dataInitializers.spec.ts +++ b/tests/unit/store/dataInitializers.spec.ts @@ -30,7 +30,7 @@ describe( 'createInitialDonationAddressValues', () => { expect( values.addressType ).toEqual( AddressTypeModel.ANON ); } ); - it( 'uses initial address type over stored address type over', () => { + it( 'uses initial address type over stored address type', () => { const storedAddressType = { key: 'addressType', value: AddressTypeModel.PERSON }; const initialAddressType = 'firma'; @@ -58,6 +58,15 @@ describe( 'createInitialDonationAddressValues', () => { expect( values.addressType ).toEqual( AddressTypeModel.PERSON ); } ); + + it( 'uses stored receipt when initial receipt is missing', () => { + const storedReceipt = { key: 'receipt', value: true }; + + const dataPersister = new FakeDataPersister( [ storedReceipt ] ); + const values = createInitialDonationAddressValues( dataPersister, {} ); + + expect( values.receipt ).toEqual( true ); + } ); } ); describe( 'createInitialDonationPaymentValues', () => {