mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 06:37:23 +01:00
continuation of PR #8161 Display error notification when attempting to purchase invalid amount of gems - fixes #8145 (#8688)
* Translation string for error notification * Use function instead of a link for paypal * Inject notification service, function to check the amount of gems to purchase, function to handle payments with paypal * Throw error if amount of gems is zero or negative * Add condition to raise error if amount is negative * Added gem errors for gifts 0 or less * Fixed linting and broken test * Fixed test syntax * Added back needed strings * Fixed group locales
This commit is contained in:
committed by
Sabe Jones
parent
48bbc22fb4
commit
e901850a6f
@@ -113,6 +113,25 @@ describe('Amazon Payments', () => {
|
|||||||
expectAmazonStubs();
|
expectAmazonStubs();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should error if gem amount is too low', async () => {
|
||||||
|
let receivingUser = new User();
|
||||||
|
receivingUser.save();
|
||||||
|
let gift = {
|
||||||
|
type: 'gems',
|
||||||
|
gems: {
|
||||||
|
amount: 0,
|
||||||
|
uuid: receivingUser._id,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
await expect(amzLib.checkout({gift, user, orderReferenceId, headers}))
|
||||||
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
|
httpCode: 400,
|
||||||
|
message: 'Amount must be at least 1.',
|
||||||
|
name: 'BadRequest',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should gift gems', async () => {
|
it('should gift gems', async () => {
|
||||||
let receivingUser = new User();
|
let receivingUser = new User();
|
||||||
receivingUser.save();
|
receivingUser.save();
|
||||||
|
|||||||
@@ -68,6 +68,25 @@ describe('Paypal Payments', () => {
|
|||||||
expect(link).to.eql(approvalHerf);
|
expect(link).to.eql(approvalHerf);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should error if gem amount is too low', async () => {
|
||||||
|
let receivingUser = new User();
|
||||||
|
receivingUser.save();
|
||||||
|
let gift = {
|
||||||
|
type: 'gems',
|
||||||
|
gems: {
|
||||||
|
amount: 0,
|
||||||
|
uuid: receivingUser._id,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
await expect(paypalPayments.checkout({gift}))
|
||||||
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
|
httpCode: 400,
|
||||||
|
message: 'Amount must be at least 1.',
|
||||||
|
name: 'BadRequest',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('creates a link for gifting gems', async () => {
|
it('creates a link for gifting gems', async () => {
|
||||||
let receivingUser = new User();
|
let receivingUser = new User();
|
||||||
let gift = {
|
let gift = {
|
||||||
|
|||||||
@@ -48,7 +48,36 @@ describe('Stripe Payments', () => {
|
|||||||
payments.createSubscription.restore();
|
payments.createSubscription.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should error if gem amount is too low', async () => {
|
||||||
|
let receivingUser = new User();
|
||||||
|
receivingUser.save();
|
||||||
|
gift = {
|
||||||
|
type: 'gems',
|
||||||
|
gems: {
|
||||||
|
amount: 0,
|
||||||
|
uuid: receivingUser._id,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
await expect(stripePayments.checkout({
|
||||||
|
token,
|
||||||
|
user,
|
||||||
|
gift,
|
||||||
|
groupId,
|
||||||
|
email,
|
||||||
|
headers,
|
||||||
|
coupon,
|
||||||
|
}, stripe))
|
||||||
|
.to.eventually.be.rejected.and.to.eql({
|
||||||
|
httpCode: 400,
|
||||||
|
message: 'Amount must be at least 1.',
|
||||||
|
name: 'BadRequest',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should purchase gems', async () => {
|
it('should purchase gems', async () => {
|
||||||
|
gift = undefined;
|
||||||
|
|
||||||
await stripePayments.checkout({
|
await stripePayments.checkout({
|
||||||
token,
|
token,
|
||||||
user,
|
user,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('habitrpg').factory('Payments',
|
angular.module('habitrpg').factory('Payments',
|
||||||
['$rootScope', 'User', '$http', 'Content',
|
['$rootScope', 'User', '$http', 'Content', 'Notification',
|
||||||
function($rootScope, User, $http, Content) {
|
function($rootScope, User, $http, Content, Notification) {
|
||||||
var Payments = {};
|
var Payments = {};
|
||||||
var isAmazonReady = false;
|
var isAmazonReady = false;
|
||||||
Payments.amazonButtonEnabled = true;
|
Payments.amazonButtonEnabled = true;
|
||||||
@@ -21,7 +21,18 @@ function($rootScope, User, $http, Content) {
|
|||||||
amazon.Login.setClientId(window.env.AMAZON_PAYMENTS.CLIENT_ID);
|
amazon.Login.setClientId(window.env.AMAZON_PAYMENTS.CLIENT_ID);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Payments.checkGemAmount = function(data) {
|
||||||
|
if(data.gift.type === "gems" && !data.gift.gems.amount || data.gift.gems.amount === 0) {
|
||||||
|
Notification.error(window.env.t('badAmountOfGemsToPurchase'), true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
Payments.showStripe = function(data) {
|
Payments.showStripe = function(data) {
|
||||||
|
|
||||||
|
if(!Payments.checkGemAmount(data)) return;
|
||||||
|
|
||||||
var sub = false;
|
var sub = false;
|
||||||
|
|
||||||
if (data.subscription) {
|
if (data.subscription) {
|
||||||
@@ -121,6 +132,7 @@ function($rootScope, User, $http, Content) {
|
|||||||
// Needs to be called everytime the modal/router is accessed
|
// Needs to be called everytime the modal/router is accessed
|
||||||
Payments.amazonPayments.init = function(data) {
|
Payments.amazonPayments.init = function(data) {
|
||||||
if(!isAmazonReady) return;
|
if(!isAmazonReady) return;
|
||||||
|
if(!Payments.checkGemAmount(data)) return;
|
||||||
if(data.type !== 'single' && data.type !== 'subscription') return;
|
if(data.type !== 'single' && data.type !== 'subscription') return;
|
||||||
|
|
||||||
if (data.gift) {
|
if (data.gift) {
|
||||||
@@ -345,6 +357,14 @@ function($rootScope, User, $http, Content) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Payments.payPalPayment = function(data){
|
||||||
|
if(!Payments.checkGemAmount(data)) return;
|
||||||
|
|
||||||
|
var gift = Payments.encodeGift(data.giftedTo, data.gift);
|
||||||
|
var url = '/paypal/checkout?_id=' + User.user._id + '&apiToken=' + User.settings.auth.apiToken + '&gift=' + gift;
|
||||||
|
$http.get(url);
|
||||||
|
}
|
||||||
|
|
||||||
Payments.encodeGift = function(uuid, gift) {
|
Payments.encodeGift = function(uuid, gift) {
|
||||||
gift.uuid = uuid;
|
gift.uuid = uuid;
|
||||||
var encodedString = JSON.stringify(gift);
|
var encodedString = JSON.stringify(gift);
|
||||||
|
|||||||
@@ -286,5 +286,6 @@
|
|||||||
"leaderMarker": " - Leader",
|
"leaderMarker": " - Leader",
|
||||||
"managerMarker": " - Manager",
|
"managerMarker": " - Manager",
|
||||||
"joinedGuild": "Joined a Guild",
|
"joinedGuild": "Joined a Guild",
|
||||||
"joinedGuildText": "Ventured into the social side of Habitica by joining a Guild!"
|
"joinedGuildText": "Ventured into the social side of Habitica by joining a Guild!",
|
||||||
|
"badAmountOfGemsToPurchase": "Amount must be at least 1."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,6 +98,9 @@ api.checkout = async function checkout (options = {}) {
|
|||||||
|
|
||||||
if (gift) {
|
if (gift) {
|
||||||
if (gift.type === this.constants.GIFT_TYPE_GEMS) {
|
if (gift.type === this.constants.GIFT_TYPE_GEMS) {
|
||||||
|
if (gift.gems.amount <= 0) {
|
||||||
|
throw new BadRequest(i18n.t('badAmountOfGemsToPurchase'));
|
||||||
|
}
|
||||||
amount = gift.gems.amount / 4;
|
amount = gift.gems.amount / 4;
|
||||||
} else if (gift.type === this.constants.GIFT_TYPE_SUBSCRIPTION) {
|
} else if (gift.type === this.constants.GIFT_TYPE_SUBSCRIPTION) {
|
||||||
amount = common.content.subscriptionBlocks[gift.subscription.key].price;
|
amount = common.content.subscriptionBlocks[gift.subscription.key].price;
|
||||||
|
|||||||
@@ -74,6 +74,9 @@ api.checkout = async function checkout (options = {}) {
|
|||||||
let description = 'Habitica Gems';
|
let description = 'Habitica Gems';
|
||||||
if (gift) {
|
if (gift) {
|
||||||
if (gift.type === 'gems') {
|
if (gift.type === 'gems') {
|
||||||
|
if (gift.gems.amount <= 0) {
|
||||||
|
throw new BadRequest(i18n.t('badAmountOfGemsToPurchase'));
|
||||||
|
}
|
||||||
amount = Number(gift.gems.amount / 4).toFixed(2);
|
amount = Number(gift.gems.amount / 4).toFixed(2);
|
||||||
description = `${description} (Gift)`;
|
description = `${description} (Gift)`;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -107,6 +107,9 @@ api.checkout = async function checkout (options, stripeInc) {
|
|||||||
if (gift.type === 'subscription') {
|
if (gift.type === 'subscription') {
|
||||||
amount = `${shared.content.subscriptionBlocks[gift.subscription.key].price * 100}`;
|
amount = `${shared.content.subscriptionBlocks[gift.subscription.key].price * 100}`;
|
||||||
} else {
|
} else {
|
||||||
|
if (gift.gems.amount <= 0) {
|
||||||
|
throw new BadRequest(shared.i18n.t('badAmountOfGemsToPurchase'));
|
||||||
|
}
|
||||||
amount = `${gift.gems.amount / 4 * 100}`;
|
amount = `${gift.gems.amount / 4 * 100}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ script(type='text/ng-template', id='modals/send-gift.html')
|
|||||||
- var fromBal = "gift.type=='gems' && gift.gems.fromBalance"
|
- var fromBal = "gift.type=='gems' && gift.gems.fromBalance"
|
||||||
button.btn.btn-primary(ng-show=fromBal, ng-click='sendGift(profile._id)')=env.t("send")
|
button.btn.btn-primary(ng-show=fromBal, ng-click='sendGift(profile._id)')=env.t("send")
|
||||||
a.btn.btn-primary(ng-hide=fromBal, ng-click='Payments.showStripe({gift:gift, uuid:profile._id})')=env.t('card')
|
a.btn.btn-primary(ng-hide=fromBal, ng-click='Payments.showStripe({gift:gift, uuid:profile._id})')=env.t('card')
|
||||||
a.btn.btn-warning(ng-hide=fromBal, href='/paypal/checkout?_id={{::user._id}}&apiToken={{::User.settings.auth.apiToken}}&gift={{Payments.encodeGift(profile._id, gift)}}') PayPal
|
a.btn.btn-warning(ng-hide=fromBal, ng-click='Payments.payPalPayment({gift: gift, giftedTo: profile._id})') PayPal
|
||||||
.btn.btn-success(ng-hide=fromBal, ng-click="Payments.amazonPayments.init({type: 'single', gift: gift, giftedTo: profile._id})") Amazon Payments
|
.btn.btn-success(ng-hide=fromBal, ng-click="Payments.amazonPayments.init({type: 'single', gift: gift, giftedTo: profile._id})") Amazon Payments
|
||||||
button.btn.btn-default(ng-click='$close()')=env.t('cancel')
|
button.btn.btn-default(ng-click='$close()')=env.t('cancel')
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user