Коммит 3add422c создал по автору Vamsi Vempati's avatar Vamsi Vempati
Просмотр файлов

Manually update query variables to trigger invoice preview query

- This change attempts at achieving better control over when invoice
preview query is triggered so we don't accidentally end up with an
infinite loop of calls
владелец cd1604e8
......@@ -37,11 +37,7 @@ export default {
client: CUSTOMERSDOT_CLIENT,
query: invoicePreviewQuery,
variables() {
return {
planId: this.selectedPlan,
quantity: this.numberOfUsers,
...(this.sendPromoCodeToPreviewInvoice && { promoCode: this.promoCode }),
};
return this.invoicePreviewQueryVariables;
},
update(data) {
if (this.sendPromoCodeToPreviewInvoice) {
......@@ -58,9 +54,7 @@ export default {
},
skip() {
return (
!this.usersPresent ||
!this.selectedPlan ||
!this.glFeatures.useInvoicePreviewApiInSaasPurchase
!this.invoicePreviewQueryVariables || !this.glFeatures.useInvoicePreviewApiInSaasPurchase
);
},
},
......@@ -69,10 +63,13 @@ export default {
return {
invoicePreview: undefined,
promoCodeErrorMessage: undefined,
invoicePreviewQueryVariables: undefined,
promoCode: undefined,
isPromoCodeInvalid: false,
};
},
computed: {
...mapState(['numberOfUsers', 'selectedPlan', 'promoCode']),
...mapState(['numberOfUsers', 'selectedPlan']),
...mapGetters([
'selectedPlanPrice',
'name',
......@@ -124,19 +121,32 @@ export default {
showSuccessAlert() {
return this.showAmount && this.hasDiscount;
},
isPromoCodeInvalid() {
return this.promoCodeErrorMessage === INVALID_PROMO_CODE_ERROR_MESSAGE;
},
},
watch: {
selectedPlan() {
this.resetPromoCodeErrorMessage();
},
usersPresent(usersPresent) {
// Clear promo code quantity error message when quantity is valid
if (usersPresent && this.promoCodeErrorMessage === PROMO_CODE_USER_QUANTITY_ERROR_MESSAGE) {
selectedPlan: {
handler() {
this.resetPromoCodeErrorMessage();
}
this.updateInvoicePreviewQueryVariables();
},
immediate: true,
},
numberOfUsers: {
handler(numberOfUsers) {
// Clear promo code quantity error message when quantity is valid
if (
numberOfUsers > 0 &&
this.promoCodeErrorMessage === PROMO_CODE_USER_QUANTITY_ERROR_MESSAGE
) {
this.resetPromoCodeErrorMessage();
}
this.updateInvoicePreviewQueryVariables();
},
immediate: true,
},
promoCode(promoCode) {
// maintain a local state for promo code to avoid issues due to potential delay in promo
// code change in state when updating invoice query variables which depends on promo code
this.updatePromoCode(promoCode);
},
legacyInvoicePreview: {
handler(val) {
......@@ -150,10 +160,6 @@ export default {
immediate: true,
},
invoicePreview(val) {
if (val) {
this.clearError();
}
this.updateInvoicePreview(val);
},
},
......@@ -165,6 +171,23 @@ export default {
clearError() {
this.$emit(PurchaseEvent.ERROR_RESET);
},
updateInvoicePreviewQueryVariables() {
if (!this.glFeatures.useInvoicePreviewApiInSaasPurchase) {
return;
}
this.clearError();
if (!this.selectedPlan || !this.usersPresent) {
return;
}
this.invoicePreviewQueryVariables = {
planId: this.selectedPlan,
quantity: this.numberOfUsers,
...(this.sendPromoCodeToPreviewInvoice ? { promoCode: this.promoCode } : {}),
};
},
handleError(error) {
this.invoicePreview = null;
......@@ -177,6 +200,7 @@ export default {
const { message } = gqlErrorExtensions || {};
if (isInvalidPromoCodeError(gqlErrorExtensions)) {
this.isPromoCodeInvalid = true;
this.promoCodeErrorMessage = INVALID_PROMO_CODE_ERROR_MESSAGE;
this.track('failure_response', { label: 'apply_coupon_code_failure_saas' });
return;
......@@ -203,24 +227,33 @@ export default {
resetPromoCodeErrorMessage() {
this.promoCodeErrorMessage = undefined;
},
handlePromoCodeUpdate() {
// reset promo code when updated until requested to apply to avoid
// using previously entered values in preview/purchase API calls
this.updatePromoCode('');
this.resetPromoCodeErrorMessage();
},
applyPromoCode(promoCode) {
if (this.usersPresent) {
this.clearError();
this.resetPromoCodeErrorMessage();
this.updatePromoCode(promoCode);
handlePromoCodeUpdate(promoCode) {
// Clear promo code until applied again
this.promoCode = undefined;
if (this.sendPromoCodeToPreviewInvoice) {
this.track('click_button', { label: 'apply_coupon_code_saas' });
}
// Only preview transaction if previous promo code is invalid, otherwise we will have price details already
if (!promoCode && this.promoCodeErrorMessage) {
this.resetPromoCodeErrorMessage();
this.updateInvoicePreviewQueryVariables();
} else {
this.resetPromoCodeErrorMessage();
}
},
applyPromoCode(promoCode) {
if (!this.usersPresent) {
this.promoCodeErrorMessage = PROMO_CODE_USER_QUANTITY_ERROR_MESSAGE;
return;
}
if (promoCode !== this.promoCode) {
this.isPromoCodeInvalid = false;
this.resetPromoCodeErrorMessage();
}
this.promoCode = promoCode;
this.updateInvoicePreviewQueryVariables();
this.track('click_button', { label: 'apply_coupon_code_saas' });
},
},
i18n: {
......
......@@ -67,7 +67,7 @@ export default {
this.$emit('apply-promo-code', this.promoCode);
},
updatePromoCode() {
this.$emit('promo-code-updated');
this.$emit('promo-code-updated', this.promoCode);
},
},
PROMO_CODE_TERMS_LINK,
......
......@@ -213,7 +213,7 @@ describe('Order Summary', () => {
});
it('emits `error-reset` event', () => {
expect(wrapper.emitted(PurchaseEvent.ERROR_RESET)).toHaveLength(2);
expect(wrapper.emitted(PurchaseEvent.ERROR_RESET)).toHaveLength(3);
});
});
});
......@@ -588,8 +588,10 @@ describe('Order Summary', () => {
assertEmptyPriceDetails();
});
it('requests invoice preview without promo code after an invalid promo code', () => {
expect(invoicePreviewSpy).toHaveBeenLastCalledWith({ planId: 'secondPlanId', quantity: 1 });
it('does not send an invalid promo code to preview when updating quantity', async () => {
await store.commit(types.UPDATE_NUMBER_OF_USERS, 2);
expect(invoicePreviewSpy).toHaveBeenLastCalledWith({ planId: 'secondPlanId', quantity: 2 });
});
it('tracks events for failing to apply a promo code', () => {
......@@ -634,12 +636,28 @@ describe('Order Summary', () => {
expect(promoCodeInput.props('errorMessage')).toBe(INVALID_PROMO_CODE_ERROR_MESSAGE);
});
it('resets promo code value on update', () => {
promoCodeInput.vm.$emit('promo-code-updated');
describe('when promo code value has been reset', () => {
beforeEach(async () => {
findPromoCodeInput().vm.$emit('promo-code-updated', '');
await waitForPromises();
});
expect(invoicePreviewSpy).toHaveBeenCalledWith({
planId: 'secondPlanId',
quantity: 1,
it('fetches invoice preview without promo code', async () => {
expect(invoicePreviewSpy).toHaveBeenLastCalledWith({
planId: 'secondPlanId',
quantity: 1,
});
});
});
describe('promo code value has been updated to a different value', () => {
beforeEach(async () => {
findPromoCodeInput().vm.$emit('promo-code-updated', 'another-promo-code');
await waitForPromises();
});
it('resets promo code error message', async () => {
expect(findPromoCodeInput().props('errorMessage')).toBe('');
});
});
});
......
......@@ -42,7 +42,7 @@ describe('PromoCodeInput', () => {
enterPromoCode();
await wrapper.find('input').trigger('change');
expect(wrapper.emitted('promo-code-updated')).toHaveLength(1);
expect(wrapper.emitted('promo-code-updated')).toEqual([[samplePromoCode]]);
});
it('emits an event on applying promo code', async () => {
......
Поддерживает Markdown
0% или .
You are about to add 0 people to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Пожалуйста, зарегистрируйтесь или чтобы прокомментировать