SSR-1064 payment method updates
This commit is contained in:
parent
aefadce025
commit
553e6c03f6
7 changed files with 154 additions and 137 deletions
|
|
@ -1,7 +1,9 @@
|
|||
export const paymentMethods = {
|
||||
const paymentMethods = Object.freeze({
|
||||
NONE: null,
|
||||
LATER: 'Later',
|
||||
PAY_AT_TIME_OF_SERVICE: 'PayAtTimeOfService',
|
||||
CREDIT_CARD: 'CreditCard',
|
||||
PAYPAL: 'Paypal',
|
||||
AFTERPAY: 'Afterpay'
|
||||
};
|
||||
});
|
||||
|
||||
export default paymentMethods;
|
||||
|
|
|
|||
|
|
@ -3,37 +3,34 @@ import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
|||
|
||||
import paymentMethodQuestion from '@/layouts/payment-method/payment-method-question/payment-method-question.vue';
|
||||
|
||||
const testConstants = {
|
||||
cms: {
|
||||
question: {
|
||||
text: 'Choose a payment option'
|
||||
},
|
||||
answers: {
|
||||
optionA: {
|
||||
name: 'NameA',
|
||||
text: 'TextA',
|
||||
subText: 'SubTextA',
|
||||
imageId: 'idA',
|
||||
image: 'imageA',
|
||||
subWidget: 'subWidgetA'
|
||||
},
|
||||
optionB: {
|
||||
name: 'NameB',
|
||||
text: 'TextB',
|
||||
subText: 'SubTextB',
|
||||
imageId: 'idB',
|
||||
image: 'imageB',
|
||||
subWidget: 'subWidgetB'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let cmsContent;
|
||||
|
||||
const mockCmsContent = {
|
||||
QuestionText: 'Choose a payment option',
|
||||
Answers: [
|
||||
{
|
||||
Name: 'NameA',
|
||||
Text: 'TextA',
|
||||
SubText: 'SubTextA',
|
||||
ImageId: 'idA',
|
||||
AnswerImageUrl: 'imageA',
|
||||
SubWidgetName: 'subWidgetA'
|
||||
},
|
||||
{
|
||||
Name: 'NameB',
|
||||
Text: 'TextB',
|
||||
SubText: 'SubTextB',
|
||||
ImageId: 'idB',
|
||||
AnswerImageUrl: 'imageB',
|
||||
SubWidgetName: 'subWidgetB'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
function generateDefaultProps() {
|
||||
return {
|
||||
modelValue: 'modelValue'
|
||||
modelValue: 'modelValue',
|
||||
cmsWidgetName: 'PaymentMethodWidget'
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -42,7 +39,7 @@ function setupMocks(customMountOptions) {
|
|||
|
||||
const mockMixin = {
|
||||
methods: {
|
||||
getCmsContent: jest.fn((widgetName, cmsFieldName) => cmsContent?.[widgetName]?.[cmsFieldName] ?? '')
|
||||
getCmsContent: jest.fn((widgetName, cmsFieldName) => cmsContent[cmsFieldName])
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -55,31 +52,8 @@ function setupMocks(customMountOptions) {
|
|||
|
||||
describe('Payment Method Question', () => {
|
||||
beforeEach(() => {
|
||||
cmsContent = {
|
||||
PaymentMethodWidget: {
|
||||
QuestionText: testConstants.cms.question,
|
||||
Answers: [
|
||||
{
|
||||
Name: testConstants.cms.answers.optionA.name,
|
||||
Text: testConstants.cms.answers.optionA.text,
|
||||
SubText: testConstants.cms.answers.optionA.subText,
|
||||
ImageId: testConstants.cms.answers.optionA.imageId,
|
||||
AnswerImageUrl: testConstants.cms.answers.optionA.image,
|
||||
SubWidgetName: testConstants.cms.answers.optionA.subWidget
|
||||
},
|
||||
{
|
||||
Name: testConstants.cms.answers.optionB.name,
|
||||
Text: testConstants.cms.answers.optionB.text,
|
||||
SubText: testConstants.cms.answers.optionB.subText,
|
||||
ImageId: testConstants.cms.answers.optionB.imageId,
|
||||
AnswerImageUrl: testConstants.cms.answers.optionB.image,
|
||||
SubWidgetName: testConstants.cms.answers.optionB.subWidget
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
cmsContent = mockCmsContent;
|
||||
});
|
||||
|
||||
it('Should map cms content correctly', () => {
|
||||
// Arrange
|
||||
const props = generateDefaultProps();
|
||||
|
|
@ -94,18 +68,18 @@ describe('Payment Method Question', () => {
|
|||
// Assert
|
||||
expect(mappedContent).toEqual([
|
||||
{
|
||||
buttonLabel: testConstants.cms.answers.optionA.text,
|
||||
altText: testConstants.cms.answers.optionA.text,
|
||||
buttonLabel: cmsContent.Answers[0].Text,
|
||||
altText: cmsContent.Answers[0].Text,
|
||||
groupName: 'payment-method',
|
||||
value: testConstants.cms.answers.optionA.name,
|
||||
buttonImage: testConstants.cms.answers.optionA.image
|
||||
value: cmsContent.Answers[0].Name,
|
||||
buttonImage: cmsContent.Answers[0].AnswerImageUrl
|
||||
},
|
||||
{
|
||||
buttonLabel: testConstants.cms.answers.optionB.text,
|
||||
altText: testConstants.cms.answers.optionB.text,
|
||||
buttonLabel: cmsContent.Answers[1].Text,
|
||||
altText: cmsContent.Answers[1].Text,
|
||||
groupName: 'payment-method',
|
||||
value: testConstants.cms.answers.optionB.name,
|
||||
buttonImage: testConstants.cms.answers.optionB.image
|
||||
value: cmsContent.Answers[1].Name,
|
||||
buttonImage: cmsContent.Answers[1].AnswerImageUrl
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -15,7 +15,9 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import buttonQuestion from '@/digital-components/button-question/button-question.vue';
|
||||
import widgetFields from '@/constants/cms-widget-fields.js';
|
||||
import paymentMethodListButton from './payment-method-list-button/payment-method-list-button.vue';
|
||||
|
||||
export default {
|
||||
|
|
@ -25,8 +27,10 @@ export default {
|
|||
},
|
||||
props: {
|
||||
modelValue: String,
|
||||
validationRules: String
|
||||
validationRules: String,
|
||||
cmsWidgetName: String
|
||||
},
|
||||
emits: ['update:modelValue'],
|
||||
data() {
|
||||
return {
|
||||
paymentMethodListButton
|
||||
|
|
@ -34,33 +38,31 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
selectedMethod: {
|
||||
get: function () {
|
||||
get() {
|
||||
return this.modelValue;
|
||||
},
|
||||
set: function (selectedMethod) {
|
||||
set(selectedMethod) {
|
||||
this.$emit('update:modelValue', selectedMethod);
|
||||
},
|
||||
}
|
||||
},
|
||||
paymentMethodQuestionText() {
|
||||
return this.getCmsContent('PaymentMethodWidget', 'QuestionText');
|
||||
return this.getCmsContent(this.cmsWidgetName, widgetFields.INPUT_QUESTION_WIDGET.QUESTION_TEXT);
|
||||
},
|
||||
paymentMethodAnswerData() {
|
||||
const cmsData = this.getAnswersNullSafe('PaymentMethodWidget');
|
||||
const cmsData = this.getAnswersNullSafe(this.cmsWidgetName);
|
||||
|
||||
return cmsData.map((answer) => {
|
||||
return {
|
||||
buttonLabel: answer.Text,
|
||||
altText: answer.Text,
|
||||
groupName: 'payment-method',
|
||||
value: answer.Name,
|
||||
buttonImage: answer.AnswerImageUrl
|
||||
};
|
||||
});
|
||||
return cmsData.map((answer) => ({
|
||||
buttonLabel: answer.Text,
|
||||
altText: answer.Text,
|
||||
groupName: 'payment-method',
|
||||
value: answer.Name,
|
||||
buttonImage: answer.AnswerImageUrl
|
||||
}));
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getAnswersNullSafe(widgetName) {
|
||||
const rawData = this.getCmsContent(widgetName, 'Answers');
|
||||
const rawData = this.getCmsContent(widgetName, widgetFields.INPUT_QUESTION_WIDGET.ANSWERS);
|
||||
|
||||
if (!rawData) {
|
||||
return [];
|
||||
|
|
@ -72,11 +74,11 @@ export default {
|
|||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
<style lang="scss" scoped>
|
||||
.payment-method-question {
|
||||
.question-text span {
|
||||
:deep(.question-text span) {
|
||||
text-align: left;
|
||||
line-height: 24px;
|
||||
line-height: 1.5rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
43
src/layouts/payment-method/payment-method.spec.js
Normal file
43
src/layouts/payment-method/payment-method.spec.js
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
// Components
|
||||
import paymentMethod from '@/layouts/payment-method/payment-method.vue';
|
||||
|
||||
// Supporting Files
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
||||
import { useMainStore } from '@/store';
|
||||
import paymentMethods from '@/constants/payment-method-constants';
|
||||
|
||||
function setupMocks() {
|
||||
const mountOptions = getMountOptions();
|
||||
|
||||
const wrapper = shallowMount(paymentMethod, mountOptions);
|
||||
|
||||
return { wrapper };
|
||||
}
|
||||
|
||||
describe('payment-method.vue', () => {
|
||||
test('getting payment method when method is pay later', async () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks();
|
||||
const payLaterPaymentMethod = paymentMethods.PAY_AT_TIME_OF_SERVICE;
|
||||
useMainStore().savePaymentMethodChoice(payLaterPaymentMethod);
|
||||
|
||||
// Act
|
||||
const paymethod = wrapper.vm.getPaymentMethodFromStore();
|
||||
|
||||
// Assert
|
||||
expect(paymethod).toBe(payLaterPaymentMethod);
|
||||
});
|
||||
test('getting payment method when method is pay in advance', async () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks();
|
||||
const payInAdvancePaymentMethod = paymentMethods.CREDIT_CARD;
|
||||
useMainStore().savePaymentMethodChoice(payInAdvancePaymentMethod);
|
||||
|
||||
// Act
|
||||
const paymethod = wrapper.vm.getPaymentMethodFromStore();
|
||||
|
||||
// Assert
|
||||
expect(paymethod).not.toBe(payInAdvancePaymentMethod);
|
||||
});
|
||||
});
|
||||
|
|
@ -22,9 +22,9 @@
|
|||
<hr class="my-5" />
|
||||
<div>Pia Alert Placeholder</div>
|
||||
<paymentMethodQuestion
|
||||
v-if="!isPiaDisabled"
|
||||
v-model="paymentMethodInternalModel"
|
||||
validationRules="option-required" />
|
||||
cmsWidgetName="PaymentMethodWidget"
|
||||
:validationRules="rules.optionRequired" />
|
||||
<div>Pia Disabled Placeholder</div>
|
||||
<siteFooter
|
||||
ref="siteFooter"
|
||||
|
|
@ -51,15 +51,15 @@ import paymentMethodQuestion from '@/layouts/payment-method/payment-method-quest
|
|||
import settleAllPromises from '@/helpers/layout-helper';
|
||||
import { useMainStore } from '@/store';
|
||||
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
||||
import { paymentMethods } from '@/constants/payment-method-constants';
|
||||
|
||||
import paymentMethods from '@/constants/payment-method-constants';
|
||||
import globalRules from '@/constants/global-rules';
|
||||
import { Form, defineRule } from 'vee-validate';
|
||||
|
||||
import { required } from '@/helpers/validation-rules';
|
||||
import errorMessages from '@/constants/error-messages';
|
||||
import { AppointmentTypeStrings } from '@/constants/schedule-constants';
|
||||
|
||||
defineRule('option-required', required(errorMessages.OPTION_REQUIRED));
|
||||
defineRule(globalRules.OPTION_REQUIRED, required(errorMessages.OPTION_REQUIRED));
|
||||
|
||||
export default {
|
||||
name: 'payment-method',
|
||||
|
|
@ -93,21 +93,24 @@ export default {
|
|||
next((vm) => {
|
||||
vm.setCmsContent(resultMap.cmsContent);
|
||||
|
||||
vm.updateFooterButtonText(vm.customCtaCopy);
|
||||
vm.updateFooterButtonText(vm.customCallToActionButtonCopy);
|
||||
|
||||
vm.$refs.reviewDropdown.initializeComponent(resultMap.reviewDropdownData);
|
||||
});
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
paymentMethodInternalModel: this.getPaymentMethodFromStore()
|
||||
paymentMethodInternalModel: this.getPaymentMethodFromStore(),
|
||||
rules: {
|
||||
optionRequired: globalRules.OPTION_REQUIRED
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
damageInfo() {
|
||||
return useMainStore().order.damage;
|
||||
},
|
||||
customCtaCopy() {
|
||||
customCallToActionButtonCopy() {
|
||||
switch (this.paymentMethod) {
|
||||
case paymentMethods.CREDIT_CARD:
|
||||
return 'Continue to checkout';
|
||||
|
|
@ -119,28 +122,12 @@ export default {
|
|||
return null;
|
||||
}
|
||||
},
|
||||
isPiaDisabled() {
|
||||
// do we have this experiment in NextGen ISS?
|
||||
|
||||
/*
|
||||
const piaExperience = this.getSettingValue(experimentSettings.PIA_EXPERIENCE);
|
||||
|
||||
const isEnabled = piaExperience === "PIA Optional" || piaExperience === "PIA Required";
|
||||
|
||||
return !isEnabled;
|
||||
*/
|
||||
return false;
|
||||
},
|
||||
paymentMethod() {
|
||||
if (this.isPiaDisabled) {
|
||||
return paymentMethods.LATER;
|
||||
}
|
||||
|
||||
return this.paymentMethodInternalModel;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
customCtaCopy(newValue) {
|
||||
customCallToActionButtonCopy(newValue) {
|
||||
this.updateFooterButtonText(newValue);
|
||||
}
|
||||
},
|
||||
|
|
@ -214,36 +201,19 @@ export default {
|
|||
);
|
||||
},
|
||||
getPaymentMethodFromStore() {
|
||||
const { piaType } = useMainStore().order.payment;
|
||||
const isPia = useMainStore().order.payment.isPia && !!piaType;
|
||||
const { payInAdvanceType } = useMainStore().order.payment;
|
||||
const isPayInAdvance = useMainStore().order.payment.isPayInAdvance && !!payInAdvanceType;
|
||||
|
||||
return isPia ? piaType : paymentMethods.LATER;
|
||||
return isPayInAdvance ? payInAdvanceType : paymentMethods.PAY_AT_TIME_OF_SERVICE;
|
||||
},
|
||||
updateFooterButtonText(newValue) {
|
||||
this.$refs.siteFooter.updateButtonText(newValue);
|
||||
},
|
||||
async forwardButtonAction() {
|
||||
// Multiple paths based on payment
|
||||
console.log('forward button hit...');
|
||||
|
||||
await useMainStore().savePaymentMethodChoice(this.paymentMethod);
|
||||
|
||||
if (this.paymentMethod === paymentMethods.LATER) {
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.CLICKED_FORWARD,
|
||||
this.$route
|
||||
);
|
||||
} else {
|
||||
this.setupPia();
|
||||
}
|
||||
},
|
||||
async setupPia() {
|
||||
this.$refs.loadingModal.showModal();
|
||||
|
||||
// if we don't have a work order in delete substatus, set the flag and submit.
|
||||
// we need a work order number for pia so we can pass it to safeliteHop.
|
||||
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.CLICKED_PAY_NOW,
|
||||
this.$route
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import damageLocationsSelected from '@/constants/damage-locations-selected';
|
|||
import coverageStatuses from '@/constants/coverage-statuses';
|
||||
import { AppointmentTypeStrings, PREMIUM_FEE_PART_TYPE } from '@/constants/schedule-constants';
|
||||
import { convertDateStringToDate, getDateDifferenceInDays, militaryToTwelveHourTime } from '@/helpers/date-helper';
|
||||
import { paymentMethods } from '@/constants/payment-method-constants';
|
||||
import paymentMethods from '@/constants/payment-method-constants';
|
||||
|
||||
const storeId = 'main';
|
||||
|
||||
|
|
@ -149,8 +149,8 @@ const getDefaultState = () => ({
|
|||
claimNumber: null
|
||||
},
|
||||
parentAccountNumber: 0,
|
||||
isPia: null,
|
||||
piaType: null
|
||||
isPayInAdvance: null,
|
||||
payInAdvanceType: null
|
||||
},
|
||||
contactInfo: {
|
||||
firstName: null,
|
||||
|
|
@ -2141,10 +2141,10 @@ export const useMainStore = defineStore({
|
|||
},
|
||||
|
||||
savePaymentMethodChoice(paymentMethod) {
|
||||
const isPia = paymentMethod !== paymentMethods.LATER;
|
||||
this.order.payment.isPia = isPia;
|
||||
this.order.payment.piaType = isPia ? paymentMethod : null;
|
||||
},
|
||||
const isPayInAdvance = paymentMethod !== paymentMethods.PAY_AT_TIME_OF_SERVICE;
|
||||
this.order.payment.isPayInAdvance = isPayInAdvance;
|
||||
this.order.payment.payInAdvanceType = isPayInAdvance ? paymentMethod : null;
|
||||
}
|
||||
|
||||
},
|
||||
persist: true
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { useMainStore } from '@/store/index.js';
|
|||
import globalMethods from '@/global-methods.js';
|
||||
import { getRandomString, getRandomGuid, getRandomInt, getRandomBoolean } from '@/helpers/data-generation.js';
|
||||
import coverageStatuses from '@/constants/coverage-statuses.js';
|
||||
import paymentMethods from '@/constants/payment-method-constants';
|
||||
import { endpoints } from '@/constants/endpoints';
|
||||
import { AppointmentTypeStrings } from '@/constants/schedule-constants';
|
||||
|
||||
|
|
@ -2083,4 +2084,29 @@ describe('Store', () => {
|
|||
expect(store.order.policy.policyLookupSuccessful).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('savePaymentMethodChoice method', () => {
|
||||
it('isPayInAdvance saved as false when choice is to pay at time of servce', () => {
|
||||
// Arrange
|
||||
const paymentMethod = paymentMethods.PAY_AT_TIME_OF_SERVICE;
|
||||
|
||||
// Act
|
||||
store.savePaymentMethodChoice(paymentMethod);
|
||||
|
||||
// Assert
|
||||
expect(store.order.payment.isPayInAdvance).toEqual(false);
|
||||
expect(store.order.payment.payInAdvanceType).toEqual(null);
|
||||
});
|
||||
it('isPayInAdvance saved as true when choice is other than to pay at time of servce', () => {
|
||||
// Arrange
|
||||
const paymentMethod = paymentMethods.CREDIT_CARD;
|
||||
|
||||
// Act
|
||||
store.savePaymentMethodChoice(paymentMethod);
|
||||
|
||||
// Assert
|
||||
expect(store.order.payment.isPayInAdvance).toEqual(true);
|
||||
expect(store.order.payment.payInAdvanceType).toEqual(paymentMethod);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue