diff --git a/force-app/main/default/classes/ElevateBatchItem.cls b/force-app/main/default/classes/ElevateBatchItem.cls index e697e05040..dbf4b23381 100644 --- a/force-app/main/default/classes/ElevateBatchItem.cls +++ b/force-app/main/default/classes/ElevateBatchItem.cls @@ -37,6 +37,7 @@ public with sharing class ElevateBatchItem { @AuraEnabled public String elevateBatchId {get; set;} @AuraEnabled public String declineReason {get; set;} @AuraEnabled public String cardLast4 {get; set;} + @AuraEnabled public String achLast4 {get; set;} @AuraEnabled public String cardNetwork {get; set;} @AuraEnabled public String cardExpirationMonth {get; set;} @AuraEnabled public String cardExpirationYear {get; set;} @@ -59,7 +60,8 @@ public with sharing class ElevateBatchItem { this.elevateBatchId = createBatchItemResponse.elevateBatchId(); this.originalTransactionId = createBatchItemResponse.originalTransactionId(); this.declineReason = createBatchItemResponse.declineReason(); - this.cardLast4 = createBatchItemResponse.last4(); + this.cardLast4 = createBatchItemResponse.cardLast4(); + this.achLast4 = createBatchItemResponse.achLast4(); this.status = createBatchItemResponse.status(); this.statusReason = createBatchItemResponse.statusReason(); this.cardNetwork = createBatchItemResponse.brand(); diff --git a/force-app/main/default/classes/ElevateBatchItemCreateResponse.cls b/force-app/main/default/classes/ElevateBatchItemCreateResponse.cls index 08d14649b4..4b3eca7c8a 100644 --- a/force-app/main/default/classes/ElevateBatchItemCreateResponse.cls +++ b/force-app/main/default/classes/ElevateBatchItemCreateResponse.cls @@ -215,10 +215,14 @@ public class ElevateBatchItemCreateResponse { return purchaseResponse?.authExpiresAt; } - public String last4() { + public String cardLast4() { return commitmentResponse != null ? commitmentResponse.cardData?.last4 : purchaseResponse.cardData?.last4; } + public String achLast4() { + return commitmentResponse != null ? commitmentResponse.achData?.last4 : purchaseResponse.achData?.last4; + } + public String brand() { return commitmentResponse != null ? commitmentResponse.cardData?.brand : purchaseResponse.cardData?.brand; } diff --git a/force-app/main/default/lwc/geConstants/geConstants.js b/force-app/main/default/lwc/geConstants/geConstants.js index b85910b4de..ef85a9330a 100644 --- a/force-app/main/default/lwc/geConstants/geConstants.js +++ b/force-app/main/default/lwc/geConstants/geConstants.js @@ -52,7 +52,9 @@ const CLICKED_DOWN = 'clicked-down'; const DOWN = 'down'; const UP = 'up'; -const DEFAULT_NAME_ON_CARD = '[Not Provided]' +const DEFAULT_NAME_ON_CARD = '[Not Provided]'; + +const RECURRING_TYPE_FIXED = 'Fixed'; export { COMMITMENT_INACTIVE_STATUS, @@ -77,5 +79,6 @@ export { CLICKED_DOWN, DOWN, UP, - DEFAULT_NAME_ON_CARD + DEFAULT_NAME_ON_CARD, + RECURRING_TYPE_FIXED }; \ No newline at end of file diff --git a/force-app/main/default/lwc/geFormRenderer/__tests__/geFormRenderer.test.js b/force-app/main/default/lwc/geFormRenderer/__tests__/geFormRenderer.test.js index fe5ad32bb7..8b5302323c 100644 --- a/force-app/main/default/lwc/geFormRenderer/__tests__/geFormRenderer.test.js +++ b/force-app/main/default/lwc/geFormRenderer/__tests__/geFormRenderer.test.js @@ -5,6 +5,7 @@ import GeFormRenderer from 'c/geFormRenderer'; import GeLabelService from 'c/geLabelService'; import Settings from 'c/geSettings'; import GeGatewaySettings from 'c/geGatewaySettings'; +const pubSub = require('c/pubsubNoPageRef'); import upsertDataImport from '@salesforce/apex/GE_GiftEntryController.upsertDataImport'; import retrieveDefaultSGERenderWrapper from '@salesforce/apex/GE_GiftEntryController.retrieveDefaultSGERenderWrapper'; @@ -15,9 +16,6 @@ import { mockCheckInputValidity } from 'lightning/input'; import { mockCheckComboboxValidity } from 'lightning/combobox'; import { mockGetIframeReply } from 'c/psElevateTokenHandler'; -import donationImported from '@salesforce/schema/DataImport__c.DonationImported__c'; -import { DEFAULT_FORM_FIELDS } from '../../utilTemplateBuilder/utilTemplateBuilder'; - const mockWrapperWithNoNames = require('../../../../../../tests/__mocks__/apex/data/retrieveDefaultSGERenderWrapper.json'); const getRecordContact1Imported = require('./data/getRecordContact1Imported.json'); const dataImportObjectInfo = require('../../../../../../tests/__mocks__/apex/data/dataImportObjectDescribeInfo.json'); @@ -32,56 +30,6 @@ describe('c-ge-form-renderer', () => { }); describe('render behavior', () => { - it('renders make recurring button, when in batch mode and feature is enabled', async () => { - retrieveDefaultSGERenderWrapper.mockResolvedValue(mockWrapperWithNoNames); - getAllocationsSettings.mockResolvedValue(allocationsSettingsNoDefaultGAU); - const element = createElement('c-ge-form-renderer', {is: GeFormRenderer }); - - const DUMMY_BATCH_ID = 'a0T11000007F8WQEA0'; - - element.batchId = DUMMY_BATCH_ID; - document.body.appendChild(element); - await flushPromises(); - - // simulate getting back data for DUMMY_CONTACT_ID - getRecord.emit(dataImportBatchRecord, config => { - return config.recordId === DUMMY_BATCH_ID; - }); - - await flushPromises(); - - const button = element.shadowRoot.querySelectorAll('[data-id="recurringButton"]'); - expect(button).toHaveLength(1); - }); - - it('make recurring button is disabled when imported gift is loaded into the form', async() => { - retrieveDefaultSGERenderWrapper.mockResolvedValue(mockWrapperWithNoNames); - getAllocationsSettings.mockResolvedValue(allocationsSettingsNoDefaultGAU); - const element = createElement('c-ge-form-renderer', {is: GeFormRenderer }); - - const DUMMY_BATCH_ID = 'a0T11000007F8WQEA0'; - - element.batchId = DUMMY_BATCH_ID; - document.body.appendChild(element); - await flushPromises(); - - // simulate getting back data for DUMMY_CONTACT_ID - getRecord.emit(dataImportBatchRecord, config => { - return config.recordId === DUMMY_BATCH_ID; - }); - - await flushPromises(); - - const button = element.shadowRoot.querySelectorAll('[data-id="recurringButton"]'); - expect(button).toHaveLength(1); - - element.isMakeRecurringButtonDisabled = true; - await flushPromises(); - - const disabledButton = element.shadowRoot.querySelectorAll('[data-id="recurringButton"]'); - expect(disabledButton[0].disabled).toBe(true); - }); - it('when a form is saved with a possible validation rule error then processing of the donation should be halted', async () => { @@ -147,6 +95,178 @@ describe('c-ge-form-renderer', () => { const spinner = element.shadowRoot.querySelector('lightning-spinner'); expect(spinner).toBeFalsy(); }); + it('make recurring button is disabled when imported gift is loaded into the form', async() => { + retrieveDefaultSGERenderWrapper.mockResolvedValue(mockWrapperWithNoNames); + getAllocationsSettings.mockResolvedValue(allocationsSettingsNoDefaultGAU); + const element = createElement('c-ge-form-renderer', {is: GeFormRenderer }); + + const DUMMY_BATCH_ID = 'a0T11000007F8WQEA0'; + + element.batchId = DUMMY_BATCH_ID; + document.body.appendChild(element); + await flushPromises(); + + // simulate getting back data for DUMMY_CONTACT_ID + getRecord.emit(dataImportBatchRecord, config => { + return config.recordId === DUMMY_BATCH_ID; + }); + + await flushPromises(); + + const button = element.shadowRoot.querySelectorAll('[data-id="recurringButton"]'); + expect(button).toHaveLength(1); + + element.isMakeRecurringButtonDisabled = true; + await flushPromises(); + + const disabledButton = element.shadowRoot.querySelectorAll('[data-id="recurringButton"]'); + expect(disabledButton[0].disabled).toBe(true); + }); + + it('save button is not disabled when schedule recurring type is Fixed for non-Elevate RD', async() => { + retrieveDefaultSGERenderWrapper.mockResolvedValue(mockWrapperWithNoNames); + getAllocationsSettings.mockResolvedValue(allocationsSettingsNoDefaultGAU); + + const element = createElement('c-ge-form-renderer', {is: GeFormRenderer }); + element.batchId = 'DUMMY_BATCH_ID'; + + Settings.isElevateCustomer = jest.fn(() => true); + element.Settings = Settings; + + GeGatewaySettings.isValidElevatePaymentMethod = jest.fn(() => false); + element.GeGatewaySettings = GeGatewaySettings; + + document.body.appendChild(element); + await flushPromises(); + + element.giftInView = { + fields: { + 'Recurring_Donation_Recurring_Type__c': 'Fixed', + 'Payment_Method__c': 'Credit Card' + } + }; + await flushPromises(); + + const saveButton = element.shadowRoot.querySelector('[data-id="bgeSaveButton"]'); + expect(saveButton.disabled).toBeFalsy(); + }); + + it('save button is disabled when schedule recurring type is Fixed for Elevate RD and widget is present and not disabled', async() => { + retrieveDefaultSGERenderWrapper.mockResolvedValue(mockWrapperWithNoNames); + getAllocationsSettings.mockResolvedValue(allocationsSettingsNoDefaultGAU); + + const element = createElement('c-ge-form-renderer', {is: GeFormRenderer }); + element.batchId = 'DUMMY_BATCH_ID'; + + Settings.isElevateCustomer = jest.fn(() => true); + element.Settings = Settings; + + GeGatewaySettings.isValidElevatePaymentMethod = jest.fn(() => true); + element.GeGatewaySettings = GeGatewaySettings; + + element.hasPaymentWidget = true; + + document.body.appendChild(element); + await flushPromises(); + + element.giftInView = { + fields: { + 'Recurring_Donation_Recurring_Type__c': 'Fixed', + 'Payment_Method__c': 'Credit Card', + 'Recurring_Donation_Elevate_Recurring_ID__c': 'DUMMY_RECURRING_ID' + } + }; + await flushPromises(); + + const saveButton = element.shadowRoot.querySelector('[data-id="bgeSaveButton"]'); + expect(saveButton.disabled).toBeTruthy(); + }); + + it('save button is not disabled when schedule recurring type is Fixed for Elevate RD and widget is disabled.', async() => { + retrieveDefaultSGERenderWrapper.mockResolvedValue(mockWrapperWithNoNames); + getAllocationsSettings.mockResolvedValue(allocationsSettingsNoDefaultGAU); + + const element = createElement('c-ge-form-renderer', {is: GeFormRenderer }); + element.batchId = 'DUMMY_BATCH_ID'; + + Settings.isElevateCustomer = jest.fn(() => true); + element.Settings = Settings; + + GeGatewaySettings.isValidElevatePaymentMethod = jest.fn(() => true); + element.GeGatewaySettings = GeGatewaySettings; + + element.hasPaymentWidget = true; + + document.body.appendChild(element); + await flushPromises(); + + element.giftInView = { + fields: { + 'Recurring_Donation_Recurring_Type__c': 'Fixed', + 'Payment_Method__c': 'Credit Card' + } + }; + await flushPromises(); + + pubSub.fireEvent({}, 'doNotChargeState', {isElevateWidgetDisabled: true}); + await flushPromises(); + + const saveButton = element.shadowRoot.querySelector('[data-id="bgeSaveButton"]'); + expect(saveButton.disabled).toBeFalsy(); + }); + + it('save button is not disabled when schedule recurring type is Fixed for Elevate RD and widget is not on the form.', async() => { + retrieveDefaultSGERenderWrapper.mockResolvedValue(mockWrapperWithNoNames); + getAllocationsSettings.mockResolvedValue(allocationsSettingsNoDefaultGAU); + + const element = createElement('c-ge-form-renderer', {is: GeFormRenderer }); + element.batchId = 'DUMMY_BATCH_ID'; + + Settings.isElevateCustomer = jest.fn(() => true); + element.Settings = Settings; + + GeGatewaySettings.isValidElevatePaymentMethod = jest.fn(() => true); + element.GeGatewaySettings = GeGatewaySettings; + + element.hasPaymentWidget = false; + + document.body.appendChild(element); + await flushPromises(); + + element.giftInView = { + fields: { + 'Recurring_Donation_Recurring_Type__c': 'Fixed', + 'Payment_Method__c': 'Credit Card' + } + }; + await flushPromises(); + + const saveButton = element.shadowRoot.querySelector('[data-id="bgeSaveButton"]'); + expect(saveButton.disabled).toBeFalsy(); + }); + + it('renders make recurring button, when in batch mode and feature is enabled', async () => { + retrieveDefaultSGERenderWrapper.mockResolvedValue(mockWrapperWithNoNames); + getAllocationsSettings.mockResolvedValue(allocationsSettingsNoDefaultGAU); + const element = createElement('c-ge-form-renderer', {is: GeFormRenderer }); + + const DUMMY_BATCH_ID = 'a0T11000007F8WQEA0'; + + document.body.appendChild(element); + await flushPromises(); + + // simulate getting back data for DUMMY_CONTACT_ID + element.batchId = DUMMY_BATCH_ID; + await flushPromises(); + + getRecord.emit(dataImportBatchRecord, config => { + return config.recordId === DUMMY_BATCH_ID; + }); + await flushPromises(); + + const button = element.shadowRoot.querySelectorAll('[data-id="recurringButton"]'); + expect(button).toHaveLength(1); + }); it('does not render make recurring button, when in batch mode and feature is disabled', async () => { retrieveDefaultSGERenderWrapper.mockResolvedValue(mockWrapperWithNoNames); @@ -268,7 +388,6 @@ describe('c-ge-form-renderer', () => { expect(sections).toHaveLength(4); }); - it('form when saving without filling anything in should result in a page level error for missing fields', async () => { retrieveDefaultSGERenderWrapper.mockResolvedValue(mockWrapperWithNoNames); // This error is specific to this mockRenderWrapperWithNoNames diff --git a/force-app/main/default/lwc/geFormRenderer/geFormRenderer.html b/force-app/main/default/lwc/geFormRenderer/geFormRenderer.html index ae5d16e12b..31c724a3fe 100644 --- a/force-app/main/default/lwc/geFormRenderer/geFormRenderer.html +++ b/force-app/main/default/lwc/geFormRenderer/geFormRenderer.html @@ -130,7 +130,7 @@ horizontal-align='center' if:false={isPermissionError}> + if:true={isWidgetEnabled}>

{CUSTOM_LABELS.geTextPaymentsSaveNotice}

@@ -148,7 +148,6 @@ title={saveActionLabel} onclick={handleSave} class='slds-m-left_x-small' - disabled={isUpdateActionDisabled} data-qa-locator={qaLocatorSaveButton}> @@ -227,7 +226,7 @@ horizontal-align='center' if:false={isPermissionError}> + if:true={isWidgetEnabled}>

{CUSTOM_LABELS.geTextPaymentsSaveNotice}

@@ -247,7 +246,7 @@ class='slds-m-left_x-small' disabled={isUpdateActionDisabled} data-qa-locator={qaLocatorSaveButton} - data-id="formSaveButton"> + data-id="bgeSaveButton">
diff --git a/force-app/main/default/lwc/geFormRenderer/geFormRenderer.js b/force-app/main/default/lwc/geFormRenderer/geFormRenderer.js index 48e8fdbef5..540e362a6e 100644 --- a/force-app/main/default/lwc/geFormRenderer/geFormRenderer.js +++ b/force-app/main/default/lwc/geFormRenderer/geFormRenderer.js @@ -97,6 +97,10 @@ import DATA_IMPORT_RECURRING_DONATION_CARD_EXPIRATION_YEAR from '@salesforce/schema/DataImport__c.Recurring_Donation_Card_Expiration_Year__c'; import DATA_IMPORT_RECURRING_DONATION_CARD_LAST_4 from '@salesforce/schema/DataImport__c.Recurring_Donation_Card_Last_4__c'; +import DATA_IMPORT_RECURRING_DONATION_ACH_LAST_4 + from '@salesforce/schema/DataImport__c.Recurring_Donation_ACH_Last_4__c'; +import DATA_IMPORT_RECURRING_TYPE + from '@salesforce/schema/DataImport__c.Recurring_Donation_Recurring_Type__c'; import DATA_IMPORT_ADDITIONAL_OBJECT_FIELD from '@salesforce/schema/DataImport__c.Additional_Object_JSON__c' import DATA_IMPORT_ACCOUNT1_IMPORTED_FIELD from '@salesforce/schema/DataImport__c.Account1Imported__c'; @@ -128,7 +132,8 @@ import { COMMITMENT_INACTIVE_STATUS, BATCH_COMMITMENT_CREATED_STATUS_REASON, PAYMENT_METHOD_ACH, - GIFT_STATUSES + GIFT_STATUSES, + RECURRING_TYPE_FIXED } from 'c/geConstants'; @@ -192,7 +197,6 @@ export default class GeFormRenderer extends LightningElement{ @api isElevateCustomer = false; @api saveDisabled = false; @api isMakeRecurringButtonDisabled = false; - _isElevateWidgetInDisabledState = false; @track isPermissionError = false; @track permissionErrorTitle; @@ -204,8 +208,8 @@ export default class GeFormRenderer extends LightningElement{ @track description = ''; @track mappingSet = ''; @track version = ''; - _hasPaymentWidget = false; - latestElevateBatchId = null; + @api hasPaymentWidget = false; + _isElevateWidgetInDisabledState = false; cardholderNamesNotInTemplate = {}; _openedGiftId; currentElevateBatch = new ElevateBatch(); @@ -296,6 +300,10 @@ export default class GeFormRenderer extends LightningElement{ }); } + isGiftCommitment() { + return isNotEmpty(this.formState[apiNameFor(DATA_IMPORT_RECURRING_DONATION_ELEVATE_ID)]); + } + loadSelectedDonationFieldValues(record) { this.loadSelectedRecordFieldValues( apiNameFor(DATA_IMPORT_DONATION_IMPORTED_FIELD), record.Id); @@ -310,8 +318,8 @@ export default class GeFormRenderer extends LightningElement{ _formState = {} /** Determines when we show payment related text above the cancel and save buttons */ - get showPaymentSaveNotice() { - return this._hasPaymentWidget && this._isElevateWidgetInDisabledState === false; + get isWidgetEnabled() { + return this.hasPaymentWidget && this._isElevateWidgetInDisabledState === false; } get title() { @@ -1059,6 +1067,11 @@ export default class GeFormRenderer extends LightningElement{ [apiNameFor(DATA_IMPORT_RECURRING_DONATION_CARD_LAST_4)]: elevateBatchItem.cardLast4, }); + } else if (this.selectedPaymentMethod() === PAYMENT_METHOD_ACH) { + this.updateFormState({ + [apiNameFor(DATA_IMPORT_RECURRING_DONATION_ACH_LAST_4)]: + elevateBatchItem.achLast4, + }); } } } @@ -1145,7 +1158,7 @@ export default class GeFormRenderer extends LightningElement{ shouldTokenizeCard() { return Settings.isElevateCustomer() - && !!(this.showPaymentSaveNotice) + && this.isWidgetEnabled && this.hasChargeableTransactionStatus(); } @@ -1432,12 +1445,16 @@ export default class GeFormRenderer extends LightningElement{ } get isUpdateActionDisabled() { - return this.getFieldValueFromFormState(STATUS_FIELD) === 'Imported' || - this.saveDisabled || - ( - this.shouldShowElevateTransactionWarning && - this._isElevateWidgetInDisabledState - ); + let newPaymentInfoRequiredAndNotEntered = this.shouldShowElevateTransactionWarning && + this._isElevateWidgetInDisabledState; + return this.getFieldValueFromFormState(STATUS_FIELD) === GIFT_STATUSES.IMPORTED || + newPaymentInfoRequiredAndNotEntered || + this.saveDisabled || ( + + (this.isWidgetEnabled || this.isGiftCommitment()) && + GeGatewaySettings.isValidElevatePaymentMethod(this.selectedPaymentMethod()) && + this.getFieldValueFromFormState(DATA_IMPORT_RECURRING_TYPE) === RECURRING_TYPE_FIXED + ) } get cardholderNames() { @@ -1919,7 +1936,7 @@ export default class GeFormRenderer extends LightningElement{ } handleRegisterPaymentWidget() { - this._hasPaymentWidget = true; + this.hasPaymentWidget = true; } /******************************************************************************* @@ -2909,7 +2926,7 @@ export default class GeFormRenderer extends LightningElement{ return this.getFieldValueFromFormState(STATUS_FIELD) !== GIFT_STATUSES.IMPORTED && ( this.hasUnprocessedReadOnlyPaymentStatus(paymentStatus) || - this.getFieldValueFromFormState(DATA_IMPORT_RECURRING_DONATION_ELEVATE_ID) + !!this.getFieldValueFromFormState(DATA_IMPORT_RECURRING_DONATION_ELEVATE_ID) ); } diff --git a/force-app/main/default/lwc/geFormWidget/geFormWidget.js b/force-app/main/default/lwc/geFormWidget/geFormWidget.js index c46a3a88c7..07a36ed300 100644 --- a/force-app/main/default/lwc/geFormWidget/geFormWidget.js +++ b/force-app/main/default/lwc/geFormWidget/geFormWidget.js @@ -12,6 +12,8 @@ import DATA_IMPORT_PARENT_BATCH_LOOKUP from '@salesforce/schema/DataImport__c.NP import DATA_IMPORT_ID from '@salesforce/schema/DataImport__c.Id'; import DATA_IMPORT_RECURRING_DONATION_ELEVATE_ID from '@salesforce/schema/DataImport__c.Recurring_Donation_Elevate_Recurring_ID__c'; +import DATA_IMPORT_RECURRING_TYPE + from '@salesforce/schema/DataImport__c.Recurring_Donation_Recurring_Type__c'; import DATA_IMPORT_STATUS from '@salesforce/schema/DataImport__c.Status__c'; const ALLOCATION_WIDGET = 'geFormWidgetAllocation'; @@ -45,7 +47,8 @@ export default class GeFormWidget extends LightningElement { apiNameFor(DATA_IMPORT_PAYMENT_STATUS), apiNameFor(DATA_IMPORT_STATUS), apiNameFor(DATA_IMPORT_ID), - apiNameFor(DATA_IMPORT_RECURRING_DONATION_ELEVATE_ID) + apiNameFor(DATA_IMPORT_RECURRING_DONATION_ELEVATE_ID), + apiNameFor(DATA_IMPORT_RECURRING_TYPE) ]; get giftInViewHasSchedule() { diff --git a/force-app/main/default/lwc/geFormWidgetTokenizeCard/__tests__/geFormWidgetTokenizeCard.test.js b/force-app/main/default/lwc/geFormWidgetTokenizeCard/__tests__/geFormWidgetTokenizeCard.test.js index 4f16e8e161..1e953d6d1f 100644 --- a/force-app/main/default/lwc/geFormWidgetTokenizeCard/__tests__/geFormWidgetTokenizeCard.test.js +++ b/force-app/main/default/lwc/geFormWidgetTokenizeCard/__tests__/geFormWidgetTokenizeCard.test.js @@ -21,6 +21,8 @@ const PAYMENT_METHOD_FIELD = 'Payment_Method__c'; const DATA_IMPORT_PARENT_BATCH_LOOKUP = 'NPSP_Data_Import_Batch__c'; const DATA_IMPORT_PAYMENT_STATUS = 'Payment_Status__c'; +import RD2_ElevateRDCannotBeFixedLength from '@salesforce/label/c.RD2_ElevateRDCannotBeFixedLength'; + const createWidgetElement = () => { let element = createElement( 'c-ge-form-widget-tokenize-card', @@ -44,6 +46,109 @@ describe('c-ge-form-widget-tokenize-card', () => { clearDOM(); }); + it('should deactivate the widget in edit mode when a fixed recurring type gift is loaded', async() => { + const element = createWidgetElement(); + element.widgetDataFromState = { + 'Payment_Method__c': 'Credit Card', + 'Recurring_Donation_Recurring_Type__c': 'Fixed', + 'NPSP_Data_Import_Batch__c': 'DUMMY_BATCH_ID' + }; + document.body.appendChild(element); + + await flushPromises(); + + const deactivatedMessage = shadowQuerySelector(element, '[data-id="deactivatedMessage"]'); + const editPaymentInformationLink = shadowQuerySelector(element, '[data-id="editPaymentInformation"]'); + + expect(deactivatedMessage.textContent).toBe(RD2_ElevateRDCannotBeFixedLength); + expect(editPaymentInformationLink).toBeFalsy(); + }); + + it('should activate the widget when recurring type is changed from Fixed to Open', async() => { + const element = createWidgetElement(); + element.widgetDataFromState = { + 'Payment_Method__c': 'Credit Card', + 'Recurring_Donation_Recurring_Type__c': 'Fixed', + 'NPSP_Data_Import_Batch__c': 'DUMMY_BATCH_ID' + }; + document.body.appendChild(element); + await flushPromises(); + + const deactivatedMessage = shadowQuerySelector(element, '[data-id="deactivatedMessage"]'); + const editPaymentInformationLink = shadowQuerySelector(element, '[data-id="editPaymentInformation"]'); + + expect(deactivatedMessage.textContent).toBe(RD2_ElevateRDCannotBeFixedLength); + expect(editPaymentInformationLink).toBeFalsy(); + + element.widgetDataFromState = { + 'Payment_Method__c': 'Credit Card', + 'Recurring_Donation_Recurring_Type__c': 'Open', + 'NPSP_Data_Import_Batch__c': 'DUMMY_BATCH_ID' + }; + await flushPromises(); + + const deactivatedMessageReRendered = shadowQuerySelector(element, '[data-id="deactivatedMessage"]'); + expect(deactivatedMessageReRendered).toBeFalsy(); + + const chargeIFrameContainer = shadowQuerySelector(element, '[data-id="chargeIFrameContainer"]'); + expect(chargeIFrameContainer).toBeTruthy(); + }); + + it('should deactivate the widget in read-only mode when a fixed recurring type gift is loaded', async() => { + const element = createWidgetElement(); + element.widgetDataFromState = { + 'Payment_Method__c': 'Credit Card', + 'Recurring_Donation_Recurring_Type__c': 'Open', + 'NPSP_Data_Import_Batch__c': 'DUMMY_BATCH_ID', + 'Id': 'DUMMY_RECORD_ID' + }; + document.body.appendChild(element); + await flushPromises(); + + const dataImportRecord = { + 'Payment_Card_Last_4__c': '1234', + 'Payment_Card_Expiration_Month__c': 'testMonth', + 'Payment_Card_Expiration_Year__c': 'testYear' + }; + const dataImportObjectInfo = { + data: { + fields: { + 'Payment_Card_Last_4__c': 'yes', + 'Payment_Card_Expiration_Month__c': 'yes', + 'Payment_Card_Expiration_Year__c': 'yes' + } + } + }; + getObjectInfo.emit(dataImportObjectInfo); + await flushPromises(); + + getRecord.emit(dataImportRecord, record => { + record.recordId = 'DUMMY_RECORD_ID'; + return record; + }); + await flushPromises(); + + const readOnlyLayout = shadowQuerySelector(element, '[data-id="readOnlyLayout"]'); + expect(readOnlyLayout).toBeTruthy(); + + element.widgetDataFromState = { + 'Payment_Method__c': 'Credit Card', + 'Recurring_Donation_Recurring_Type__c': 'Fixed', + 'NPSP_Data_Import_Batch__c': 'DUMMY_BATCH_ID', + 'Id': 'DUMMY_RECORD_ID' + }; + await flushPromises(); + + const deactivatedMessage = shadowQuerySelector(element, '[data-id="deactivatedMessage"]'); + const editPaymentInformationLink = shadowQuerySelector(element, '[data-id="editPaymentInformation"]'); + + expect(deactivatedMessage.textContent).toBe(RD2_ElevateRDCannotBeFixedLength); + expect(editPaymentInformationLink).toBeFalsy(); + + const readOnlyLayoutReRendered = shadowQuerySelector(element, '[data-id="readOnlyLayout"]'); + expect(readOnlyLayoutReRendered).toBeFalsy(); + }); + it('should not render the iframe and related elements if is not an Elevate customer', async () => { Settings.isElevateCustomer = jest.fn(() => false); const element = createWidgetElement(); diff --git a/force-app/main/default/lwc/geFormWidgetTokenizeCard/geFormWidgetTokenizeCard.html b/force-app/main/default/lwc/geFormWidgetTokenizeCard/geFormWidgetTokenizeCard.html index 7470207ad8..582b632c50 100755 --- a/force-app/main/default/lwc/geFormWidgetTokenizeCard/geFormWidgetTokenizeCard.html +++ b/force-app/main/default/lwc/geFormWidgetTokenizeCard/geFormWidgetTokenizeCard.html @@ -35,7 +35,8 @@

icon-position="right" onclick={handleUserEditExpired} class='slds-button slds-button_base slds-float_right do-not-charge-card-button' - data-qa-locator={qaLocatorEditPaymentInformation}> + data-qa-locator={qaLocatorEditPaymentInformation} + data-id="editPaymentInformation"> @@ -79,7 +80,7 @@

icon={alert.icon} message={alert.message}> -
+
@@ -114,7 +115,7 @@