mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 14:47:53 +01:00
Ported open mystery item, added unit tests, added route, and integration tests
This commit is contained in:
@@ -128,5 +128,7 @@
|
|||||||
"privateMessageGiftSubscriptionMessage": "<%= numberOfMonths %> months of subscription! ",
|
"privateMessageGiftSubscriptionMessage": "<%= numberOfMonths %> months of subscription! ",
|
||||||
"cannotSendGemsToYourself": "Cannot send gems to yourself. Try a subscription instead.",
|
"cannotSendGemsToYourself": "Cannot send gems to yourself. Try a subscription instead.",
|
||||||
"notEnoughGemsToSend": "Amount must be within 0 and your current number of gems.",
|
"notEnoughGemsToSend": "Amount must be within 0 and your current number of gems.",
|
||||||
"mustPurchaseToSet": "Must purchase <%= val %> to set it on <%= key %>."
|
"mustPurchaseToSet": "Must purchase <%= val %> to set it on <%= key %>.",
|
||||||
|
"mysteryItemIsEmpty": "Mystery items are empty",
|
||||||
|
"mysteryItemOpened": "Mystery item opened."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ import feed from './ops/feed';
|
|||||||
import equip from './ops/equip';
|
import equip from './ops/equip';
|
||||||
import changeClass from './ops/changeClass';
|
import changeClass from './ops/changeClass';
|
||||||
import disableClasses from './ops/disableClasses';
|
import disableClasses from './ops/disableClasses';
|
||||||
|
import openMysteryItem from './ops/openMysteryItem';
|
||||||
|
|
||||||
api.ops = {
|
api.ops = {
|
||||||
scoreTask,
|
scoreTask,
|
||||||
@@ -129,6 +130,7 @@ api.ops = {
|
|||||||
equip,
|
equip,
|
||||||
changeClass,
|
changeClass,
|
||||||
disableClasses,
|
disableClasses,
|
||||||
|
openMysteryItem,
|
||||||
};
|
};
|
||||||
|
|
||||||
import handleTwoHanded from './fns/handleTwoHanded';
|
import handleTwoHanded from './fns/handleTwoHanded';
|
||||||
|
|||||||
@@ -1,32 +1,40 @@
|
|||||||
import content from '../content/index';
|
import content from '../content/index';
|
||||||
|
import i18n from '../i18n';
|
||||||
|
import {
|
||||||
|
BadRequest,
|
||||||
|
} from '../libs/errors';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
module.exports = function openMysteryItem (user, req = {}, analytics) {
|
||||||
|
let item = user.purchased.plan.mysteryItems.shift();
|
||||||
|
|
||||||
module.exports = function(user, req, cb, analytics) {
|
|
||||||
var analyticsData, item, ref, ref1;
|
|
||||||
item = (ref = user.purchased.plan) != null ? (ref1 = ref.mysteryItems) != null ? ref1.shift() : void 0 : void 0;
|
|
||||||
if (!item) {
|
if (!item) {
|
||||||
return typeof cb === "function" ? cb({
|
throw new BadRequest(i18n.t('mysteryItemIsEmpty', req.language));
|
||||||
code: 400,
|
|
||||||
message: "Empty"
|
|
||||||
}) : void 0;
|
|
||||||
}
|
|
||||||
item = content.gear.flat[item];
|
|
||||||
user.items.gear.owned[item.key] = true;
|
|
||||||
if (typeof user.markModified === "function") {
|
|
||||||
user.markModified('purchased.plan.mysteryItems');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item = _.cloneDeep(content.gear.flat[item]);
|
||||||
item.notificationType = 'Mystery';
|
item.notificationType = 'Mystery';
|
||||||
analyticsData = {
|
user.items.gear.owned[item.key] = true;
|
||||||
|
|
||||||
|
user.markModified('purchased.plan.mysteryItems');
|
||||||
|
|
||||||
|
if (analytics) {
|
||||||
|
analytics.track('open mystery item', {
|
||||||
uuid: user._id,
|
uuid: user._id,
|
||||||
itemKey: item,
|
itemKey: item,
|
||||||
itemType: 'Subscriber Gear',
|
itemType: 'Subscriber Gear',
|
||||||
acquireMethod: 'Subscriber',
|
acquireMethod: 'Subscriber',
|
||||||
category: 'behavior'
|
category: 'behavior',
|
||||||
};
|
});
|
||||||
if (analytics != null) {
|
|
||||||
analytics.track('open mystery item', analyticsData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== 'undefined') {
|
||||||
(user._tmp != null ? user._tmp : user._tmp = {}).drop = item;
|
if (!user._tmp) user._tmp = {};
|
||||||
|
user._tmp.drop = item;
|
||||||
}
|
}
|
||||||
return typeof cb === "function" ? cb(null, user.items.gear.owned) : void 0;
|
|
||||||
|
return {
|
||||||
|
message: i18n.t('mysteryItemOpened', req.language),
|
||||||
|
data: user.items.gear.owned,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ const COMMON_FILES = [
|
|||||||
'!./common/script/ops/getTag.js',
|
'!./common/script/ops/getTag.js',
|
||||||
'!./common/script/ops/getTags.js',
|
'!./common/script/ops/getTags.js',
|
||||||
'!./common/script/ops/hourglassPurchase.js',
|
'!./common/script/ops/hourglassPurchase.js',
|
||||||
'!./common/script/ops/openMysteryItem.js',
|
|
||||||
'!./common/script/ops/purchase.js',
|
'!./common/script/ops/purchase.js',
|
||||||
'!./common/script/ops/readCard.js',
|
'!./common/script/ops/readCard.js',
|
||||||
'!./common/script/ops/rebirth.js',
|
'!./common/script/ops/rebirth.js',
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import {
|
||||||
|
generateUser,
|
||||||
|
translate as t,
|
||||||
|
} from '../../../../helpers/api-integration/v3';
|
||||||
|
|
||||||
|
describe('POST /user/open-mystery-item', () => {
|
||||||
|
let user;
|
||||||
|
let mysteryItemKey = 'eyewear_special_summerRogue';
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
user = await generateUser({
|
||||||
|
'purchased.plan.mysteryItems': [mysteryItemKey],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// More tests in common code unit tests
|
||||||
|
|
||||||
|
it('opens a mystery item', async () => {
|
||||||
|
let response = await user.post(`/user/open-mystery-item`);
|
||||||
|
await user.sync();
|
||||||
|
|
||||||
|
expect(user.items.gear.owned[mysteryItemKey]).to.be.true;
|
||||||
|
expect(response.message).to.equal(t('mysteryItemOpened'));
|
||||||
|
expect(response.data).to.deep.equal(user.items.gear.owned);
|
||||||
|
});
|
||||||
|
});
|
||||||
38
test/common/ops/openMysteryItem.js
Normal file
38
test/common/ops/openMysteryItem.js
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import openMysteryItem from '../../../common/script/ops/openMysteryItem';
|
||||||
|
import {
|
||||||
|
generateUser,
|
||||||
|
} from '../../helpers/common.helper';
|
||||||
|
import {
|
||||||
|
BadRequest,
|
||||||
|
} from '../../../common/script/libs/errors';
|
||||||
|
import i18n from '../../../common/script/i18n';
|
||||||
|
|
||||||
|
describe('shared.ops.openMysteryItem', () => {
|
||||||
|
let user;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
user = generateUser();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns error when item key is empty', (done) => {
|
||||||
|
try {
|
||||||
|
openMysteryItem(user);
|
||||||
|
} catch (err) {
|
||||||
|
expect(err).to.be.an.instanceof(BadRequest);
|
||||||
|
expect(err.message).to.equal(i18n.t('mysteryItemIsEmpty'));
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('opens mystery item', () => {
|
||||||
|
let mysteryItemKey = 'eyewear_special_summerRogue';
|
||||||
|
|
||||||
|
user.purchased.plan.mysteryItems = [mysteryItemKey];
|
||||||
|
|
||||||
|
let response = openMysteryItem(user);
|
||||||
|
|
||||||
|
expect(user.items.gear.owned[mysteryItemKey]).to.be.true;
|
||||||
|
expect(response.message).to.equal(i18n.t('mysteryItemOpened'));
|
||||||
|
expect(response.data).to.equal(user.items.gear.owned);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -676,4 +676,24 @@ api.disableClasses = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {post} /user/open-mystery-item Open the mystery item.
|
||||||
|
* @apiVersion 3.0.0
|
||||||
|
* @apiName UserOpenMysteryItem
|
||||||
|
* @apiGroup User
|
||||||
|
*
|
||||||
|
* @apiSuccess {Object} data `user.items.gear.owned`
|
||||||
|
*/
|
||||||
|
api.userOpenMysteryItem = {
|
||||||
|
method: 'POST',
|
||||||
|
middlewares: [authWithHeaders(), cron],
|
||||||
|
url: '/user/open-mystery-item',
|
||||||
|
async handler (req, res) {
|
||||||
|
let user = res.locals.user;
|
||||||
|
let openMysteryItemResponse = common.ops.openMysteryItem(user, req, res.analytics);
|
||||||
|
await user.save();
|
||||||
|
res.respond(200, openMysteryItemResponse);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = api;
|
module.exports = api;
|
||||||
|
|||||||
Reference in New Issue
Block a user