Merge branch 'api-v3' into api-v3-unlock-fix
@@ -12,13 +12,13 @@ website/public/
|
|||||||
|
|
||||||
# Temporarilly disabled. These should be removed when the linting errors are fixed
|
# Temporarilly disabled. These should be removed when the linting errors are fixed
|
||||||
common/script/content/index.js
|
common/script/content/index.js
|
||||||
common/script/fns/randomDrop.js
|
|
||||||
common/script/public/**/*.js
|
common/script/public/**/*.js
|
||||||
|
|
||||||
website/src/**/api-v2/**/*.js
|
website/src/**/api-v2/**/*.js
|
||||||
website/src/routes/payments.js
|
website/src/routes/payments.js
|
||||||
website/src/routes/pages.js
|
website/src/routes/pages.js
|
||||||
website/src/middlewares/
|
website/src/middlewares/apiThrottle.js
|
||||||
|
website/src/middlewares/forceRefresh.js
|
||||||
website/src/controllers/payments/
|
website/src/controllers/payments/
|
||||||
|
|
||||||
debug-scripts/*
|
debug-scripts/*
|
||||||
|
|||||||
702
common/dist/sprites/spritesmith-main-10.css
vendored
BIN
common/dist/sprites/spritesmith-main-10.png
vendored
|
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 143 KiB |
798
common/dist/sprites/spritesmith-main-11.css
vendored
BIN
common/dist/sprites/spritesmith-main-11.png
vendored
|
Before Width: | Height: | Size: 154 KiB After Width: | Height: | Size: 155 KiB |
1156
common/dist/sprites/spritesmith-main-12.css
vendored
BIN
common/dist/sprites/spritesmith-main-12.png
vendored
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 68 KiB |
472
common/dist/sprites/spritesmith-main-7.css
vendored
BIN
common/dist/sprites/spritesmith-main-7.png
vendored
|
Before Width: | Height: | Size: 143 KiB After Width: | Height: | Size: 140 KiB |
436
common/dist/sprites/spritesmith-main-8.css
vendored
BIN
common/dist/sprites/spritesmith-main-8.png
vendored
|
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 145 KiB |
474
common/dist/sprites/spritesmith-main-9.css
vendored
BIN
common/dist/sprites/spritesmith-main-9.png
vendored
|
Before Width: | Height: | Size: 140 KiB After Width: | Height: | Size: 139 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
@@ -113,14 +113,13 @@
|
|||||||
"missingKeyParam": "\"req.params.key\" is required.",
|
"missingKeyParam": "\"req.params.key\" is required.",
|
||||||
"mysterySetNotFound": "Mystery set not found, or set already owned.",
|
"mysterySetNotFound": "Mystery set not found, or set already owned.",
|
||||||
"itemNotFound": "Item \"<%= key %>\" not found.",
|
"itemNotFound": "Item \"<%= key %>\" not found.",
|
||||||
"cannoyBuyItem": "You can't buy this item.",
|
"cannotBuyItem": "You can't buy this item.",
|
||||||
"missingTypeKeyEquip": "\"key\" and \"type\" are required parameters.",
|
"missingTypeKeyEquip": "\"key\" and \"type\" are required parameters.",
|
||||||
"missingPetFoodFeed": "\"pet\" and \"food\" are required parameters.",
|
"missingPetFoodFeed": "\"pet\" and \"food\" are required parameters.",
|
||||||
"invalidPetName": "Invalid pet name supplied.",
|
"invalidPetName": "Invalid pet name supplied.",
|
||||||
"missingEggHatchingPotionHatch": "\"egg\" and \"hatchingPotion\" are required parameters.",
|
"missingEggHatchingPotionHatch": "\"egg\" and \"hatchingPotion\" are required parameters.",
|
||||||
"invalidTypeEquip": "\"type\" must be one of 'equipped', 'pet', 'mount', 'costume'.",
|
"invalidTypeEquip": "\"type\" must be one of 'equipped', 'pet', 'mount', 'costume'.",
|
||||||
"cannotDeleteActiveAccount": "You have an active subscription, cancel your plan before deleting your account.",
|
"cannotDeleteActiveAccount": "You have an active subscription, cancel your plan before deleting your account.",
|
||||||
"cannoyBuyItem": "You can't buy this item",
|
|
||||||
"messageRequired": "A message is required.",
|
"messageRequired": "A message is required.",
|
||||||
"toUserIDRequired": "A toUserId is required",
|
"toUserIDRequired": "A toUserId is required",
|
||||||
"notAuthorizedToSendMessageToThisUser": "Can't send message to this user.",
|
"notAuthorizedToSendMessageToThisUser": "Can't send message to this user.",
|
||||||
@@ -171,5 +170,6 @@
|
|||||||
"pushDeviceAdded": "Push device added successfully",
|
"pushDeviceAdded": "Push device added successfully",
|
||||||
"pushDeviceAlreadyAdded": "The user already has the push device",
|
"pushDeviceAlreadyAdded": "The user already has the push device",
|
||||||
"resetComplete": "Reset completed",
|
"resetComplete": "Reset completed",
|
||||||
"lvl10ChangeClass": "To change class you must be at least level 10."
|
"lvl10ChangeClass": "To change class you must be at least level 10.",
|
||||||
|
"equipmentAlreadyOwned": "You already own that piece of equipment"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"communityGuidelinesWarning": "Please keep in mind that your Display Name, profile photo, and blurb must comply with the <a href='https://habitica.com/static/community-guidelines' target='_blank'>Community Guidelines</a> (e.g. no profanity, no adult topics, no insults, etc). If you have any questions about whether or not something is appropriate, feel free to email <a href='mailto:leslie@habitica.com' target='blank'>leslie@habitica.com</a>!",
|
||||||
"statsAch": "Stats & Achievements",
|
"statsAch": "Stats & Achievements",
|
||||||
"profile": "Profile",
|
"profile": "Profile",
|
||||||
"avatar": "Customize Avatar",
|
"avatar": "Customize Avatar",
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
"orca": "Orca",
|
"orca": "Orca",
|
||||||
"royalPurpleGryphon": "Royal Purple Gryphon",
|
"royalPurpleGryphon": "Royal Purple Gryphon",
|
||||||
"phoenix": "Phoenix",
|
"phoenix": "Phoenix",
|
||||||
"bumblebee": "Magical Bee",
|
"magicalBee": "Magical Bee",
|
||||||
"rarePetPop1": "Click the gold paw to learn more about how you can obtain this rare pet through contributing to Habitica!",
|
"rarePetPop1": "Click the gold paw to learn more about how you can obtain this rare pet through contributing to Habitica!",
|
||||||
"rarePetPop2": "How to Get this Pet!",
|
"rarePetPop2": "How to Get this Pet!",
|
||||||
"potion": "<%= potionType %> Potion",
|
"potion": "<%= potionType %> Potion",
|
||||||
|
|||||||
@@ -66,6 +66,14 @@
|
|||||||
"API": "API",
|
"API": "API",
|
||||||
"APIText": "Copy these for use in third party applications. However, think of your API Token like a password, and do not share it publicly. You may occasionally be asked for your User ID, but never post your API Token where others can see it, including on Github.",
|
"APIText": "Copy these for use in third party applications. However, think of your API Token like a password, and do not share it publicly. You may occasionally be asked for your User ID, but never post your API Token where others can see it, including on Github.",
|
||||||
"APIToken": "API Token (this is a password - see warning above!)",
|
"APIToken": "API Token (this is a password - see warning above!)",
|
||||||
|
"thirdPartyApps": "Third Party Apps",
|
||||||
|
"dataToolDesc": "A webpage that shows you certain information from your Habitica account, such as statistics about your tasks, equipment, and skills.",
|
||||||
|
"beeminder": "Beeminder",
|
||||||
|
"beeminderDesc": "Let Beeminder automatically monitor your Habitica To-Dos. You can commit to maintaining a target number of To-Dos completed per day or per week, or you can commit to gradually reducing your remaining number of uncompleted To-Dos. (By \"commit\" Beeminder means under threat of paying actual money! But you may also just like Beeminder's fancy graphs.)",
|
||||||
|
"chromeChatExtension": "Chrome Chat Extension",
|
||||||
|
"chromeChatExtensionDesc": "The Chrome Chat Extension for Habitica adds an intuitive chat box to all of habitica.com. It allows users to chat in the Tavern, their party, and any guilds they are in.",
|
||||||
|
"otherExtensions": "<a target='blank' href='http://habitica.wikia.com/wiki/App_and_Extension_Integrations'>Other Extensions</a>",
|
||||||
|
"otherDesc": "Find other apps, extensions, and tools on the Habitica wiki.",
|
||||||
"resetDo": "Do it, reset my account!",
|
"resetDo": "Do it, reset my account!",
|
||||||
"fixValues": "Fix Values",
|
"fixValues": "Fix Values",
|
||||||
"fixValuesText1": "If you've encountered a bug or made a mistake that unfairly changed your character (damage you shouldn't have taken, Gold you didn't really earn, etc.), you can manually correct your numbers here. Yes, this makes it possible to cheat: use this feature wisely, or you'll sabotage your own habit-building!",
|
"fixValuesText1": "If you've encountered a bug or made a mistake that unfairly changed your character (damage you shouldn't have taken, Gold you didn't really earn, etc.), you can manually correct your numbers here. Yes, this makes it possible to cheat: use this feature wisely, or you'll sabotage your own habit-building!",
|
||||||
|
|||||||
@@ -418,7 +418,7 @@ api.specialPets = {
|
|||||||
'Tiger-Veteran': 'veteranTiger',
|
'Tiger-Veteran': 'veteranTiger',
|
||||||
'Phoenix-Base': 'phoenix',
|
'Phoenix-Base': 'phoenix',
|
||||||
'Turkey-Gilded': 'gildedTurkey',
|
'Turkey-Gilded': 'gildedTurkey',
|
||||||
'Bumblebee-Base': 'bumblebee',
|
'MagicalBee-Base': 'magicalBee',
|
||||||
};
|
};
|
||||||
|
|
||||||
api.specialMounts = {
|
api.specialMounts = {
|
||||||
@@ -431,7 +431,7 @@ api.specialMounts = {
|
|||||||
'Gryphon-RoyalPurple': 'royalPurpleGryphon',
|
'Gryphon-RoyalPurple': 'royalPurpleGryphon',
|
||||||
'Phoenix-Base': 'phoenix',
|
'Phoenix-Base': 'phoenix',
|
||||||
'JackOLantern-Base': 'jackolantern',
|
'JackOLantern-Base': 'jackolantern',
|
||||||
'Bumblebee-Base': 'bumblebee',
|
'MagicalBee-Base': 'magicalBee',
|
||||||
};
|
};
|
||||||
|
|
||||||
api.timeTravelStable = {
|
api.timeTravelStable = {
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
|
import predictableRandom from './predictableRandom';
|
||||||
|
|
||||||
module.exports = function crit (user, stat = 'str', chance = 0.03) {
|
module.exports = function crit (user, stat = 'str', chance = 0.03) {
|
||||||
let s = user._statsComputed[stat];
|
let s = user._statsComputed[stat];
|
||||||
if (user.fns.predictableRandom() <= chance * (1 + s / 100)) {
|
if (predictableRandom(user) <= chance * (1 + s / 100)) {
|
||||||
return 1.5 + 4 * s / (s + 200);
|
return 1.5 + 4 * s / (s + 200);
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -3,80 +3,118 @@ import content from '../content/index';
|
|||||||
import i18n from '../i18n';
|
import i18n from '../i18n';
|
||||||
import { daysSince } from '../cron';
|
import { daysSince } from '../cron';
|
||||||
import { diminishingReturns } from '../statHelpers';
|
import { diminishingReturns } from '../statHelpers';
|
||||||
|
import { predictableRandom } from './predictableRandom';
|
||||||
|
import randomVal from './randomVal';
|
||||||
|
|
||||||
// Clone a drop object maintaining its functions so that we can change it without affecting the original item
|
// Clone a drop object maintaining its functions so that we can change it without affecting the original item
|
||||||
function cloneDropItem (drop) {
|
function cloneDropItem (drop) {
|
||||||
return _.cloneDeep(drop, function (val) {
|
return _.cloneDeep(drop, (val) => {
|
||||||
return _.isFunction(val) ? val : undefined; // undefined will be handled by lodash
|
return _.isFunction(val) ? val : undefined; // undefined will be handled by lodash
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = function randomDrop (user, modifiers, req) {
|
module.exports = function randomDrop (user, modifiers, req = {}) {
|
||||||
var acceptableDrops, base, base1, base2, chance, drop, dropK, dropMultiplier, name, name1, name2, quest, rarity, ref, ref1, ref2, ref3, task;
|
let acceptableDrops;
|
||||||
|
let chance;
|
||||||
|
let drop;
|
||||||
|
let dropK;
|
||||||
|
let dropMultiplier;
|
||||||
|
let quest;
|
||||||
|
let rarity;
|
||||||
|
let task;
|
||||||
|
|
||||||
task = modifiers.task;
|
task = modifiers.task;
|
||||||
chance = _.min([Math.abs(task.value - 21.27), 37.5]) / 150 + .02;
|
|
||||||
chance *= task.priority * (1 + (task.streak / 100 || 0)) * (1 + (user._statsComputed.per / 100)) * (1 + (user.contributor.level / 40 || 0)) * (1 + (user.achievements.rebirths / 20 || 0)) * (1 + (user.achievements.streak / 200 || 0)) * (user._tmp.crit || 1) * (1 + .5 * (_.reduce(task.checklist, (function(m, i) {
|
chance = _.min([Math.abs(task.value - 21.27), 37.5]) / 150 + 0.02;
|
||||||
return m + (i.completed ? 1 : 0);
|
chance *= task.priority * // Task priority: +50% for Medium, +100% for Hard
|
||||||
}), 0) || 0));
|
(1 + (task.streak / 100 || 0)) * // Streak bonus: +1% per streak
|
||||||
|
(1 + user._statsComputed.per / 100) * // PERception: +1% per point
|
||||||
|
(1 + (user.contributor.level / 40 || 0)) * // Contrib levels: +2.5% per level
|
||||||
|
(1 + (user.achievements.rebirths / 20 || 0)) * // Rebirths: +5% per achievement
|
||||||
|
(1 + (user.achievements.streak / 200 || 0)) * // Streak achievements: +0.5% per achievement
|
||||||
|
(user._tmp.crit || 1) * (1 + 0.5 * (_.reduce(task.checklist, (m, i) => {
|
||||||
|
return m + (i.completed ? 1 : 0); // +50% per checklist item complete. TODO: make this into X individual drop chances instead
|
||||||
|
}, 0) || 0));
|
||||||
chance = diminishingReturns(chance, 0.75);
|
chance = diminishingReturns(chance, 0.75);
|
||||||
quest = content.quests[(ref = user.party.quest) != null ? ref.key : void 0];
|
|
||||||
if ((quest != null ? quest.collect : void 0) && user.fns.predictableRandom(user.stats.gp) < chance) {
|
if (user.party.quest.key)
|
||||||
dropK = user.fns.randomVal(quest.collect, {
|
quest = content.quests[user.party.quest.key];
|
||||||
key: true
|
if (quest && quest.collect && predictableRandom(user, user.stats.gp) < chance) {
|
||||||
|
dropK = randomVal(user, quest.collect, {
|
||||||
|
key: true,
|
||||||
});
|
});
|
||||||
|
if (!user.party.quest.progress.collect[dropK])
|
||||||
|
user.party.quest.progress.collect[dropK] = 0;
|
||||||
user.party.quest.progress.collect[dropK]++;
|
user.party.quest.progress.collect[dropK]++;
|
||||||
if (typeof user.markModified === "function") {
|
|
||||||
user.markModified('party.quest.progress');
|
user.markModified('party.quest.progress');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (user.purchased && user.purchased.plan && user.purchased.plan.custsomerId) {
|
||||||
|
dropMultiplier = 2;
|
||||||
|
} else {
|
||||||
|
dropMultiplier = 1;
|
||||||
}
|
}
|
||||||
dropMultiplier = ((ref1 = user.purchased) != null ? (ref2 = ref1.plan) != null ? ref2.customerId : void 0 : void 0) ? 2 : 1;
|
|
||||||
if ((daysSince(user.items.lastDrop.date, user.preferences) === 0) && (user.items.lastDrop.count >= dropMultiplier * (5 + Math.floor(user._statsComputed.per / 25) + (user.contributor.level || 0)))) {
|
if (daysSince(user.items.lastDrop.date, user.preferences) === 0 &&
|
||||||
|
user.items.lastDrop.count >= dropMultiplier * (5 + Math.floor(user._statsComputed.per / 25) + (user.contributor.level || 0))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (((ref3 = user.flags) != null ? ref3.dropsEnabled : void 0) && user.fns.predictableRandom(user.stats.exp) < chance) {
|
|
||||||
rarity = user.fns.predictableRandom(user.stats.gp);
|
if (user.flags && user.flags.dropsEnabled && predictableRandom(user, user.stats.exp) < chance) {
|
||||||
if (rarity > .6) {
|
rarity = predictableRandom(user, user.stats.gp);
|
||||||
drop = cloneDropItem(user.fns.randomVal(_.where(content.food, {
|
|
||||||
canDrop: true
|
if (rarity > 0.6) { // food 40% chance
|
||||||
|
drop = cloneDropItem(randomVal(user, _.where(content.food, {
|
||||||
|
canDrop: true,
|
||||||
})));
|
})));
|
||||||
if ((base = user.items.food)[name = drop.key] == null) {
|
|
||||||
base[name] = 0;
|
if (!user.items.food[drop.key]) {
|
||||||
|
user.items.food[drop.key] = 0;
|
||||||
}
|
}
|
||||||
user.items.food[drop.key] += 1;
|
user.items.food[drop.key] += 1;
|
||||||
drop.type = 'Food';
|
drop.type = 'Food';
|
||||||
drop.dialog = i18n.t('messageDropFood', {
|
drop.dialog = i18n.t('messageDropFood', {
|
||||||
dropArticle: drop.article,
|
dropArticle: drop.article,
|
||||||
dropText: drop.text(req.language),
|
dropText: drop.text(req.language),
|
||||||
dropNotes: drop.notes(req.language)
|
dropNotes: drop.notes(req.language),
|
||||||
}, req.language);
|
}, req.language);
|
||||||
} else if (rarity > .3) {
|
} else if (rarity > 0.3) { // eggs 30% chance
|
||||||
drop = cloneDropItem(user.fns.randomVal(content.dropEggs));
|
drop = cloneDropItem(randomVal(user, content.dropEggs));
|
||||||
if ((base1 = user.items.eggs)[name1 = drop.key] == null) {
|
if (!user.items.eggs[drop.key]) {
|
||||||
base1[name1] = 0;
|
user.items.eggs[drop.key] = 0;
|
||||||
}
|
}
|
||||||
user.items.eggs[drop.key]++;
|
user.items.eggs[drop.key]++;
|
||||||
drop.type = 'Egg';
|
drop.type = 'Egg';
|
||||||
drop.dialog = i18n.t('messageDropEgg', {
|
drop.dialog = i18n.t('messageDropEgg', {
|
||||||
dropText: drop.text(req.language),
|
dropText: drop.text(req.language),
|
||||||
dropNotes: drop.notes(req.language)
|
dropNotes: drop.notes(req.language),
|
||||||
}, req.language);
|
}, req.language);
|
||||||
} else {
|
} else { // Hatching Potion, 30% chance - break down by rarity.
|
||||||
acceptableDrops = rarity < .02 ? ['Golden'] : rarity < .09 ? ['Zombie', 'CottonCandyPink', 'CottonCandyBlue'] : rarity < .18 ? ['Red', 'Shade', 'Skeleton'] : ['Base', 'White', 'Desert'];
|
if (rarity < 0.02) { // Very Rare: 10% (of 30%)
|
||||||
drop = cloneDropItem(user.fns.randomVal(_.pick(content.hatchingPotions, (function(v, k) {
|
acceptableDrops = ['Golden'];
|
||||||
|
} else if (rarity < 0.09) { // Rare: 20% of 30%
|
||||||
|
acceptableDrops = ['Zombie', 'CottonCandyPink', 'CottonCandyBlue'];
|
||||||
|
} else if (rarity < 0.18) { // uncommon: 30% of 30%
|
||||||
|
acceptableDrops = ['Red', 'Shade', 'Skeleton'];
|
||||||
|
} else { // common, 40% of 30%
|
||||||
|
acceptableDrops = ['Base', 'White', 'Desert'];
|
||||||
|
}
|
||||||
|
drop = cloneDropItem(randomVal(user, _.pick(content.hatchingPotions, (v, k) => {
|
||||||
return acceptableDrops.indexOf(k) >= 0;
|
return acceptableDrops.indexOf(k) >= 0;
|
||||||
}))));
|
})));
|
||||||
if ((base2 = user.items.hatchingPotions)[name2 = drop.key] == null) {
|
if (!user.items.hatchingPotions[drop.key]) {
|
||||||
base2[name2] = 0;
|
user.items.hatchingPotions[drop.key] = 0;
|
||||||
}
|
}
|
||||||
user.items.hatchingPotions[drop.key]++;
|
user.items.hatchingPotions[drop.key]++;
|
||||||
drop.type = 'HatchingPotion';
|
drop.type = 'HatchingPotion';
|
||||||
drop.dialog = i18n.t('messageDropPotion', {
|
drop.dialog = i18n.t('messageDropPotion', {
|
||||||
dropText: drop.text(req.language),
|
dropText: drop.text(req.language),
|
||||||
dropNotes: drop.notes(req.language)
|
dropNotes: drop.notes(req.language),
|
||||||
}, req.language);
|
}, req.language);
|
||||||
}
|
}
|
||||||
|
|
||||||
user._tmp.drop = drop;
|
user._tmp.drop = drop;
|
||||||
user.items.lastDrop.date = +(new Date);
|
user.items.lastDrop.date = Number(new Date());
|
||||||
return user.items.lastDrop.count++;
|
user.items.lastDrop.count++;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -85,12 +85,37 @@ import count from './count';
|
|||||||
api.count = count;
|
api.count = count;
|
||||||
|
|
||||||
import statsComputed from './libs/statsComputed';
|
import statsComputed from './libs/statsComputed';
|
||||||
|
api.statsComputed = statsComputed;
|
||||||
|
|
||||||
|
import autoAllocate from './fns/autoAllocate';
|
||||||
|
import crit from './fns/crit';
|
||||||
|
import handleTwoHanded from './fns/handleTwoHanded';
|
||||||
|
import predictableRandom from './fns/predictableRandom';
|
||||||
|
import randomDrop from './fns/randomDrop';
|
||||||
|
import randomVal from './fns/randomVal';
|
||||||
|
import resetGear from './fns/resetGear';
|
||||||
|
import ultimateGear from './fns/ultimateGear';
|
||||||
|
import updateStats from './fns/updateStats';
|
||||||
|
|
||||||
|
api.fns = {
|
||||||
|
autoAllocate,
|
||||||
|
crit,
|
||||||
|
handleTwoHanded,
|
||||||
|
predictableRandom,
|
||||||
|
randomDrop,
|
||||||
|
randomVal,
|
||||||
|
resetGear,
|
||||||
|
ultimateGear,
|
||||||
|
updateStats,
|
||||||
|
};
|
||||||
|
|
||||||
// TODO As ops and fns are ported, exported them through the api object
|
|
||||||
import scoreTask from './ops/scoreTask';
|
import scoreTask from './ops/scoreTask';
|
||||||
import sleep from './ops/sleep';
|
import sleep from './ops/sleep';
|
||||||
import allocate from './ops/allocate';
|
import allocate from './ops/allocate';
|
||||||
import buy from './ops/buy';
|
import buy from './ops/buy';
|
||||||
|
import buyGear from './ops/buyGear';
|
||||||
|
import buyPotion from './ops/buyPotion';
|
||||||
|
import buyArmoire from './ops/buyArmoire';
|
||||||
import buyMysterySet from './ops/buyMysterySet';
|
import buyMysterySet from './ops/buyMysterySet';
|
||||||
import buyQuest from './ops/buyQuest';
|
import buyQuest from './ops/buyQuest';
|
||||||
import buySpecialSpell from './ops/buySpecialSpell';
|
import buySpecialSpell from './ops/buySpecialSpell';
|
||||||
@@ -128,6 +153,9 @@ api.ops = {
|
|||||||
sleep,
|
sleep,
|
||||||
allocate,
|
allocate,
|
||||||
buy,
|
buy,
|
||||||
|
buyGear,
|
||||||
|
buyPotion,
|
||||||
|
buyArmoire,
|
||||||
buyMysterySet,
|
buyMysterySet,
|
||||||
buySpecialSpell,
|
buySpecialSpell,
|
||||||
buyQuest,
|
buyQuest,
|
||||||
@@ -161,28 +189,12 @@ api.ops = {
|
|||||||
reset,
|
reset,
|
||||||
};
|
};
|
||||||
|
|
||||||
import handleTwoHanded from './fns/handleTwoHanded';
|
|
||||||
import predictableRandom from './fns/predictableRandom';
|
|
||||||
import randomVal from './fns/randomVal';
|
|
||||||
import ultimateGear from './fns/ultimateGear';
|
|
||||||
import autoAllocate from './fns/autoAllocate';
|
|
||||||
|
|
||||||
api.fns = {
|
|
||||||
handleTwoHanded,
|
|
||||||
predictableRandom,
|
|
||||||
randomVal,
|
|
||||||
ultimateGear,
|
|
||||||
autoAllocate,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
------------------------------------------------------
|
------------------------------------------------------
|
||||||
User (prototype wrapper to give it ops, helper funcs, and virtuals
|
User (prototype wrapper to give it ops, helper funcs, and virtuals
|
||||||
------------------------------------------------------
|
------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
User is now wrapped (both on client and server), adding a few new properties:
|
User is now wrapped (both on client and server), adding a few new properties:
|
||||||
* getters (_statsComputed, tasks, etc)
|
* getters (_statsComputed, tasks, etc)
|
||||||
@@ -216,7 +228,7 @@ TODO
|
|||||||
import importedOps from './ops';
|
import importedOps from './ops';
|
||||||
import importedFns from './fns';
|
import importedFns from './fns';
|
||||||
|
|
||||||
// TODO redo
|
// TODO Kept for the client side
|
||||||
api.wrap = function wrapUser (user, main = true) {
|
api.wrap = function wrapUser (user, main = true) {
|
||||||
if (user._wrapped) return;
|
if (user._wrapped) return;
|
||||||
user._wrapped = true;
|
user._wrapped = true;
|
||||||
@@ -260,6 +272,9 @@ api.wrap = function wrapUser (user, main = true) {
|
|||||||
releaseMounts: _.partial(importedOps.releaseMounts, user),
|
releaseMounts: _.partial(importedOps.releaseMounts, user),
|
||||||
releaseBoth: _.partial(importedOps.releaseBoth, user),
|
releaseBoth: _.partial(importedOps.releaseBoth, user),
|
||||||
buy: _.partial(importedOps.buy, user),
|
buy: _.partial(importedOps.buy, user),
|
||||||
|
buyPotion: _.partial(importedOps.buyPotion, user),
|
||||||
|
buyArmoire: _.partial(importedOps.buyArmoire, user),
|
||||||
|
buyGear: _.partial(importedOps.buyGear, user),
|
||||||
buyQuest: _.partial(importedOps.buyQuest, user),
|
buyQuest: _.partial(importedOps.buyQuest, user),
|
||||||
buyMysterySet: _.partial(importedOps.buyMysterySet, user),
|
buyMysterySet: _.partial(importedOps.buyMysterySet, user),
|
||||||
hourglassPurchase: _.partial(importedOps.hourglassPurchase, user),
|
hourglassPurchase: _.partial(importedOps.hourglassPurchase, user),
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import i18n from '../i18n';
|
import i18n from '../i18n';
|
||||||
import splitWhitespace from '../libs/splitWhitespace';
|
|
||||||
import {
|
import {
|
||||||
BadRequest,
|
BadRequest,
|
||||||
NotAuthorized,
|
NotAuthorized,
|
||||||
} from '../libs/errors';
|
} from '../libs/errors';
|
||||||
|
|
||||||
|
// TODO move to server code
|
||||||
module.exports = function addPushDevice (user, req = {}) {
|
module.exports = function addPushDevice (user, req = {}) {
|
||||||
let regId = _.get(req, 'body.regId');
|
let regId = _.get(req, 'body.regId');
|
||||||
if (!regId) throw new BadRequest(i18n.t('regIdRequired', req.language));
|
if (!regId) throw new BadRequest(i18n.t('regIdRequired', req.language));
|
||||||
@@ -34,10 +34,8 @@ module.exports = function addPushDevice (user, req = {}) {
|
|||||||
|
|
||||||
pushDevices.push(item);
|
pushDevices.push(item);
|
||||||
|
|
||||||
let response = {
|
return [
|
||||||
data: _.pick(user, splitWhitespace('pushDevices')),
|
user.pushDevices,
|
||||||
message: i18n.t('pushDeviceAdded', req.language),
|
i18n.t('pushDeviceAdded', req.language),
|
||||||
};
|
];
|
||||||
|
|
||||||
return response;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ import {
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
module.exports = function addWebhook (user, req = {}) {
|
module.exports = function addWebhook (user, req = {}) {
|
||||||
let wh;
|
let wh = user.preferences.webhooks;
|
||||||
wh = user.preferences.webhooks;
|
|
||||||
|
|
||||||
if (!validator.isURL(_.get(req, 'body.url'))) throw new BadRequest(i18n.t('invalidUrl', req.language));
|
if (!validator.isURL(_.get(req, 'body.url'))) throw new BadRequest(i18n.t('invalidUrl', req.language));
|
||||||
if (!validator.isBoolean(_.get(req, 'body.enabled'))) throw new BadRequest(i18n.t('invalidEnabled', req.language));
|
if (!validator.isBoolean(_.get(req, 'body.enabled'))) throw new BadRequest(i18n.t('invalidEnabled', req.language));
|
||||||
@@ -18,9 +17,11 @@ module.exports = function addWebhook (user, req = {}) {
|
|||||||
if (req.v2 === true) {
|
if (req.v2 === true) {
|
||||||
return user.preferences.webhooks;
|
return user.preferences.webhooks;
|
||||||
} else {
|
} else {
|
||||||
return refPush(wh, {
|
return [
|
||||||
|
refPush(wh, {
|
||||||
url: req.body.url,
|
url: req.body.url,
|
||||||
enabled: req.body.enabled,
|
enabled: req.body.enabled,
|
||||||
});
|
}),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import splitWhitespace from '../libs/splitWhitespace';
|
|
||||||
import {
|
import {
|
||||||
ATTRIBUTES,
|
ATTRIBUTES,
|
||||||
} from '../constants';
|
} from '../constants';
|
||||||
@@ -26,5 +25,7 @@ module.exports = function allocate (user, req = {}) {
|
|||||||
throw new NotAuthorized(i18n.t('notEnoughAttrPoints', req.language));
|
throw new NotAuthorized(i18n.t('notEnoughAttrPoints', req.language));
|
||||||
}
|
}
|
||||||
|
|
||||||
return _.pick(user, splitWhitespace('stats'));
|
return [
|
||||||
|
user.stats,
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ module.exports = function allocateNow (user, req = {}) {
|
|||||||
if (req.v2 === true) {
|
if (req.v2 === true) {
|
||||||
return _.pick(user, 'stats');
|
return _.pick(user, 'stats');
|
||||||
} else {
|
} else {
|
||||||
return {
|
return [
|
||||||
data: _.pick(user, 'stats'),
|
user.stats,
|
||||||
};
|
];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,5 +15,7 @@ module.exports = function blockUser (user, req = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
user.markModified('inbox.blocks');
|
user.markModified('inbox.blocks');
|
||||||
return user.inbox.blocks;
|
return [
|
||||||
|
user.inbox.blocks,
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,142 +1,24 @@
|
|||||||
import content from '../content/index';
|
|
||||||
import i18n from '../i18n';
|
import i18n from '../i18n';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import count from '../count';
|
|
||||||
import splitWhitespace from '../libs/splitWhitespace';
|
|
||||||
import {
|
import {
|
||||||
BadRequest,
|
BadRequest,
|
||||||
NotAuthorized,
|
|
||||||
NotFound,
|
|
||||||
} from '../libs/errors';
|
} from '../libs/errors';
|
||||||
import predictableRandom from '../fns/predictableRandom';
|
import buyPotion from './buyPotion';
|
||||||
import randomVal from '../fns/randomVal';
|
import buyArmoire from './buyArmoire';
|
||||||
import handleTwoHanded from '../fns/handleTwoHanded';
|
import buyGear from './buyGear';
|
||||||
import ultimateGear from '../fns/ultimateGear';
|
|
||||||
|
|
||||||
module.exports = function buy (user, req = {}, analytics) {
|
module.exports = function buy (user, req = {}, analytics) {
|
||||||
let key = _.get(req, 'params.key');
|
let key = _.get(req, 'params.key');
|
||||||
if (!key) throw new BadRequest(i18n.t('missingKeyParam', req.language));
|
if (!key) throw new BadRequest(i18n.t('missingKeyParam', req.language));
|
||||||
|
|
||||||
let item;
|
let buyRes;
|
||||||
if (key === 'potion') {
|
if (key === 'potion') {
|
||||||
item = content.potion;
|
buyRes = buyPotion(user, req, analytics);
|
||||||
} else if (key === 'armoire') {
|
} else if (key === 'armoire') {
|
||||||
item = content.armoire;
|
buyRes = buyArmoire(user, req, analytics);
|
||||||
} else {
|
} else {
|
||||||
item = content.gear.flat[key];
|
buyRes = buyGear(user, req, analytics);
|
||||||
}
|
|
||||||
if (!item) throw new NotFound(i18n.t('itemNotFound', {key}, req.language));
|
|
||||||
|
|
||||||
if (user.stats.gp < item.value) {
|
|
||||||
throw new NotAuthorized(i18n.t('messageNotEnoughGold', req.language));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.canOwn && !item.canOwn(user)) {
|
return buyRes;
|
||||||
throw new NotAuthorized(i18n.t('cannoyBuyItem', req.language));
|
|
||||||
}
|
|
||||||
|
|
||||||
let armoireResp;
|
|
||||||
let armoireResult;
|
|
||||||
let eligibleEquipment;
|
|
||||||
let drop;
|
|
||||||
let message;
|
|
||||||
|
|
||||||
if (item.key === 'potion') {
|
|
||||||
user.stats.hp += 15;
|
|
||||||
if (user.stats.hp > 50) {
|
|
||||||
user.stats.hp = 50;
|
|
||||||
}
|
|
||||||
} else if (item.key === 'armoire') {
|
|
||||||
armoireResult = predictableRandom(user, user.stats.gp);
|
|
||||||
eligibleEquipment = _.filter(content.gear.flat, (eligible) => {
|
|
||||||
return eligible.klass === 'armoire' && !user.items.gear.owned[eligible.key];
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!_.isEmpty(eligibleEquipment) && (armoireResult < 0.6 || !user.flags.armoireOpened)) {
|
|
||||||
eligibleEquipment.sort();
|
|
||||||
drop = randomVal(user, eligibleEquipment);
|
|
||||||
|
|
||||||
user.items.gear.owned[drop.key] = true;
|
|
||||||
user.flags.armoireOpened = true;
|
|
||||||
message = i18n.t('armoireEquipment', {
|
|
||||||
image: `<span class="shop_${drop.key} pull-left"></span>`,
|
|
||||||
dropText: drop.text(req.language),
|
|
||||||
}, req.language);
|
|
||||||
|
|
||||||
if (count.remainingGearInSet(user.items.gear.owned, 'armoire') === 0) {
|
|
||||||
user.flags.armoireEmpty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
armoireResp = {
|
|
||||||
type: 'gear',
|
|
||||||
dropKey: drop.key,
|
|
||||||
dropText: drop.text(req.language),
|
|
||||||
};
|
|
||||||
} else if ((!_.isEmpty(eligibleEquipment) && armoireResult < 0.8) || armoireResult < 0.5) { // eslint-disable-line no-extra-parens
|
|
||||||
drop = randomVal(user, _.where(content.food, {
|
|
||||||
canDrop: true,
|
|
||||||
}));
|
|
||||||
user.items.food[drop.key] = user.items.food[drop.key] || 0;
|
|
||||||
user.items.food[drop.key] += 1;
|
|
||||||
|
|
||||||
message = i18n.t('armoireFood', {
|
|
||||||
image: `<span class="Pet_Food_${drop.key} pull-left"></span>`,
|
|
||||||
dropArticle: drop.article,
|
|
||||||
dropText: drop.text(req.language),
|
|
||||||
}, req.language);
|
|
||||||
armoireResp = {
|
|
||||||
type: 'food',
|
|
||||||
dropKey: drop.key,
|
|
||||||
dropArticle: drop.article,
|
|
||||||
dropText: drop.text(req.language),
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
let armoireExp = Math.floor(predictableRandom(user, user.stats.exp) * 40 + 10);
|
|
||||||
user.stats.exp += armoireExp;
|
|
||||||
message = i18n.t('armoireExp', req.language);
|
|
||||||
armoireResp = {
|
|
||||||
type: 'experience',
|
|
||||||
value: armoireExp,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (user.preferences.autoEquip) {
|
|
||||||
user.items.gear.equipped[item.type] = item.key;
|
|
||||||
message = handleTwoHanded(user, item, undefined, req);
|
|
||||||
}
|
|
||||||
user.items.gear.owned[item.key] = true;
|
|
||||||
|
|
||||||
if (item.last) ultimateGear(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
user.stats.gp -= item.value;
|
|
||||||
|
|
||||||
if (!message) {
|
|
||||||
message = i18n.t('messageBought', {
|
|
||||||
itemText: item.text(req.language),
|
|
||||||
}, req.language);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (analytics) {
|
|
||||||
analytics.track('acquire item', {
|
|
||||||
uuid: user._id,
|
|
||||||
itemKey: key,
|
|
||||||
acquireMethod: 'Gold',
|
|
||||||
goldCost: item.value,
|
|
||||||
category: 'behavior',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let res = {
|
|
||||||
data: _.pick(user, splitWhitespace('items achievements stats flags')),
|
|
||||||
message,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (armoireResp) res.armoire = armoireResp;
|
|
||||||
|
|
||||||
if (req.v2 === true) {
|
|
||||||
return res.data;
|
|
||||||
} else {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|||||||
115
common/script/ops/buyArmoire.js
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
import content from '../content/index';
|
||||||
|
import i18n from '../i18n';
|
||||||
|
import _ from 'lodash';
|
||||||
|
import count from '../count';
|
||||||
|
import splitWhitespace from '../libs/splitWhitespace';
|
||||||
|
import {
|
||||||
|
NotAuthorized,
|
||||||
|
} from '../libs/errors';
|
||||||
|
import predictableRandom from '../fns/predictableRandom';
|
||||||
|
import randomVal from '../fns/randomVal';
|
||||||
|
|
||||||
|
module.exports = function buyArmoire (user, req = {}, analytics) {
|
||||||
|
let item = content.armoire;
|
||||||
|
|
||||||
|
if (user.stats.gp < item.value) {
|
||||||
|
throw new NotAuthorized(i18n.t('messageNotEnoughGold', req.language));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.canOwn && !item.canOwn(user)) {
|
||||||
|
throw new NotAuthorized(i18n.t('cannotBuyItem', req.language));
|
||||||
|
}
|
||||||
|
|
||||||
|
let armoireResp;
|
||||||
|
let armoireResult;
|
||||||
|
let eligibleEquipment;
|
||||||
|
let drop;
|
||||||
|
let message;
|
||||||
|
|
||||||
|
armoireResult = predictableRandom(user, user.stats.gp);
|
||||||
|
eligibleEquipment = _.filter(content.gear.flat, (eligible) => {
|
||||||
|
return eligible.klass === 'armoire' && !user.items.gear.owned[eligible.key];
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!_.isEmpty(eligibleEquipment) && (armoireResult < 0.6 || !user.flags.armoireOpened)) {
|
||||||
|
eligibleEquipment.sort();
|
||||||
|
drop = randomVal(user, eligibleEquipment);
|
||||||
|
|
||||||
|
if (user.items.gear.owned[drop.key]) {
|
||||||
|
throw new NotAuthorized(i18n.t('equipmentAlradyOwned', req.language));
|
||||||
|
}
|
||||||
|
|
||||||
|
user.items.gear.owned[drop.key] = true;
|
||||||
|
user.flags.armoireOpened = true;
|
||||||
|
message = i18n.t('armoireEquipment', {
|
||||||
|
image: `<span class="shop_${drop.key} pull-left"></span>`,
|
||||||
|
dropText: drop.text(req.language),
|
||||||
|
}, req.language);
|
||||||
|
|
||||||
|
if (count.remainingGearInSet(user.items.gear.owned, 'armoire') === 0) {
|
||||||
|
user.flags.armoireEmpty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
armoireResp = {
|
||||||
|
type: 'gear',
|
||||||
|
dropKey: drop.key,
|
||||||
|
dropText: drop.text(req.language),
|
||||||
|
};
|
||||||
|
} else if ((!_.isEmpty(eligibleEquipment) && armoireResult < 0.8) || armoireResult < 0.5) { // eslint-disable-line no-extra-parens
|
||||||
|
drop = randomVal(user, _.where(content.food, {
|
||||||
|
canDrop: true,
|
||||||
|
}));
|
||||||
|
user.items.food[drop.key] = user.items.food[drop.key] || 0;
|
||||||
|
user.items.food[drop.key] += 1;
|
||||||
|
|
||||||
|
message = i18n.t('armoireFood', {
|
||||||
|
image: `<span class="Pet_Food_${drop.key} pull-left"></span>`,
|
||||||
|
dropArticle: drop.article,
|
||||||
|
dropText: drop.text(req.language),
|
||||||
|
}, req.language);
|
||||||
|
armoireResp = {
|
||||||
|
type: 'food',
|
||||||
|
dropKey: drop.key,
|
||||||
|
dropArticle: drop.article,
|
||||||
|
dropText: drop.text(req.language),
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
let armoireExp = Math.floor(predictableRandom(user, user.stats.exp) * 40 + 10);
|
||||||
|
user.stats.exp += armoireExp;
|
||||||
|
message = i18n.t('armoireExp', req.language);
|
||||||
|
armoireResp = {
|
||||||
|
type: 'experience',
|
||||||
|
value: armoireExp,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
user.stats.gp -= item.value;
|
||||||
|
|
||||||
|
if (!message) {
|
||||||
|
message = i18n.t('messageBought', {
|
||||||
|
itemText: item.text(req.language),
|
||||||
|
}, req.language);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (analytics) {
|
||||||
|
analytics.track('acquire item', {
|
||||||
|
uuid: user._id,
|
||||||
|
itemKey: 'Armoire',
|
||||||
|
acquireMethod: 'Gold',
|
||||||
|
goldCost: item.value,
|
||||||
|
category: 'behavior',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let resData = _.pick(user, splitWhitespace('items flags'));
|
||||||
|
if (armoireResp) resData.armoire = armoireResp;
|
||||||
|
|
||||||
|
if (req.v2 === true) {
|
||||||
|
return resData;
|
||||||
|
} else {
|
||||||
|
return [
|
||||||
|
resData,
|
||||||
|
message,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
};
|
||||||
70
common/script/ops/buyGear.js
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
import content from '../content/index';
|
||||||
|
import i18n from '../i18n';
|
||||||
|
import _ from 'lodash';
|
||||||
|
import splitWhitespace from '../libs/splitWhitespace';
|
||||||
|
import {
|
||||||
|
BadRequest,
|
||||||
|
NotAuthorized,
|
||||||
|
NotFound,
|
||||||
|
} from '../libs/errors';
|
||||||
|
import handleTwoHanded from '../fns/handleTwoHanded';
|
||||||
|
import ultimateGear from '../fns/ultimateGear';
|
||||||
|
|
||||||
|
module.exports = function buyGear (user, req = {}, analytics) {
|
||||||
|
let key = _.get(req, 'params.key');
|
||||||
|
if (!key) throw new BadRequest(i18n.t('missingKeyParam', req.language));
|
||||||
|
|
||||||
|
let item = content.gear.flat[key];
|
||||||
|
|
||||||
|
if (!item) throw new NotFound(i18n.t('itemNotFound', {key}, req.language));
|
||||||
|
|
||||||
|
if (user.stats.gp < item.value) {
|
||||||
|
throw new NotAuthorized(i18n.t('messageNotEnoughGold', req.language));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.canOwn && !item.canOwn(user)) {
|
||||||
|
throw new NotAuthorized(i18n.t('cannotBuyItem', req.language));
|
||||||
|
}
|
||||||
|
|
||||||
|
let message;
|
||||||
|
|
||||||
|
if (user.items.gear.owned[item.key]) {
|
||||||
|
throw new NotAuthorized(i18n.t('equipmentAlreadyOwned', req.language));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.preferences.autoEquip) {
|
||||||
|
user.items.gear.equipped[item.type] = item.key;
|
||||||
|
message = handleTwoHanded(user, item, undefined, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
user.items.gear.owned[item.key] = true;
|
||||||
|
|
||||||
|
if (item.last) ultimateGear(user);
|
||||||
|
|
||||||
|
user.stats.gp -= item.value;
|
||||||
|
|
||||||
|
if (!message) {
|
||||||
|
message = i18n.t('messageBought', {
|
||||||
|
itemText: item.text(req.language),
|
||||||
|
}, req.language);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (analytics) {
|
||||||
|
analytics.track('acquire item', {
|
||||||
|
uuid: user._id,
|
||||||
|
itemKey: key,
|
||||||
|
acquireMethod: 'Gold',
|
||||||
|
goldCost: item.value,
|
||||||
|
category: 'behavior',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.v2 === true) {
|
||||||
|
return _.pick(user, splitWhitespace('items achievements stats flags'));
|
||||||
|
} else {
|
||||||
|
return [
|
||||||
|
_.pick(user, splitWhitespace('items achievements stats flags')),
|
||||||
|
message,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -47,9 +47,9 @@ module.exports = function buyMysterySet (user, req = {}, analytics) {
|
|||||||
if (req.v2 === true) {
|
if (req.v2 === true) {
|
||||||
return pickDeep(user, splitWhitespace('items purchased.plan.consecutive'));
|
return pickDeep(user, splitWhitespace('items purchased.plan.consecutive'));
|
||||||
} else {
|
} else {
|
||||||
return {
|
return [
|
||||||
data: pickDeep(user, splitWhitespace('items purchased.plan.consecutive')),
|
{ items: user.items, purchasedPlanConsecutive: user.purchased.plan.consecutive },
|
||||||
message: i18n.t('hourglassPurchaseSet', req.language),
|
i18n.t('hourglassPurchaseSet', req.language),
|
||||||
};
|
];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
48
common/script/ops/buyPotion.js
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import content from '../content/index';
|
||||||
|
import i18n from '../i18n';
|
||||||
|
import {
|
||||||
|
NotAuthorized,
|
||||||
|
} from '../libs/errors';
|
||||||
|
|
||||||
|
module.exports = function buyPotion (user, req = {}, analytics) {
|
||||||
|
let item = content.potion;
|
||||||
|
|
||||||
|
if (user.stats.gp < item.value) {
|
||||||
|
throw new NotAuthorized(i18n.t('messageNotEnoughGold', req.language));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.canOwn && !item.canOwn(user)) {
|
||||||
|
throw new NotAuthorized(i18n.t('cannotBuyItem', req.language));
|
||||||
|
}
|
||||||
|
|
||||||
|
user.stats.hp += 15;
|
||||||
|
if (user.stats.hp > 50) {
|
||||||
|
user.stats.hp = 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
user.stats.gp -= item.value;
|
||||||
|
|
||||||
|
let message = i18n.t('messageBought', {
|
||||||
|
itemText: item.text(req.language),
|
||||||
|
}, req.language);
|
||||||
|
|
||||||
|
|
||||||
|
if (analytics) {
|
||||||
|
analytics.track('acquire item', {
|
||||||
|
uuid: user._id,
|
||||||
|
itemKey: 'Potion',
|
||||||
|
acquireMethod: 'Gold',
|
||||||
|
goldCost: item.value,
|
||||||
|
category: 'behavior',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.v2 === true) {
|
||||||
|
return user.stats;
|
||||||
|
} else {
|
||||||
|
return [
|
||||||
|
user.stats,
|
||||||
|
message,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -40,11 +40,11 @@ module.exports = function buyQuest (user, req = {}, analytics) {
|
|||||||
if (req.v2 === true) {
|
if (req.v2 === true) {
|
||||||
return user.items.quests;
|
return user.items.quests;
|
||||||
} else {
|
} else {
|
||||||
return {
|
return [
|
||||||
data: user.items.quests,
|
user.items.quests,
|
||||||
message: i18n.t('messageBought', {
|
i18n.t('messageBought', {
|
||||||
itemText: item.text(req.language),
|
itemText: item.text(req.language),
|
||||||
}, req.language),
|
}, req.language),
|
||||||
};
|
];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,11 +25,11 @@ module.exports = function buySpecialSpell (user, req = {}) {
|
|||||||
if (req.v2 === true) {
|
if (req.v2 === true) {
|
||||||
return _.pick(user, splitWhitespace('items stats'));
|
return _.pick(user, splitWhitespace('items stats'));
|
||||||
} else {
|
} else {
|
||||||
return {
|
return [
|
||||||
data: _.pick(user, splitWhitespace('items stats')),
|
_.pick(user, splitWhitespace('items stats')),
|
||||||
message: i18n.t('messageBought', {
|
i18n.t('messageBought', {
|
||||||
itemText: item.text(req.language),
|
itemText: item.text(req.language),
|
||||||
}, req.language),
|
}, req.language),
|
||||||
};
|
];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -71,8 +71,8 @@ module.exports = function changeClass (user, req = {}, analytics) {
|
|||||||
if (req.v2 === true) {
|
if (req.v2 === true) {
|
||||||
return _.pick(user, splitWhitespace('stats flags items preferences'));
|
return _.pick(user, splitWhitespace('stats flags items preferences'));
|
||||||
} else {
|
} else {
|
||||||
return {
|
return [
|
||||||
data: _.pick(user, splitWhitespace('stats flags items preferences')),
|
_.pick(user, splitWhitespace('stats flags items preferences')),
|
||||||
};
|
];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
module.exports = function clearPMs (user) {
|
module.exports = function clearPMs (user) {
|
||||||
user.inbox.messages = {};
|
user.inbox.messages = {};
|
||||||
user.markModified('inbox.messages');
|
user.markModified('inbox.messages');
|
||||||
return user.inbox.messages;
|
return [
|
||||||
|
user.inbox.messages,
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,5 +3,7 @@ import _ from 'lodash';
|
|||||||
module.exports = function deletePM (user, req = {}) {
|
module.exports = function deletePM (user, req = {}) {
|
||||||
delete user.inbox.messages[_.get(req, 'params.id')];
|
delete user.inbox.messages[_.get(req, 'params.id')];
|
||||||
user.markModified(`inbox.messages.${req.params.id}`);
|
user.markModified(`inbox.messages.${req.params.id}`);
|
||||||
return user.inbox.messages;
|
return [
|
||||||
|
user.inbox.messages,
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,5 +4,7 @@ module.exports = function deleteWebhook (user, req) {
|
|||||||
delete user.preferences.webhooks[_.get(req, 'params.id')];
|
delete user.preferences.webhooks[_.get(req, 'params.id')];
|
||||||
user.markModified('preferences.webhooks');
|
user.markModified('preferences.webhooks');
|
||||||
|
|
||||||
return user.preferences.webhooks;
|
return [
|
||||||
|
user.preferences.webhooks,
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ module.exports = function disableClasses (user, req = {}) {
|
|||||||
if (req.v2 === true) {
|
if (req.v2 === true) {
|
||||||
return _.pick(user, splitWhitespace('stats flags preferences'));
|
return _.pick(user, splitWhitespace('stats flags preferences'));
|
||||||
} else {
|
} else {
|
||||||
return {
|
return [
|
||||||
data: _.pick(user, splitWhitespace('stats flags preferences')),
|
_.pick(user, splitWhitespace('stats flags preferences')),
|
||||||
};
|
];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -58,14 +58,11 @@ module.exports = function equip (user, req = {}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let res = {
|
|
||||||
data: user.items,
|
|
||||||
};
|
|
||||||
if (message) res.message = message;
|
|
||||||
|
|
||||||
if (req.v2 === true) {
|
if (req.v2 === true) {
|
||||||
return user.items;
|
return user.items;
|
||||||
} else {
|
} else {
|
||||||
|
let res = [user.items];
|
||||||
|
if (message) res.push(message);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -94,9 +94,9 @@ module.exports = function feed (user, req = {}) {
|
|||||||
value: userPets[pet],
|
value: userPets[pet],
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return {
|
return [
|
||||||
data: userPets[pet],
|
userPets[pet],
|
||||||
message,
|
message,
|
||||||
};
|
];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -36,9 +36,9 @@ module.exports = function hatch (user, req = {}) {
|
|||||||
if (req.v2 === true) {
|
if (req.v2 === true) {
|
||||||
return user.items;
|
return user.items;
|
||||||
} else {
|
} else {
|
||||||
return {
|
return [
|
||||||
message: i18n.t('messageHatched', req.language),
|
user.items,
|
||||||
data: user.items,
|
i18n.t('messageHatched', req.language),
|
||||||
};
|
];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
import content from '../content/index';
|
import content from '../content/index';
|
||||||
import i18n from '../i18n';
|
import i18n from '../i18n';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import splitWhitespace from '../libs/splitWhitespace';
|
|
||||||
import pickDeep from '../libs/pickDeep';
|
|
||||||
import {
|
import {
|
||||||
BadRequest,
|
BadRequest,
|
||||||
NotAuthorized,
|
NotAuthorized,
|
||||||
} from '../libs/errors';
|
} from '../libs/errors';
|
||||||
|
import splitWhitespace from '../libs/splitWhitespace';
|
||||||
|
|
||||||
module.exports = function purchaseHourglass (user, req = {}, analytics) {
|
module.exports = function purchaseHourglass (user, req = {}, analytics) {
|
||||||
let key = _.get(req, 'params.key');
|
let key = _.get(req, 'params.key');
|
||||||
@@ -51,14 +50,12 @@ module.exports = function purchaseHourglass (user, req = {}, analytics) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let res = {
|
|
||||||
data: pickDeep(user, splitWhitespace('items purchased.plan.consecutive')),
|
|
||||||
message: i18n.t('hourglassPurchase', req.language),
|
|
||||||
};
|
|
||||||
|
|
||||||
if (req.v2 === true) {
|
if (req.v2 === true) {
|
||||||
return res.data;
|
return _.pick(user, splitWhitespace('items purchased.plan.consecutive'));
|
||||||
} else {
|
} else {
|
||||||
return res;
|
return [
|
||||||
|
{ items: user.items, purchasedPlanConsecutive: user.purchased.plan.consecutive },
|
||||||
|
i18n.t('hourglassPurchase', req.language),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ import releasePets from './releasePets';
|
|||||||
import releaseMounts from './releaseMounts';
|
import releaseMounts from './releaseMounts';
|
||||||
import releaseBoth from './releaseBoth';
|
import releaseBoth from './releaseBoth';
|
||||||
import buy from './buy';
|
import buy from './buy';
|
||||||
|
import buyGear from './buyGear';
|
||||||
|
import buyPotion from './buyPotion';
|
||||||
|
import buyArmoire from './buyArmoire';
|
||||||
import buyQuest from './buyQuest';
|
import buyQuest from './buyQuest';
|
||||||
import buyMysterySet from './buyMysterySet';
|
import buyMysterySet from './buyMysterySet';
|
||||||
import hourglassPurchase from './hourglassPurchase';
|
import hourglassPurchase from './hourglassPurchase';
|
||||||
@@ -77,6 +80,9 @@ module.exports = {
|
|||||||
releaseMounts,
|
releaseMounts,
|
||||||
releaseBoth,
|
releaseBoth,
|
||||||
buy,
|
buy,
|
||||||
|
buyGear,
|
||||||
|
buyPotion,
|
||||||
|
buyArmoire,
|
||||||
buyQuest,
|
buyQuest,
|
||||||
buyMysterySet,
|
buyMysterySet,
|
||||||
hourglassPurchase,
|
hourglassPurchase,
|
||||||
|
|||||||
@@ -36,9 +36,9 @@ module.exports = function openMysteryItem (user, req = {}, analytics) {
|
|||||||
if (req.v2 === true) {
|
if (req.v2 === true) {
|
||||||
return user.items.gear.owned;
|
return user.items.gear.owned;
|
||||||
} else {
|
} else {
|
||||||
return {
|
return [
|
||||||
message: i18n.t('mysteryItemOpened', req.language),
|
user.items.gear.owned,
|
||||||
data: user.items.gear.owned,
|
i18n.t('mysteryItemOpened', req.language),
|
||||||
};
|
];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -54,12 +54,10 @@ module.exports = function purchase (user, req = {}, analytics) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let response = {
|
return [
|
||||||
data: _.pick(user, splitWhitespace('stats balance')),
|
_.pick(user, splitWhitespace('stats balance')),
|
||||||
message: i18n.t('plusOneGem'),
|
i18n.t('plusOneGem'),
|
||||||
};
|
];
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let acceptedTypes = ['eggs', 'hatchingPotions', 'food', 'quests', 'gear'];
|
let acceptedTypes = ['eggs', 'hatchingPotions', 'food', 'quests', 'gear'];
|
||||||
@@ -119,14 +117,12 @@ module.exports = function purchase (user, req = {}, analytics) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let response = {
|
|
||||||
data: _.pick(user, splitWhitespace('items balance')),
|
|
||||||
message: i18n.t('purchased', {type, key}),
|
|
||||||
};
|
|
||||||
|
|
||||||
if (req.v2 === true) {
|
if (req.v2 === true) {
|
||||||
return response.data;
|
return _.pick(user, splitWhitespace('items balance'));
|
||||||
} else {
|
} else {
|
||||||
return response;
|
return [
|
||||||
|
_.pick(user, splitWhitespace('items balance')),
|
||||||
|
i18n.t('purchased', {type, key}),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,9 +24,9 @@ module.exports = function readCard (user, req = {}) {
|
|||||||
if (req.v2 === true) {
|
if (req.v2 === true) {
|
||||||
return _.pick(user, splitWhitespace('items.special flags.cardReceived'));
|
return _.pick(user, splitWhitespace('items.special flags.cardReceived'));
|
||||||
} else {
|
} else {
|
||||||
return {
|
return [
|
||||||
message: i18n.t('readCard', {cardType}, req.language),
|
{ specialItems: user.items.special, cardReceived: user.flags.cardReceived },
|
||||||
data: _.pick(user, splitWhitespace('items.special flags.cardReceived')),
|
i18n.t('readCard', {cardType}, req.language),
|
||||||
};
|
];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -98,14 +98,12 @@ module.exports = function rebirth (user, tasks = [], req = {}, analytics) {
|
|||||||
|
|
||||||
user.stats.buffs = {};
|
user.stats.buffs = {};
|
||||||
|
|
||||||
let response = {
|
|
||||||
data: user,
|
|
||||||
message: i18n.t('rebirthComplete'),
|
|
||||||
};
|
|
||||||
|
|
||||||
if (req.v2 === true) {
|
if (req.v2 === true) {
|
||||||
return user;
|
return user;
|
||||||
} else {
|
} else {
|
||||||
return response;
|
return [
|
||||||
|
{user, tasks},
|
||||||
|
i18n.t('rebirthComplete'),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -57,14 +57,12 @@ module.exports = function releaseBoth (user, req = {}, analytics) {
|
|||||||
user.achievements.triadBingoCount++;
|
user.achievements.triadBingoCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
let response = {
|
|
||||||
data: _.pick(user, splitWhitespace('achievements')),
|
|
||||||
message: i18n.t('mountsAndPetsReleased'),
|
|
||||||
};
|
|
||||||
|
|
||||||
if (req.v2 === true) {
|
if (req.v2 === true) {
|
||||||
return user;
|
return user;
|
||||||
} else {
|
} else {
|
||||||
return response;
|
return [
|
||||||
|
_.pick(user, splitWhitespace('achievements items balance')),
|
||||||
|
i18n.t('mountsAndPetsReleased'),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ import i18n from '../i18n';
|
|||||||
import {
|
import {
|
||||||
NotAuthorized,
|
NotAuthorized,
|
||||||
} from '../libs/errors';
|
} from '../libs/errors';
|
||||||
import splitWhitespace from '../libs/splitWhitespace';
|
|
||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
module.exports = function releaseMounts (user, req = {}, analytics) {
|
module.exports = function releaseMounts (user, req = {}, analytics) {
|
||||||
let mount;
|
let mount;
|
||||||
@@ -34,14 +32,12 @@ module.exports = function releaseMounts (user, req = {}, analytics) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let response = {
|
|
||||||
data: _.pick(user, splitWhitespace('mounts')),
|
|
||||||
message: i18n.t('mountsReleased'),
|
|
||||||
};
|
|
||||||
|
|
||||||
if (req.v2 === true) {
|
if (req.v2 === true) {
|
||||||
return user;
|
return user;
|
||||||
} else {
|
} else {
|
||||||
return response;
|
return [
|
||||||
|
user.items.mounts,
|
||||||
|
i18n.t('mountsReleased'),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ import i18n from '../i18n';
|
|||||||
import {
|
import {
|
||||||
NotAuthorized,
|
NotAuthorized,
|
||||||
} from '../libs/errors';
|
} from '../libs/errors';
|
||||||
import splitWhitespace from '../libs/splitWhitespace';
|
|
||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
module.exports = function releasePets (user, req = {}, analytics) {
|
module.exports = function releasePets (user, req = {}, analytics) {
|
||||||
if (user.balance < 1) {
|
if (user.balance < 1) {
|
||||||
@@ -32,14 +30,12 @@ module.exports = function releasePets (user, req = {}, analytics) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let response = {
|
|
||||||
data: _.pick(user, splitWhitespace('user.items.pets')),
|
|
||||||
message: i18n.t('petsReleased'),
|
|
||||||
};
|
|
||||||
|
|
||||||
if (req.v2 === true) {
|
if (req.v2 === true) {
|
||||||
return user;
|
return user;
|
||||||
} else {
|
} else {
|
||||||
return response;
|
return [
|
||||||
|
user.items.pets,
|
||||||
|
i18n.t('petsReleased'),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -27,14 +27,12 @@ module.exports = function reroll (user, tasks = [], req = {}, analytics) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let response = {
|
|
||||||
data: {user, tasks},
|
|
||||||
message: i18n.t('rerollComplete'),
|
|
||||||
};
|
|
||||||
|
|
||||||
if (req.v2 === true) {
|
if (req.v2 === true) {
|
||||||
return user;
|
return user;
|
||||||
} else {
|
} else {
|
||||||
return response;
|
return [
|
||||||
|
{user, tasks},
|
||||||
|
i18n.t('rerollComplete'),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,14 +19,12 @@ module.exports = function reset (user, tasks = [], req = {}) {
|
|||||||
|
|
||||||
resetGear(user);
|
resetGear(user);
|
||||||
|
|
||||||
let response = {
|
|
||||||
data: {user, tasksToRemove},
|
|
||||||
message: i18n.t('resetComplete'),
|
|
||||||
};
|
|
||||||
|
|
||||||
if (req.v2 === true) {
|
if (req.v2 === true) {
|
||||||
return user;
|
return user;
|
||||||
} else {
|
} else {
|
||||||
return response;
|
return [
|
||||||
|
{user, tasksToRemove},
|
||||||
|
i18n.t('resetComplete'),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import _ from 'lodash';
|
|||||||
import {
|
import {
|
||||||
NotAuthorized,
|
NotAuthorized,
|
||||||
} from '../libs/errors';
|
} from '../libs/errors';
|
||||||
import splitWhitespace from '../libs/splitWhitespace';
|
|
||||||
import randomVal from '../fns/randomVal';
|
import randomVal from '../fns/randomVal';
|
||||||
|
|
||||||
module.exports = function revive (user, req = {}, analytics) {
|
module.exports = function revive (user, req = {}, analytics) {
|
||||||
@@ -97,14 +96,12 @@ module.exports = function revive (user, req = {}, analytics) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let response = {
|
|
||||||
data: _.pick(user, splitWhitespace('user.items')),
|
|
||||||
message,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (req.v2 === true) {
|
if (req.v2 === true) {
|
||||||
return user;
|
return user;
|
||||||
} else {
|
} else {
|
||||||
return response;
|
return [
|
||||||
|
user.items,
|
||||||
|
message,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
} from '../libs/errors';
|
} from '../libs/errors';
|
||||||
import i18n from '../i18n';
|
import i18n from '../i18n';
|
||||||
import updateStats from '../fns/updateStats';
|
import updateStats from '../fns/updateStats';
|
||||||
|
import crit from '../fns/crit';
|
||||||
|
|
||||||
const MAX_TASK_VALUE = 21.27;
|
const MAX_TASK_VALUE = 21.27;
|
||||||
const MIN_TASK_VALUE = -47.27;
|
const MIN_TASK_VALUE = -47.27;
|
||||||
@@ -105,7 +106,7 @@ function _subtractPoints (user, task, stats, delta) {
|
|||||||
function _addPoints (user, task, stats, direction, delta) {
|
function _addPoints (user, task, stats, direction, delta) {
|
||||||
// ===== CRITICAL HITS =====
|
// ===== CRITICAL HITS =====
|
||||||
// allow critical hit only when checking off a task, not when unchecking it:
|
// allow critical hit only when checking off a task, not when unchecking it:
|
||||||
let _crit = delta > 0 ? user.fns.crit() : 1;
|
let _crit = delta > 0 ? crit(user) : 1;
|
||||||
// if there was a crit, alert the user via notification
|
// if there was a crit, alert the user via notification
|
||||||
if (_crit > 1) user._tmp.crit = _crit;
|
if (_crit > 1) user._tmp.crit = _crit;
|
||||||
|
|
||||||
@@ -256,5 +257,5 @@ module.exports = function scoreTask (options = {}, req = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateStats(user, stats, req);
|
updateStats(user, stats, req);
|
||||||
return delta;
|
return [delta];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -33,14 +33,12 @@ module.exports = function sell (user, req = {}) {
|
|||||||
user.items[type][key]--;
|
user.items[type][key]--;
|
||||||
user.stats.gp += content[type][key].value;
|
user.stats.gp += content[type][key].value;
|
||||||
|
|
||||||
let response = {
|
|
||||||
data: _.pick(user, splitWhitespace('stats items')),
|
|
||||||
message: i18n.t('sold', {type, key}),
|
|
||||||
};
|
|
||||||
|
|
||||||
if (req.v2 === true) {
|
if (req.v2 === true) {
|
||||||
return response.data;
|
return _.pick(user, splitWhitespace('stats items'));
|
||||||
} else {
|
} else {
|
||||||
return response;
|
return [
|
||||||
|
_.pick(user, splitWhitespace('stats items')),
|
||||||
|
i18n.t('sold', {type, key}),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,10 +4,6 @@ module.exports = function sleep (user, req = {}) {
|
|||||||
if (req.v2 === true) {
|
if (req.v2 === true) {
|
||||||
return {};
|
return {};
|
||||||
} else {
|
} else {
|
||||||
return {
|
return [user.preferences.sleep];
|
||||||
preferences: {
|
|
||||||
sleep: user.preferences.sleep,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ module.exports = function unlock (user, req = {}, analytics) {
|
|||||||
_.set(user, `purchased.${pathPart}`, true);
|
_.set(user, `purchased.${pathPart}`, true);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (alreadyOwns) {
|
if (alreadyOwns) { // eslint-disable-line no-lonely-if
|
||||||
let split = path.split('.');
|
let split = path.split('.');
|
||||||
let value = split.pop();
|
let value = split.pop();
|
||||||
let key = split.join('.');
|
let key = split.join('.');
|
||||||
@@ -97,14 +97,14 @@ module.exports = function unlock (user, req = {}, analytics) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let response = {
|
let response = [
|
||||||
data: _.pick(user, splitWhitespace('purchased preferences items')),
|
_.pick(user, splitWhitespace('purchased preferences items')),
|
||||||
};
|
];
|
||||||
|
|
||||||
if (!alreadyOwns) response.message = i18n.t('unlocked', req.language);
|
if (!alreadyOwns) response.push(i18n.t('unlocked', req.language));
|
||||||
|
|
||||||
if (req.v2 === true) {
|
if (req.v2 === true) {
|
||||||
return response.data;
|
return response[0];
|
||||||
} else {
|
} else {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,5 +22,5 @@ module.exports = function updateTask (task, req = {}) {
|
|||||||
|
|
||||||
_.merge(task, _.omit(req.body, ['_id', 'id', 'type']));
|
_.merge(task, _.omit(req.body, ['_id', 'id', 'type']));
|
||||||
|
|
||||||
return task;
|
return [task];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,6 +15,6 @@ module.exports = function updateWebhook (user, req) {
|
|||||||
if (req.v2 === true) {
|
if (req.v2 === true) {
|
||||||
return user.preferences.webhooks;
|
return user.preferences.webhooks;
|
||||||
} else {
|
} else {
|
||||||
return user.preferences.webhooks[req.params.id];
|
return [user.preferences.webhooks[req.params.id]];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
|
|
||||||
describe('GET /meta/models/:model/paths', () => {
|
describe('GET /models/:model/paths', () => {
|
||||||
let user;
|
let user;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
@@ -11,7 +11,7 @@ describe('GET /meta/models/:model/paths', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns an error when model is not accessible or doesn\'t exists', async () => {
|
it('returns an error when model is not accessible or doesn\'t exists', async () => {
|
||||||
await expect(user.get('/meta/models/1234/paths')).to.eventually.be.rejected.and.eql({
|
await expect(user.get('/models/1234/paths')).to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
message: t('invalidReqParams'),
|
message: t('invalidReqParams'),
|
||||||
@@ -21,7 +21,7 @@ describe('GET /meta/models/:model/paths', () => {
|
|||||||
let models = ['habit', 'daily', 'todo', 'reward', 'user', 'tag', 'challenge', 'group'];
|
let models = ['habit', 'daily', 'todo', 'reward', 'user', 'tag', 'challenge', 'group'];
|
||||||
models.forEach(model => {
|
models.forEach(model => {
|
||||||
it(`returns the model paths for ${model}`, async () => {
|
it(`returns the model paths for ${model}`, async () => {
|
||||||
let res = await user.get(`/meta/models/${model}/paths`);
|
let res = await user.get(`/models/${model}/paths`);
|
||||||
|
|
||||||
expect(res._id).to.equal('String');
|
expect(res._id).to.equal('String');
|
||||||
expect(res).to.not.have.keys('__v');
|
expect(res).to.not.have.keys('__v');
|
||||||
@@ -36,6 +36,6 @@ describe('POST /user/allocate', () => {
|
|||||||
await user.sync();
|
await user.sync();
|
||||||
expect(user.stats.con).to.equal(1);
|
expect(user.stats.con).to.equal(1);
|
||||||
expect(user.stats.points).to.equal(0);
|
expect(user.stats.points).to.equal(0);
|
||||||
expect(res.stats.con).to.equal(1);
|
expect(res.con).to.equal(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -18,11 +18,7 @@ describe('POST /user/allocate-now', () => {
|
|||||||
let res = await user.post('/user/allocate-now');
|
let res = await user.post('/user/allocate-now');
|
||||||
await user.sync();
|
await user.sync();
|
||||||
|
|
||||||
expect(res).to.eql({
|
expect(res).to.eql(user.stats);
|
||||||
data: {
|
|
||||||
stats: user.stats,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(user.stats.points).to.equal(0);
|
expect(user.stats.points).to.equal(0);
|
||||||
expect(user.stats.con).to.equal(9);
|
expect(user.stats.con).to.equal(9);
|
||||||
expect(user.stats.int).to.equal(8);
|
expect(user.stats.int).to.equal(8);
|
||||||
|
|||||||
@@ -26,17 +26,26 @@ describe('POST /user/buy/:key', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('buys an item', async () => {
|
it('buys a potion', async () => {
|
||||||
|
await user.update({
|
||||||
|
'stats.gp': 400,
|
||||||
|
});
|
||||||
|
|
||||||
let potion = content.potion;
|
let potion = content.potion;
|
||||||
let res = await user.post('/user/buy/potion');
|
let res = await user.post('/user/buy/potion');
|
||||||
await user.sync();
|
await user.sync();
|
||||||
|
|
||||||
expect(res.data).to.eql({
|
expect(user.stats.hp).to.equal(50);
|
||||||
items: JSON.parse(JSON.stringify(user.items)), // otherwise dates can't be compared
|
expect(res.data).to.eql(user.stats);
|
||||||
achievements: user.achievements,
|
|
||||||
stats: user.stats,
|
|
||||||
flags: JSON.parse(JSON.stringify(user.flags)), // otherwise dates can't be compared
|
|
||||||
});
|
|
||||||
expect(res.message).to.equal(t('messageBought', {itemText: potion.text()}));
|
expect(res.message).to.equal(t('messageBought', {itemText: potion.text()}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('buys a piece of gear', async () => {
|
||||||
|
let key = 'armor_warrior_1';
|
||||||
|
|
||||||
|
await user.post(`/user/buy/${key}`);
|
||||||
|
await user.sync();
|
||||||
|
|
||||||
|
expect(user.items.gear.owned).to.eql({ armor_warrior_1: true }); // eslint-disable-line camelcase
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
44
test/api/v3/integration/user/POST-user_buy_armoire.test.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import {
|
||||||
|
generateUser,
|
||||||
|
translate as t,
|
||||||
|
} from '../../../../helpers/api-integration/v3';
|
||||||
|
import shared from '../../../../../common/script';
|
||||||
|
|
||||||
|
let content = shared.content;
|
||||||
|
|
||||||
|
describe('POST /user/buy-armoire', () => {
|
||||||
|
let user;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
user = await generateUser({
|
||||||
|
'stats.hp': 40,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// More tests in common code unit tests
|
||||||
|
|
||||||
|
it('returns an error if user does not have enough gold', async () => {
|
||||||
|
await expect(user.post('/user/buy-potion'))
|
||||||
|
.to.eventually.be.rejected.and.eql({
|
||||||
|
code: 401,
|
||||||
|
error: 'NotAuthorized',
|
||||||
|
message: t('messageNotEnoughGold'),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
xit('buys a piece of armoire', async () => {
|
||||||
|
await user.update({
|
||||||
|
'stats.gp': 400,
|
||||||
|
});
|
||||||
|
|
||||||
|
let potion = content.potion;
|
||||||
|
let res = await user.post('/user/buy-potion');
|
||||||
|
await user.sync();
|
||||||
|
|
||||||
|
expect(user.stats.hp).to.equal(50);
|
||||||
|
expect(res.data).to.eql({
|
||||||
|
stats: user.stats,
|
||||||
|
});
|
||||||
|
expect(res.message).to.equal(t('messageBought', {itemText: potion.text()}));
|
||||||
|
});
|
||||||
|
});
|
||||||
34
test/api/v3/integration/user/POST-user_buy_gear.test.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import {
|
||||||
|
generateUser,
|
||||||
|
translate as t,
|
||||||
|
} from '../../../../helpers/api-integration/v3';
|
||||||
|
|
||||||
|
describe('POST /user/buy-gear/:key', () => {
|
||||||
|
let user;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
user = await generateUser({
|
||||||
|
'stats.gp': 400,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// More tests in common code unit tests
|
||||||
|
|
||||||
|
it('returns an error if the item is not found', async () => {
|
||||||
|
await expect(user.post('/user/buy-gear/notExisting'))
|
||||||
|
.to.eventually.be.rejected.and.eql({
|
||||||
|
code: 404,
|
||||||
|
error: 'NotFound',
|
||||||
|
message: t('itemNotFound', {key: 'notExisting'}),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('buys a piece of gear', async () => {
|
||||||
|
let key = 'armor_warrior_1';
|
||||||
|
|
||||||
|
await user.post(`/user/buy-gear/${key}`);
|
||||||
|
await user.sync();
|
||||||
|
|
||||||
|
expect(user.items.gear.owned).to.eql({ armor_warrior_1: true }); // eslint-disable-line camelcase
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -31,11 +31,7 @@ describe('POST /user/buy-mystery-set/:key', () => {
|
|||||||
|
|
||||||
expect(res.data).to.eql({
|
expect(res.data).to.eql({
|
||||||
items: JSON.parse(JSON.stringify(user.items)), // otherwise dates can't be compared
|
items: JSON.parse(JSON.stringify(user.items)), // otherwise dates can't be compared
|
||||||
purchased: {
|
purchasedPlanConsecutive: user.purchased.plan.consecutive,
|
||||||
plan: {
|
|
||||||
consecutive: user.purchased.plan.consecutive,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
expect(res.message).to.equal(t('hourglassPurchaseSet'));
|
expect(res.message).to.equal(t('hourglassPurchaseSet'));
|
||||||
});
|
});
|
||||||
|
|||||||
42
test/api/v3/integration/user/POST-user_buy_potion.test.js
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import {
|
||||||
|
generateUser,
|
||||||
|
translate as t,
|
||||||
|
} from '../../../../helpers/api-integration/v3';
|
||||||
|
import shared from '../../../../../common/script';
|
||||||
|
|
||||||
|
let content = shared.content;
|
||||||
|
|
||||||
|
describe('POST /user/buy-potion', () => {
|
||||||
|
let user;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
user = await generateUser({
|
||||||
|
'stats.hp': 40,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// More tests in common code unit tests
|
||||||
|
|
||||||
|
it('returns an error if user does not have enough gold', async () => {
|
||||||
|
await expect(user.post('/user/buy-potion'))
|
||||||
|
.to.eventually.be.rejected.and.eql({
|
||||||
|
code: 401,
|
||||||
|
error: 'NotAuthorized',
|
||||||
|
message: t('messageNotEnoughGold'),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('buys a potion', async () => {
|
||||||
|
await user.update({
|
||||||
|
'stats.gp': 400,
|
||||||
|
});
|
||||||
|
|
||||||
|
let potion = content.potion;
|
||||||
|
let res = await user.post('/user/buy-potion');
|
||||||
|
await user.sync();
|
||||||
|
|
||||||
|
expect(user.stats.hp).to.equal(50);
|
||||||
|
expect(res.data).to.eql(user.stats);
|
||||||
|
expect(res.message).to.equal(t('messageBought', {itemText: potion.text()}));
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -18,13 +18,13 @@ describe('POST /user/change-class', () => {
|
|||||||
let res = await user.post('/user/change-class?class=rogue');
|
let res = await user.post('/user/change-class?class=rogue');
|
||||||
await user.sync();
|
await user.sync();
|
||||||
|
|
||||||
expect(res).to.eql({
|
expect(res).to.eql(JSON.parse(
|
||||||
data: JSON.parse(JSON.stringify({
|
JSON.stringify({
|
||||||
preferences: user.preferences,
|
preferences: user.preferences,
|
||||||
stats: user.stats,
|
stats: user.stats,
|
||||||
flags: user.flags,
|
flags: user.flags,
|
||||||
items: user.items,
|
items: user.items,
|
||||||
})),
|
})
|
||||||
});
|
));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ describe('POST /user/disable-classes', () => {
|
|||||||
let res = await user.post('/user/disable-classes');
|
let res = await user.post('/user/disable-classes');
|
||||||
await user.sync();
|
await user.sync();
|
||||||
|
|
||||||
expect(res).to.eql({
|
expect(res).to.eql(JSON.parse(
|
||||||
data: JSON.parse(JSON.stringify({
|
JSON.stringify({
|
||||||
preferences: user.preferences,
|
preferences: user.preferences,
|
||||||
stats: user.stats,
|
stats: user.stats,
|
||||||
flags: user.flags,
|
flags: user.flags,
|
||||||
})),
|
})
|
||||||
});
|
));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -35,8 +35,6 @@ describe('POST /user/equip/:type/:key', () => {
|
|||||||
let res = await user.post('/user/equip/equipped/weapon_warrior_2');
|
let res = await user.post('/user/equip/equipped/weapon_warrior_2');
|
||||||
await user.sync();
|
await user.sync();
|
||||||
|
|
||||||
expect(res).to.eql({
|
expect(res).to.eql(JSON.parse(JSON.stringify(user.items)));
|
||||||
data: JSON.parse(JSON.stringify(user.items)),
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -13,16 +13,12 @@ describe('POST /user/sleep', () => {
|
|||||||
|
|
||||||
it('toggles sleep status', async () => {
|
it('toggles sleep status', async () => {
|
||||||
let res = await user.post('/user/sleep');
|
let res = await user.post('/user/sleep');
|
||||||
expect(res).to.eql({
|
expect(res).to.eql(true);
|
||||||
preferences: {sleep: true},
|
|
||||||
});
|
|
||||||
await user.sync();
|
await user.sync();
|
||||||
expect(user.preferences.sleep).to.be.true;
|
expect(user.preferences.sleep).to.be.true;
|
||||||
|
|
||||||
let res2 = await user.post('/user/sleep');
|
let res2 = await user.post('/user/sleep');
|
||||||
expect(res2).to.eql({
|
expect(res2).to.eql(false);
|
||||||
preferences: {sleep: false},
|
|
||||||
});
|
|
||||||
await user.sync();
|
await user.sync();
|
||||||
expect(user.preferences.sleep).to.be.false;
|
expect(user.preferences.sleep).to.be.false;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ describe('POST /user/reset-password', async () => {
|
|||||||
let response = await user.post(endpoint, {
|
let response = await user.post(endpoint, {
|
||||||
email: user.auth.local.email,
|
email: user.auth.local.email,
|
||||||
});
|
});
|
||||||
expect(response).to.eql({ message: t('passwordReset') });
|
expect(response).to.eql({ data: {}, message: t('passwordReset') });
|
||||||
await user.sync();
|
await user.sync();
|
||||||
expect(user.auth.local.hashed_password).to.not.eql(previousPassword);
|
expect(user.auth.local.hashed_password).to.not.eql(previousPassword);
|
||||||
});
|
});
|
||||||
@@ -25,7 +25,7 @@ describe('POST /user/reset-password', async () => {
|
|||||||
let response = await user.post(endpoint, {
|
let response = await user.post(endpoint, {
|
||||||
email: 'nonExistent@email.com',
|
email: 'nonExistent@email.com',
|
||||||
});
|
});
|
||||||
expect(response).to.eql({ message: t('passwordReset') });
|
expect(response).to.eql({ data: {}, message: t('passwordReset') });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('errors if email is not provided', async () => {
|
it('errors if email is not provided', async () => {
|
||||||
@@ -36,4 +36,3 @@ describe('POST /user/reset-password', async () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ describe('errorHandler', () => {
|
|||||||
|
|
||||||
expect(res.status).to.be.calledWith(500);
|
expect(res.status).to.be.calledWith(500);
|
||||||
expect(res.json).to.be.calledWith({
|
expect(res.json).to.be.calledWith({
|
||||||
|
success: false,
|
||||||
error: 'InternalServerError',
|
error: 'InternalServerError',
|
||||||
message: 'An unexpected error occurred.',
|
message: 'An unexpected error occurred.',
|
||||||
});
|
});
|
||||||
@@ -54,6 +55,7 @@ describe('errorHandler', () => {
|
|||||||
|
|
||||||
expect(res.status).to.be.calledWith(400);
|
expect(res.status).to.be.calledWith(400);
|
||||||
expect(res.json).to.be.calledWith({
|
expect(res.json).to.be.calledWith({
|
||||||
|
success: false,
|
||||||
error: 'Error',
|
error: 'Error',
|
||||||
message: 'Error message',
|
message: 'Error message',
|
||||||
});
|
});
|
||||||
@@ -70,6 +72,7 @@ describe('errorHandler', () => {
|
|||||||
|
|
||||||
expect(res.status).to.be.calledWith(500);
|
expect(res.status).to.be.calledWith(500);
|
||||||
expect(res.json).to.be.calledWith({
|
expect(res.json).to.be.calledWith({
|
||||||
|
success: false,
|
||||||
error: 'InternalServerError',
|
error: 'InternalServerError',
|
||||||
message: 'An unexpected error occurred.',
|
message: 'An unexpected error occurred.',
|
||||||
});
|
});
|
||||||
@@ -85,6 +88,7 @@ describe('errorHandler', () => {
|
|||||||
|
|
||||||
expect(res.status).to.be.calledWith(400);
|
expect(res.status).to.be.calledWith(400);
|
||||||
expect(res.json).to.be.calledWith({
|
expect(res.json).to.be.calledWith({
|
||||||
|
success: false,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
message: 'Bad request.',
|
message: 'Bad request.',
|
||||||
});
|
});
|
||||||
@@ -101,6 +105,7 @@ describe('errorHandler', () => {
|
|||||||
|
|
||||||
expect(res.status).to.be.calledWith(error.statusCode);
|
expect(res.status).to.be.calledWith(error.statusCode);
|
||||||
expect(res.json).to.be.calledWith({
|
expect(res.json).to.be.calledWith({
|
||||||
|
success: false,
|
||||||
error: error.name,
|
error: error.name,
|
||||||
message: error.message,
|
message: error.message,
|
||||||
});
|
});
|
||||||
@@ -116,6 +121,7 @@ describe('errorHandler', () => {
|
|||||||
|
|
||||||
expect(res.status).to.be.calledWith(400);
|
expect(res.status).to.be.calledWith(400);
|
||||||
expect(res.json).to.be.calledWith({
|
expect(res.json).to.be.calledWith({
|
||||||
|
success: false,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
message: 'Invalid request parameters.',
|
message: 'Invalid request parameters.',
|
||||||
errors: [
|
errors: [
|
||||||
@@ -143,6 +149,7 @@ describe('errorHandler', () => {
|
|||||||
|
|
||||||
expect(res.status).to.be.calledWith(400);
|
expect(res.status).to.be.calledWith(400);
|
||||||
expect(res.json).to.be.calledWith({
|
expect(res.json).to.be.calledWith({
|
||||||
|
success: false,
|
||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
message: 'User validation failed.',
|
message: 'User validation failed.',
|
||||||
errors: [
|
errors: [
|
||||||
|
|||||||
@@ -30,7 +30,23 @@ describe('response middleware', () => {
|
|||||||
|
|
||||||
expect(res.status).to.be.calledWith(200);
|
expect(res.status).to.be.calledWith(200);
|
||||||
expect(res.json).to.be.calledWith({
|
expect(res.json).to.be.calledWith({
|
||||||
field: 1,
|
success: true,
|
||||||
|
data: {field: 1},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can be passed a third parameter to be used as optional message', () => {
|
||||||
|
responseMiddleware(req, res, next);
|
||||||
|
res.respond(200, {field: 1}, 'hello');
|
||||||
|
|
||||||
|
expect(res.status).to.be.calledOnce;
|
||||||
|
expect(res.json).to.be.calledOnce;
|
||||||
|
|
||||||
|
expect(res.status).to.be.calledWith(200);
|
||||||
|
expect(res.json).to.be.calledWith({
|
||||||
|
success: true,
|
||||||
|
data: {field: 1},
|
||||||
|
message: 'hello',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -43,7 +59,8 @@ describe('response middleware', () => {
|
|||||||
|
|
||||||
expect(res.status).to.be.calledWith(403);
|
expect(res.status).to.be.calledWith(403);
|
||||||
expect(res.json).to.be.calledWith({
|
expect(res.json).to.be.calledWith({
|
||||||
field: 1,
|
success: false,
|
||||||
|
data: {field: 1},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ describe('Challenge Model', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Tasks.Task.sanitize(req.body);
|
Tasks.Task.sanitize(req.body);
|
||||||
_.assign(task, common.ops.updateTask(task.toObject(), req));
|
_.assign(task, common.ops.updateTask(task.toObject(), req)[0]);
|
||||||
|
|
||||||
await challenge.updateTask(task);
|
await challenge.updateTask(task);
|
||||||
|
|
||||||
|
|||||||
165
test/common/fns/randomDrop.test.js
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
// TODO disable until we can find a way to stub predictableRandom
|
||||||
|
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
import randomDrop from '../../../common/script/fns/randomDrop';
|
||||||
|
import {
|
||||||
|
generateUser,
|
||||||
|
generateTodo,
|
||||||
|
generateHabit,
|
||||||
|
generateDaily,
|
||||||
|
generateReward,
|
||||||
|
} from '../../helpers/common.helper';
|
||||||
|
// import predictableRandom from '../../../common/script/fns/predictableRandom'; // eslint-disable
|
||||||
|
import content from '../../../common/script/content/index';
|
||||||
|
|
||||||
|
xdescribe('common.fns.randomDrop', () => {
|
||||||
|
let user;
|
||||||
|
let task;
|
||||||
|
let predictableRandom;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
user = generateUser();
|
||||||
|
user._tmp = user._tmp ? user._tmp : {};
|
||||||
|
task = generateTodo({ userId: user._id });
|
||||||
|
predictableRandom = () => {
|
||||||
|
return 0.5;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function signature as follows:
|
||||||
|
* randomDrop(user, modifiers) {}
|
||||||
|
* modifiers = { task, delta = null }
|
||||||
|
**/
|
||||||
|
|
||||||
|
it('drops an item for the user.party.quest.progress', () => {
|
||||||
|
expect(user.party.quest.progress.collect).to.eql({});
|
||||||
|
user.party.quest.key = 'vice2';
|
||||||
|
let collectWhat = Object.keys(content.quests[user.party.quest.key].collect)[0]; // lightCrystal
|
||||||
|
predictableRandom = () => {
|
||||||
|
return 0.0001;
|
||||||
|
};
|
||||||
|
randomDrop(user, { task });
|
||||||
|
expect(user.party.quest.progress.collect[collectWhat]).to.eql(1);
|
||||||
|
randomDrop(user, { task });
|
||||||
|
expect(user.party.quest.progress.collect[collectWhat]).to.eql(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
context('drops enabled', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
user.flags.dropsEnabled = true;
|
||||||
|
task.priority = 100000;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does nothing if user.items.lastDrop.count is exceeded', () => {
|
||||||
|
user.items.lastDrop.count = 100;
|
||||||
|
randomDrop(user, { task });
|
||||||
|
expect(user._tmp).to.eql({});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('drops something when the task is a todo', () => {
|
||||||
|
expect(user._tmp).to.eql({});
|
||||||
|
user.flags.dropsEnabled = true;
|
||||||
|
predictableRandom = () => {
|
||||||
|
return 0.1;
|
||||||
|
};
|
||||||
|
randomDrop(user, { task });
|
||||||
|
expect(user._tmp).to.not.eql({});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('drops something when the task is a habit', () => {
|
||||||
|
task = generateHabit({ userId: user._id });
|
||||||
|
expect(user._tmp).to.eql({});
|
||||||
|
user.flags.dropsEnabled = true;
|
||||||
|
predictableRandom = () => {
|
||||||
|
return 0.1;
|
||||||
|
};
|
||||||
|
randomDrop(user, { task });
|
||||||
|
expect(user._tmp).to.not.eql({});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('drops something when the task is a daily', () => {
|
||||||
|
task = generateDaily({ userId: user._id });
|
||||||
|
expect(user._tmp).to.eql({});
|
||||||
|
user.flags.dropsEnabled = true;
|
||||||
|
predictableRandom = () => {
|
||||||
|
return 0.1;
|
||||||
|
};
|
||||||
|
randomDrop(user, { task });
|
||||||
|
expect(user._tmp).to.not.eql({});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('drops something when the task is a reward', () => {
|
||||||
|
task = generateReward({ userId: user._id });
|
||||||
|
expect(user._tmp).to.eql({});
|
||||||
|
user.flags.dropsEnabled = true;
|
||||||
|
predictableRandom = () => {
|
||||||
|
return 0.1;
|
||||||
|
};
|
||||||
|
randomDrop(user, { task });
|
||||||
|
expect(user._tmp).to.not.eql({});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('drops food', () => {
|
||||||
|
predictableRandom = () => {
|
||||||
|
return 0.65;
|
||||||
|
};
|
||||||
|
randomDrop(user, { task });
|
||||||
|
expect(user._tmp.drop.type).to.eql('Food');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('drops eggs', () => {
|
||||||
|
predictableRandom = () => {
|
||||||
|
return 0.35;
|
||||||
|
};
|
||||||
|
randomDrop(user, { task });
|
||||||
|
expect(user._tmp.drop.type).to.eql('Egg');
|
||||||
|
});
|
||||||
|
|
||||||
|
context('drops hatching potion', () => {
|
||||||
|
it('drops a very rare potion', () => {
|
||||||
|
predictableRandom = () => {
|
||||||
|
return 0.01;
|
||||||
|
};
|
||||||
|
randomDrop(user, { task });
|
||||||
|
expect(user._tmp.drop.type).to.eql('HatchingPotion');
|
||||||
|
expect(user._tmp.drop.value).to.eql(5);
|
||||||
|
expect(user._tmp.drop.key).to.eql('Golden');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('drops a rare potion', () => {
|
||||||
|
predictableRandom = () => {
|
||||||
|
return 0.08;
|
||||||
|
};
|
||||||
|
randomDrop(user, { task });
|
||||||
|
expect(user._tmp.drop.type).to.eql('HatchingPotion');
|
||||||
|
expect(user._tmp.drop.value).to.eql(4);
|
||||||
|
let acceptableDrops = ['Zombie', 'CottonCandyPink', 'CottonCandyBlue'];
|
||||||
|
expect(acceptableDrops).to.contain(user._tmp.drop.key); // deterministically 'CottonCandyBlue'
|
||||||
|
});
|
||||||
|
|
||||||
|
it('drops an uncommon potion', () => {
|
||||||
|
predictableRandom = () => {
|
||||||
|
return 0.17;
|
||||||
|
};
|
||||||
|
randomDrop(user, { task });
|
||||||
|
expect(user._tmp.drop.type).to.eql('HatchingPotion');
|
||||||
|
expect(user._tmp.drop.value).to.eql(3);
|
||||||
|
let acceptableDrops = ['Red', 'Shade', 'Skeleton'];
|
||||||
|
expect(acceptableDrops).to.contain(user._tmp.drop.key); // always skeleton
|
||||||
|
});
|
||||||
|
|
||||||
|
it('drops a common potion', () => {
|
||||||
|
predictableRandom = () => {
|
||||||
|
return 0.20;
|
||||||
|
};
|
||||||
|
randomDrop(user, { task });
|
||||||
|
expect(user._tmp.drop.type).to.eql('HatchingPotion');
|
||||||
|
expect(user._tmp.drop.value).to.eql(2);
|
||||||
|
let acceptableDrops = ['Base', 'White', 'Desert'];
|
||||||
|
expect(acceptableDrops).to.contain(user._tmp.drop.key); // always Desert
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -39,9 +39,9 @@ describe('shared.ops.addPushDevice', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('adds a push device', () => {
|
it('adds a push device', () => {
|
||||||
let response = addPushDevice(user, {body: {regId, type}});
|
let [, message] = addPushDevice(user, {body: {regId, type}});
|
||||||
|
|
||||||
expect(response.message).to.equal(i18n.t('pushDeviceAdded'));
|
expect(message).to.equal(i18n.t('pushDeviceAdded'));
|
||||||
expect(user.pushDevices[0].type).to.equal(type);
|
expect(user.pushDevices[0].type).to.equal(type);
|
||||||
expect(user.pushDevices[0].regId).to.equal(regId);
|
expect(user.pushDevices[0].regId).to.equal(regId);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -18,17 +18,13 @@ describe('shared.ops.allocateNow', () => {
|
|||||||
user.stats.str = 9;
|
user.stats.str = 9;
|
||||||
user.preferences.allocationMode = 'flat';
|
user.preferences.allocationMode = 'flat';
|
||||||
|
|
||||||
let res = allocateNow(user);
|
let [data] = allocateNow(user);
|
||||||
|
|
||||||
expect(user.stats.points).to.equal(0);
|
expect(user.stats.points).to.equal(0);
|
||||||
expect(user.stats.con).to.equal(9);
|
expect(user.stats.con).to.equal(9);
|
||||||
expect(user.stats.int).to.equal(8);
|
expect(user.stats.int).to.equal(8);
|
||||||
expect(user.stats.per).to.equal(9);
|
expect(user.stats.per).to.equal(9);
|
||||||
expect(user.stats.str).to.equal(9);
|
expect(user.stats.str).to.equal(9);
|
||||||
expect(res).to.eql({
|
expect(data).to.eql(user.stats);
|
||||||
data: {
|
|
||||||
stats: user.stats,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -26,10 +26,10 @@ describe('shared.ops.blockUser', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('blocks user', () => {
|
it('blocks user', () => {
|
||||||
let result = blockUser(user, { params: { uuid: blockedUser._id } });
|
let [result] = blockUser(user, { params: { uuid: blockedUser._id } });
|
||||||
expect(user.inbox.blocks).to.eql([blockedUser._id]);
|
expect(user.inbox.blocks).to.eql([blockedUser._id]);
|
||||||
expect(result).to.eql([blockedUser._id]);
|
expect(result).to.eql([blockedUser._id]);
|
||||||
result = blockUser(user, { params: { uuid: blockedUser2._id } });
|
[result] = blockUser(user, { params: { uuid: blockedUser2._id } });
|
||||||
expect(user.inbox.blocks).to.eql([blockedUser._id, blockedUser2._id]);
|
expect(user.inbox.blocks).to.eql([blockedUser._id, blockedUser2._id]);
|
||||||
expect(result).to.eql([blockedUser._id, blockedUser2._id]);
|
expect(result).to.eql([blockedUser._id, blockedUser2._id]);
|
||||||
});
|
});
|
||||||
@@ -37,7 +37,7 @@ describe('shared.ops.blockUser', () => {
|
|||||||
it('blocks, then unblocks user', () => {
|
it('blocks, then unblocks user', () => {
|
||||||
blockUser(user, { params: { uuid: blockedUser._id } });
|
blockUser(user, { params: { uuid: blockedUser._id } });
|
||||||
expect(user.inbox.blocks).to.eql([blockedUser._id]);
|
expect(user.inbox.blocks).to.eql([blockedUser._id]);
|
||||||
let result = blockUser(user, { params: { uuid: blockedUser._id } });
|
let [result] = blockUser(user, { params: { uuid: blockedUser._id } });
|
||||||
expect(user.inbox.blocks).to.eql([]);
|
expect(user.inbox.blocks).to.eql([]);
|
||||||
expect(result).to.eql([]);
|
expect(result).to.eql([]);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,15 +1,10 @@
|
|||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
|
|
||||||
import sinon from 'sinon'; // eslint-disable-line no-shadow
|
|
||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
} from '../../helpers/common.helper';
|
} from '../../helpers/common.helper';
|
||||||
import count from '../../../common/script/count';
|
|
||||||
import buy from '../../../common/script/ops/buy';
|
import buy from '../../../common/script/ops/buy';
|
||||||
import shared from '../../../common/script';
|
|
||||||
import content from '../../../common/script/content/index';
|
|
||||||
import {
|
import {
|
||||||
NotAuthorized,
|
BadRequest,
|
||||||
} from '../../../common/script/libs/errors';
|
} from '../../../common/script/libs/errors';
|
||||||
import i18n from '../../../common/script/i18n';
|
import i18n from '../../../common/script/i18n';
|
||||||
|
|
||||||
@@ -30,277 +25,27 @@ describe('shared.ops.buy', () => {
|
|||||||
},
|
},
|
||||||
stats: { gp: 200 },
|
stats: { gp: 200 },
|
||||||
});
|
});
|
||||||
|
|
||||||
sinon.stub(shared.fns, 'randomVal');
|
|
||||||
sinon.stub(shared.fns, 'predictableRandom');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
it('returns error when key is not provided', (done) => {
|
||||||
shared.fns.randomVal.restore();
|
try {
|
||||||
shared.fns.predictableRandom.restore();
|
buy(user);
|
||||||
|
} catch (err) {
|
||||||
|
expect(err).to.be.an.instanceof(BadRequest);
|
||||||
|
expect(err.message).to.equal(i18n.t('missingKeyParam'));
|
||||||
|
done();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
context('Potion', () => {
|
|
||||||
it('recovers 15 hp', () => {
|
it('recovers 15 hp', () => {
|
||||||
user.stats.hp = 30;
|
user.stats.hp = 30;
|
||||||
buy(user, {params: {key: 'potion'}});
|
buy(user, {params: {key: 'potion'}});
|
||||||
expect(user.stats.hp).to.eql(45);
|
expect(user.stats.hp).to.eql(45);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not increase hp above 50', () => {
|
|
||||||
user.stats.hp = 45;
|
|
||||||
buy(user, {params: {key: 'potion'}});
|
|
||||||
expect(user.stats.hp).to.eql(50);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('deducts 25 gp', () => {
|
|
||||||
user.stats.hp = 45;
|
|
||||||
buy(user, {params: {key: 'potion'}});
|
|
||||||
|
|
||||||
expect(user.stats.gp).to.eql(175);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not purchase if not enough gp', (done) => {
|
|
||||||
user.stats.hp = 45;
|
|
||||||
user.stats.gp = 5;
|
|
||||||
try {
|
|
||||||
buy(user, {params: {key: 'potion'}});
|
|
||||||
} catch (err) {
|
|
||||||
expect(err).to.be.an.instanceof(NotAuthorized);
|
|
||||||
expect(err.message).to.equal(i18n.t('messageNotEnoughGold'));
|
|
||||||
expect(user.stats.hp).to.eql(45);
|
|
||||||
expect(user.stats.gp).to.eql(5);
|
|
||||||
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
context('Gear', () => {
|
|
||||||
it('adds equipment to inventory', () => {
|
it('adds equipment to inventory', () => {
|
||||||
user.stats.gp = 31;
|
user.stats.gp = 31;
|
||||||
|
|
||||||
buy(user, {params: {key: 'armor_warrior_1'}});
|
buy(user, {params: {key: 'armor_warrior_1'}});
|
||||||
|
|
||||||
expect(user.items.gear.owned).to.eql({ weapon_warrior_0: true, armor_warrior_1: true });
|
expect(user.items.gear.owned).to.eql({ weapon_warrior_0: true, armor_warrior_1: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('deducts gold from user', () => {
|
|
||||||
user.stats.gp = 31;
|
|
||||||
|
|
||||||
buy(user, {params: {key: 'armor_warrior_1'}});
|
|
||||||
|
|
||||||
expect(user.stats.gp).to.eql(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('auto equips equipment if user has auto-equip preference turned on', () => {
|
|
||||||
user.stats.gp = 31;
|
|
||||||
user.preferences.autoEquip = true;
|
|
||||||
|
|
||||||
buy(user, {params: {key: 'armor_warrior_1'}});
|
|
||||||
|
|
||||||
expect(user.items.gear.equipped).to.have.property('armor', 'armor_warrior_1');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('buys equipment but does not auto-equip', () => {
|
|
||||||
user.stats.gp = 31;
|
|
||||||
user.preferences.autoEquip = false;
|
|
||||||
|
|
||||||
buy(user, {params: {key: 'armor_warrior_1'}});
|
|
||||||
|
|
||||||
expect(user.items.gear.equipped.property).to.not.equal('armor_warrior_1');
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO after user.ops.equip is done
|
|
||||||
xit('removes one-handed weapon and shield if auto-equip is on and a two-hander is bought', () => {
|
|
||||||
user.stats.gp = 100;
|
|
||||||
user.preferences.autoEquip = true;
|
|
||||||
buy(user, {params: {key: 'shield_warrior_1'}});
|
|
||||||
user.ops.equip({params: {key: 'shield_warrior_1'}});
|
|
||||||
buy(user, {params: {key: 'weapon_warrior_1'}});
|
|
||||||
user.ops.equip({params: {key: 'weapon_warrior_1'}});
|
|
||||||
|
|
||||||
buy(user, {params: {key: 'weapon_wizard_1'}});
|
|
||||||
|
|
||||||
expect(user.items.gear.equipped).to.have.property('shield', 'shield_base_0');
|
|
||||||
expect(user.items.gear.equipped).to.have.property('weapon', 'weapon_wizard_1');
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO after user.ops.equip is done
|
|
||||||
xit('buys two-handed equipment but does not automatically remove sword or shield', () => {
|
|
||||||
user.stats.gp = 100;
|
|
||||||
user.preferences.autoEquip = false;
|
|
||||||
buy(user, {params: {key: 'shield_warrior_1'}});
|
|
||||||
user.ops.equip({params: {key: 'shield_warrior_1'}});
|
|
||||||
buy(user, {params: {key: 'weapon_warrior_1'}});
|
|
||||||
user.ops.equip({params: {key: 'weapon_warrior_1'}});
|
|
||||||
|
|
||||||
buy(user, {params: {key: 'weapon_wizard_1'}});
|
|
||||||
|
|
||||||
expect(user.items.gear.equipped).to.have.property('shield', 'shield_warrior_1');
|
|
||||||
expect(user.items.gear.equipped).to.have.property('weapon', 'weapon_warrior_1');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not buy equipment without enough Gold', (done) => {
|
|
||||||
user.stats.gp = 20;
|
|
||||||
|
|
||||||
try {
|
|
||||||
buy(user, {params: {key: 'armor_warrior_1'}});
|
|
||||||
} catch (err) {
|
|
||||||
expect(err).to.be.an.instanceof(NotAuthorized);
|
|
||||||
expect(err.message).to.equal(i18n.t('messageNotEnoughGold'));
|
|
||||||
expect(user.items.gear.owned).to.not.have.property('armor_warrior_1');
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
context('Enchanted Armoire', () => {
|
|
||||||
let YIELD_EQUIPMENT = 0.5;
|
|
||||||
let YIELD_FOOD = 0.7;
|
|
||||||
let YIELD_EXP = 0.9;
|
|
||||||
|
|
||||||
let fullArmoire = {};
|
|
||||||
|
|
||||||
_(content.gearTypes).each((type) => {
|
|
||||||
_(content.gear.tree[type].armoire).each((gearObject) => {
|
|
||||||
let armoireKey = gearObject.key;
|
|
||||||
|
|
||||||
fullArmoire[armoireKey] = true;
|
|
||||||
}).value();
|
|
||||||
}).value();
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
user.achievements.ultimateGearSets = { rogue: true };
|
|
||||||
user.flags.armoireOpened = true;
|
|
||||||
user.stats.exp = 0;
|
|
||||||
user.items.food = {};
|
|
||||||
});
|
|
||||||
|
|
||||||
context('failure conditions', () => {
|
|
||||||
it('does not open if user does not have enough gold', (done) => {
|
|
||||||
shared.fns.predictableRandom.returns(YIELD_EQUIPMENT);
|
|
||||||
user.stats.gp = 50;
|
|
||||||
|
|
||||||
try {
|
|
||||||
buy(user, {params: {key: 'armoire'}});
|
|
||||||
} catch (err) {
|
|
||||||
expect(err).to.be.an.instanceof(NotAuthorized);
|
|
||||||
expect(err.message).to.equal(i18n.t('messageNotEnoughGold'));
|
|
||||||
expect(user.items.gear.owned).to.eql({weapon_warrior_0: true});
|
|
||||||
expect(user.items.food).to.be.empty;
|
|
||||||
expect(user.stats.exp).to.eql(0);
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not open without Ultimate Gear achievement', (done) => {
|
|
||||||
shared.fns.predictableRandom.returns(YIELD_EQUIPMENT);
|
|
||||||
user.achievements.ultimateGearSets = {healer: false, wizard: false, rogue: false, warrior: false};
|
|
||||||
|
|
||||||
try {
|
|
||||||
buy(user, {params: {key: 'armoire'}});
|
|
||||||
} catch (err) {
|
|
||||||
expect(err).to.be.an.instanceof(NotAuthorized);
|
|
||||||
expect(err.message).to.equal(i18n.t('cannoyBuyItem'));
|
|
||||||
expect(user.items.gear.owned).to.eql({weapon_warrior_0: true});
|
|
||||||
expect(user.items.food).to.be.empty;
|
|
||||||
expect(user.stats.exp).to.eql(0);
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
context('non-gear awards', () => {
|
|
||||||
// Skipped because can't stub predictableRandom correctly
|
|
||||||
xit('gives Experience', () => {
|
|
||||||
shared.fns.predictableRandom.returns(YIELD_EXP);
|
|
||||||
|
|
||||||
buy(user, {params: {key: 'armoire'}});
|
|
||||||
|
|
||||||
expect(user.items.gear.owned).to.eql({weapon_warrior_0: true});
|
|
||||||
expect(user.items.food).to.be.empty;
|
|
||||||
expect(user.stats.exp).to.eql(46);
|
|
||||||
expect(user.stats.gp).to.eql(100);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Skipped because can't stub predictableRandom correctly
|
|
||||||
xit('gives food', () => {
|
|
||||||
let honey = content.food.Honey;
|
|
||||||
|
|
||||||
shared.fns.randomVal.returns(honey);
|
|
||||||
shared.fns.predictableRandom.returns(YIELD_FOOD);
|
|
||||||
|
|
||||||
buy(user, {params: {key: 'armoire'}});
|
|
||||||
|
|
||||||
expect(user.items.gear.owned).to.eql({weapon_warrior_0: true});
|
|
||||||
expect(user.items.food).to.eql({Honey: 1});
|
|
||||||
expect(user.stats.exp).to.eql(0);
|
|
||||||
expect(user.stats.gp).to.eql(100);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Skipped because can't stub predictableRandom correctly
|
|
||||||
xit('does not give equipment if all equipment has been found', () => {
|
|
||||||
shared.fns.predictableRandom.returns(YIELD_EQUIPMENT);
|
|
||||||
user.items.gear.owned = fullArmoire;
|
|
||||||
user.stats.gp = 150;
|
|
||||||
|
|
||||||
buy(user, {params: {key: 'armoire'}});
|
|
||||||
|
|
||||||
expect(user.items.gear.owned).to.eql(fullArmoire);
|
|
||||||
let armoireCount = count.remainingGearInSet(user.items.gear.owned, 'armoire');
|
|
||||||
|
|
||||||
expect(armoireCount).to.eql(0);
|
|
||||||
|
|
||||||
expect(user.stats.exp).to.eql(30);
|
|
||||||
expect(user.stats.gp).to.eql(50);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
context('gear awards', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
let shield = content.gear.tree.shield.armoire.gladiatorShield;
|
|
||||||
|
|
||||||
shared.fns.randomVal.returns(shield);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Skipped because can't stub predictableRandom correctly
|
|
||||||
xit('always drops equipment the first time', () => {
|
|
||||||
delete user.flags.armoireOpened;
|
|
||||||
shared.fns.predictableRandom.returns(YIELD_EXP);
|
|
||||||
|
|
||||||
buy(user, {params: {key: 'armoire'}});
|
|
||||||
|
|
||||||
expect(user.items.gear.owned).to.eql({
|
|
||||||
weapon_warrior_0: true,
|
|
||||||
shield_armoire_gladiatorShield: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
let armoireCount = count.remainingGearInSet(user.items.gear.owned, 'armoire');
|
|
||||||
|
|
||||||
expect(armoireCount).to.eql(_.size(fullArmoire) - 1);
|
|
||||||
expect(user.items.food).to.be.empty;
|
|
||||||
expect(user.stats.exp).to.eql(0);
|
|
||||||
expect(user.stats.gp).to.eql(100);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Skipped because can't stub predictableRandom correctly
|
|
||||||
xit('gives more equipment', () => {
|
|
||||||
shared.fns.predictableRandom.returns(YIELD_EQUIPMENT);
|
|
||||||
user.items.gear.owned = {
|
|
||||||
weapon_warrior_0: true,
|
|
||||||
head_armoire_hornedIronHelm: true,
|
|
||||||
};
|
|
||||||
user.stats.gp = 200;
|
|
||||||
|
|
||||||
buy(user, {params: {key: 'armoire'}});
|
|
||||||
|
|
||||||
expect(user.items.gear.owned).to.eql({weapon_warrior_0: true, shield_armoire_gladiatorShield: true, head_armoire_hornedIronHelm: true});
|
|
||||||
let armoireCount = count.remainingGearInSet(user.items.gear.owned, 'armoire');
|
|
||||||
|
|
||||||
expect(armoireCount).to.eql(_.size(fullArmoire) - 2);
|
|
||||||
expect(user.stats.gp).to.eql(100);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
187
test/common/ops/buyArmoire.js
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
/* eslint-disable camelcase */
|
||||||
|
|
||||||
|
import sinon from 'sinon'; // eslint-disable-line no-shadow
|
||||||
|
import {
|
||||||
|
generateUser,
|
||||||
|
} from '../../helpers/common.helper';
|
||||||
|
import count from '../../../common/script/count';
|
||||||
|
import buyArmoire from '../../../common/script/ops/buyArmoire';
|
||||||
|
import shared from '../../../common/script';
|
||||||
|
import content from '../../../common/script/content/index';
|
||||||
|
import {
|
||||||
|
NotAuthorized,
|
||||||
|
} from '../../../common/script/libs/errors';
|
||||||
|
import i18n from '../../../common/script/i18n';
|
||||||
|
|
||||||
|
describe('shared.ops.buyArmoire', () => {
|
||||||
|
let user;
|
||||||
|
let YIELD_EQUIPMENT = 0.5;
|
||||||
|
let YIELD_FOOD = 0.7;
|
||||||
|
let YIELD_EXP = 0.9;
|
||||||
|
|
||||||
|
let fullArmoire = {};
|
||||||
|
|
||||||
|
_(content.gearTypes).each((type) => {
|
||||||
|
_(content.gear.tree[type].armoire).each((gearObject) => {
|
||||||
|
let armoireKey = gearObject.key;
|
||||||
|
|
||||||
|
fullArmoire[armoireKey] = true;
|
||||||
|
}).value();
|
||||||
|
}).value();
|
||||||
|
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
user = generateUser({
|
||||||
|
items: {
|
||||||
|
gear: {
|
||||||
|
owned: {
|
||||||
|
weapon_warrior_0: true,
|
||||||
|
},
|
||||||
|
equipped: {
|
||||||
|
weapon_warrior_0: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
stats: { gp: 200 },
|
||||||
|
});
|
||||||
|
|
||||||
|
user.achievements.ultimateGearSets = { rogue: true };
|
||||||
|
user.flags.armoireOpened = true;
|
||||||
|
user.stats.exp = 0;
|
||||||
|
user.items.food = {};
|
||||||
|
|
||||||
|
sinon.stub(shared.fns, 'randomVal');
|
||||||
|
sinon.stub(shared.fns, 'predictableRandom');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
shared.fns.randomVal.restore();
|
||||||
|
shared.fns.predictableRandom.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
context('failure conditions', () => {
|
||||||
|
it('does not open if user does not have enough gold', (done) => {
|
||||||
|
shared.fns.predictableRandom.returns(YIELD_EQUIPMENT);
|
||||||
|
user.stats.gp = 50;
|
||||||
|
|
||||||
|
try {
|
||||||
|
buyArmoire(user);
|
||||||
|
} catch (err) {
|
||||||
|
expect(err).to.be.an.instanceof(NotAuthorized);
|
||||||
|
expect(err.message).to.equal(i18n.t('messageNotEnoughGold'));
|
||||||
|
expect(user.items.gear.owned).to.eql({weapon_warrior_0: true});
|
||||||
|
expect(user.items.food).to.be.empty;
|
||||||
|
expect(user.stats.exp).to.eql(0);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not open without Ultimate Gear achievement', (done) => {
|
||||||
|
shared.fns.predictableRandom.returns(YIELD_EQUIPMENT);
|
||||||
|
user.achievements.ultimateGearSets = {healer: false, wizard: false, rogue: false, warrior: false};
|
||||||
|
|
||||||
|
try {
|
||||||
|
buyArmoire(user);
|
||||||
|
} catch (err) {
|
||||||
|
expect(err).to.be.an.instanceof(NotAuthorized);
|
||||||
|
expect(err.message).to.equal(i18n.t('cannotBuyItem'));
|
||||||
|
expect(user.items.gear.owned).to.eql({weapon_warrior_0: true});
|
||||||
|
expect(user.items.food).to.be.empty;
|
||||||
|
expect(user.stats.exp).to.eql(0);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('non-gear awards', () => {
|
||||||
|
// Skipped because can't stub predictableRandom correctly
|
||||||
|
xit('gives Experience', () => {
|
||||||
|
shared.fns.predictableRandom.returns(YIELD_EXP);
|
||||||
|
|
||||||
|
buyArmoire(user);
|
||||||
|
|
||||||
|
expect(user.items.gear.owned).to.eql({weapon_warrior_0: true});
|
||||||
|
expect(user.items.food).to.be.empty;
|
||||||
|
expect(user.stats.exp).to.eql(46);
|
||||||
|
expect(user.stats.gp).to.eql(100);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Skipped because can't stub predictableRandom correctly
|
||||||
|
xit('gives food', () => {
|
||||||
|
let honey = content.food.Honey;
|
||||||
|
|
||||||
|
shared.fns.randomVal.returns(honey);
|
||||||
|
shared.fns.predictableRandom.returns(YIELD_FOOD);
|
||||||
|
|
||||||
|
buyArmoire(user);
|
||||||
|
|
||||||
|
expect(user.items.gear.owned).to.eql({weapon_warrior_0: true});
|
||||||
|
expect(user.items.food).to.eql({Honey: 1});
|
||||||
|
expect(user.stats.exp).to.eql(0);
|
||||||
|
expect(user.stats.gp).to.eql(100);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Skipped because can't stub predictableRandom correctly
|
||||||
|
xit('does not give equipment if all equipment has been found', () => {
|
||||||
|
shared.fns.predictableRandom.returns(YIELD_EQUIPMENT);
|
||||||
|
user.items.gear.owned = fullArmoire;
|
||||||
|
user.stats.gp = 150;
|
||||||
|
|
||||||
|
buyArmoire(user);
|
||||||
|
|
||||||
|
expect(user.items.gear.owned).to.eql(fullArmoire);
|
||||||
|
let armoireCount = count.remainingGearInSet(user.items.gear.owned, 'armoire');
|
||||||
|
|
||||||
|
expect(armoireCount).to.eql(0);
|
||||||
|
|
||||||
|
expect(user.stats.exp).to.eql(30);
|
||||||
|
expect(user.stats.gp).to.eql(50);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('gear awards', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
let shield = content.gear.tree.shield.armoire.gladiatorShield;
|
||||||
|
|
||||||
|
shared.fns.randomVal.returns(shield);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Skipped because can't stub predictableRandom correctly
|
||||||
|
xit('always drops equipment the first time', () => {
|
||||||
|
delete user.flags.armoireOpened;
|
||||||
|
shared.fns.predictableRandom.returns(YIELD_EXP);
|
||||||
|
|
||||||
|
buyArmoire(user);
|
||||||
|
|
||||||
|
expect(user.items.gear.owned).to.eql({
|
||||||
|
weapon_warrior_0: true,
|
||||||
|
shield_armoire_gladiatorShield: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
let armoireCount = count.remainingGearInSet(user.items.gear.owned, 'armoire');
|
||||||
|
|
||||||
|
expect(armoireCount).to.eql(_.size(fullArmoire) - 1);
|
||||||
|
expect(user.items.food).to.be.empty;
|
||||||
|
expect(user.stats.exp).to.eql(0);
|
||||||
|
expect(user.stats.gp).to.eql(100);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Skipped because can't stub predictableRandom correctly
|
||||||
|
xit('gives more equipment', () => {
|
||||||
|
shared.fns.predictableRandom.returns(YIELD_EQUIPMENT);
|
||||||
|
user.items.gear.owned = {
|
||||||
|
weapon_warrior_0: true,
|
||||||
|
head_armoire_hornedIronHelm: true,
|
||||||
|
};
|
||||||
|
user.stats.gp = 200;
|
||||||
|
|
||||||
|
buyArmoire(user);
|
||||||
|
|
||||||
|
expect(user.items.gear.owned).to.eql({weapon_warrior_0: true, shield_armoire_gladiatorShield: true, head_armoire_hornedIronHelm: true});
|
||||||
|
let armoireCount = count.remainingGearInSet(user.items.gear.owned, 'armoire');
|
||||||
|
|
||||||
|
expect(armoireCount).to.eql(_.size(fullArmoire) - 2);
|
||||||
|
expect(user.stats.gp).to.eql(100);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
132
test/common/ops/buyGear.js
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
/* eslint-disable camelcase */
|
||||||
|
|
||||||
|
import sinon from 'sinon'; // eslint-disable-line no-shadow
|
||||||
|
import {
|
||||||
|
generateUser,
|
||||||
|
} from '../../helpers/common.helper';
|
||||||
|
import buyGear from '../../../common/script/ops/buyGear';
|
||||||
|
import shared from '../../../common/script';
|
||||||
|
import {
|
||||||
|
NotAuthorized,
|
||||||
|
} from '../../../common/script/libs/errors';
|
||||||
|
import i18n from '../../../common/script/i18n';
|
||||||
|
|
||||||
|
describe('shared.ops.buyGear', () => {
|
||||||
|
let user;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
user = generateUser({
|
||||||
|
items: {
|
||||||
|
gear: {
|
||||||
|
owned: {
|
||||||
|
weapon_warrior_0: true,
|
||||||
|
},
|
||||||
|
equipped: {
|
||||||
|
weapon_warrior_0: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
stats: { gp: 200 },
|
||||||
|
});
|
||||||
|
|
||||||
|
sinon.stub(shared.fns, 'randomVal');
|
||||||
|
sinon.stub(shared.fns, 'predictableRandom');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
shared.fns.randomVal.restore();
|
||||||
|
shared.fns.predictableRandom.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
context('Gear', () => {
|
||||||
|
it('adds equipment to inventory', () => {
|
||||||
|
user.stats.gp = 31;
|
||||||
|
|
||||||
|
buyGear(user, {params: {key: 'armor_warrior_1'}});
|
||||||
|
|
||||||
|
expect(user.items.gear.owned).to.eql({ weapon_warrior_0: true, armor_warrior_1: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('deducts gold from user', () => {
|
||||||
|
user.stats.gp = 31;
|
||||||
|
|
||||||
|
buyGear(user, {params: {key: 'armor_warrior_1'}});
|
||||||
|
|
||||||
|
expect(user.stats.gp).to.eql(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('auto equips equipment if user has auto-equip preference turned on', () => {
|
||||||
|
user.stats.gp = 31;
|
||||||
|
user.preferences.autoEquip = true;
|
||||||
|
|
||||||
|
buyGear(user, {params: {key: 'armor_warrior_1'}});
|
||||||
|
|
||||||
|
expect(user.items.gear.equipped).to.have.property('armor', 'armor_warrior_1');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('buyGears equipment but does not auto-equip', () => {
|
||||||
|
user.stats.gp = 31;
|
||||||
|
user.preferences.autoEquip = false;
|
||||||
|
|
||||||
|
buyGear(user, {params: {key: 'armor_warrior_1'}});
|
||||||
|
|
||||||
|
expect(user.items.gear.equipped.property).to.not.equal('armor_warrior_1');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not buyGear equipment twice', (done) => {
|
||||||
|
user.stats.gp = 62;
|
||||||
|
buyGear(user, {params: {key: 'armor_warrior_1'}});
|
||||||
|
|
||||||
|
try {
|
||||||
|
buyGear(user, {params: {key: 'armor_warrior_1'}});
|
||||||
|
} catch (err) {
|
||||||
|
expect(err).to.be.an.instanceof(NotAuthorized);
|
||||||
|
expect(err.message).to.equal(i18n.t('equipmentAlreadyOwned'));
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO after user.ops.equip is done
|
||||||
|
xit('removes one-handed weapon and shield if auto-equip is on and a two-hander is bought', () => {
|
||||||
|
user.stats.gp = 100;
|
||||||
|
user.preferences.autoEquip = true;
|
||||||
|
buyGear(user, {params: {key: 'shield_warrior_1'}});
|
||||||
|
user.ops.equip({params: {key: 'shield_warrior_1'}});
|
||||||
|
buyGear(user, {params: {key: 'weapon_warrior_1'}});
|
||||||
|
user.ops.equip({params: {key: 'weapon_warrior_1'}});
|
||||||
|
|
||||||
|
buyGear(user, {params: {key: 'weapon_wizard_1'}});
|
||||||
|
|
||||||
|
expect(user.items.gear.equipped).to.have.property('shield', 'shield_base_0');
|
||||||
|
expect(user.items.gear.equipped).to.have.property('weapon', 'weapon_wizard_1');
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO after user.ops.equip is done
|
||||||
|
xit('buyGears two-handed equipment but does not automatically remove sword or shield', () => {
|
||||||
|
user.stats.gp = 100;
|
||||||
|
user.preferences.autoEquip = false;
|
||||||
|
buyGear(user, {params: {key: 'shield_warrior_1'}});
|
||||||
|
user.ops.equip({params: {key: 'shield_warrior_1'}});
|
||||||
|
buyGear(user, {params: {key: 'weapon_warrior_1'}});
|
||||||
|
user.ops.equip({params: {key: 'weapon_warrior_1'}});
|
||||||
|
|
||||||
|
buyGear(user, {params: {key: 'weapon_wizard_1'}});
|
||||||
|
|
||||||
|
expect(user.items.gear.equipped).to.have.property('shield', 'shield_warrior_1');
|
||||||
|
expect(user.items.gear.equipped).to.have.property('weapon', 'weapon_warrior_1');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not buyGear equipment without enough Gold', (done) => {
|
||||||
|
user.stats.gp = 20;
|
||||||
|
|
||||||
|
try {
|
||||||
|
buyGear(user, {params: {key: 'armor_warrior_1'}});
|
||||||
|
} catch (err) {
|
||||||
|
expect(err).to.be.an.instanceof(NotAuthorized);
|
||||||
|
expect(err.message).to.equal(i18n.t('messageNotEnoughGold'));
|
||||||
|
expect(user.items.gear.owned).to.not.have.property('armor_warrior_1');
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
65
test/common/ops/buyPotion.js
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/* eslint-disable camelcase */
|
||||||
|
import {
|
||||||
|
generateUser,
|
||||||
|
} from '../../helpers/common.helper';
|
||||||
|
import buyPotion from '../../../common/script/ops/buyPotion';
|
||||||
|
import {
|
||||||
|
NotAuthorized,
|
||||||
|
} from '../../../common/script/libs/errors';
|
||||||
|
import i18n from '../../../common/script/i18n';
|
||||||
|
|
||||||
|
describe('shared.ops.buyPotion', () => {
|
||||||
|
let user;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
user = generateUser({
|
||||||
|
items: {
|
||||||
|
gear: {
|
||||||
|
owned: {
|
||||||
|
weapon_warrior_0: true,
|
||||||
|
},
|
||||||
|
equipped: {
|
||||||
|
weapon_warrior_0: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
stats: { gp: 200 },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('Potion', () => {
|
||||||
|
it('recovers 15 hp', () => {
|
||||||
|
user.stats.hp = 30;
|
||||||
|
buyPotion(user);
|
||||||
|
expect(user.stats.hp).to.eql(45);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not increase hp above 50', () => {
|
||||||
|
user.stats.hp = 45;
|
||||||
|
buyPotion(user);
|
||||||
|
expect(user.stats.hp).to.eql(50);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('deducts 25 gp', () => {
|
||||||
|
user.stats.hp = 45;
|
||||||
|
buyPotion(user);
|
||||||
|
|
||||||
|
expect(user.stats.gp).to.eql(175);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not purchase if not enough gp', (done) => {
|
||||||
|
user.stats.hp = 45;
|
||||||
|
user.stats.gp = 5;
|
||||||
|
try {
|
||||||
|
buyPotion(user);
|
||||||
|
} catch (err) {
|
||||||
|
expect(err).to.be.an.instanceof(NotAuthorized);
|
||||||
|
expect(err.message).to.equal(i18n.t('messageNotEnoughGold'));
|
||||||
|
expect(user.stats.hp).to.eql(45);
|
||||||
|
expect(user.stats.gp).to.eql(5);
|
||||||
|
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -60,7 +60,7 @@ describe('shared.ops.buySpecialSpell', () => {
|
|||||||
user.stats.gp = 11;
|
user.stats.gp = 11;
|
||||||
let item = content.special.thankyou;
|
let item = content.special.thankyou;
|
||||||
|
|
||||||
let res = buySpecialSpell(user, {
|
let [data, message] = buySpecialSpell(user, {
|
||||||
params: {
|
params: {
|
||||||
key: 'thankyou',
|
key: 'thankyou',
|
||||||
},
|
},
|
||||||
@@ -68,11 +68,11 @@ describe('shared.ops.buySpecialSpell', () => {
|
|||||||
|
|
||||||
expect(user.stats.gp).to.equal(1);
|
expect(user.stats.gp).to.equal(1);
|
||||||
expect(user.items.special.thankyou).to.equal(1);
|
expect(user.items.special.thankyou).to.equal(1);
|
||||||
expect(res.data).to.eql({
|
expect(data).to.eql({
|
||||||
items: user.items,
|
items: user.items,
|
||||||
stats: user.stats,
|
stats: user.stats,
|
||||||
});
|
});
|
||||||
expect(res.message).to.equal(i18n.t('messageBought', {
|
expect(message).to.equal(i18n.t('messageBought', {
|
||||||
itemText: item.text(),
|
itemText: item.text(),
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -46,14 +46,12 @@ describe('shared.ops.changeClass', () => {
|
|||||||
user.stats.class = 'healer';
|
user.stats.class = 'healer';
|
||||||
user.items.gear.owned.armor_rogue_1 = true; // eslint-disable-line camelcase
|
user.items.gear.owned.armor_rogue_1 = true; // eslint-disable-line camelcase
|
||||||
|
|
||||||
let res = changeClass(user, {query: {class: 'rogue'}});
|
let [data] = changeClass(user, {query: {class: 'rogue'}});
|
||||||
expect(res).to.eql({
|
expect(data).to.eql({
|
||||||
data: {
|
|
||||||
preferences: user.preferences,
|
preferences: user.preferences,
|
||||||
stats: user.stats,
|
stats: user.stats,
|
||||||
flags: user.flags,
|
flags: user.flags,
|
||||||
items: user.items,
|
items: user.items,
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(user.stats.class).to.equal('rogue');
|
expect(user.stats.class).to.equal('rogue');
|
||||||
@@ -80,14 +78,12 @@ describe('shared.ops.changeClass', () => {
|
|||||||
user.stats.int = 4;
|
user.stats.int = 4;
|
||||||
user.flags.classSelected = true;
|
user.flags.classSelected = true;
|
||||||
|
|
||||||
let res = changeClass(user);
|
let [data] = changeClass(user);
|
||||||
expect(res).to.eql({
|
expect(data).to.eql({
|
||||||
data: {
|
|
||||||
preferences: user.preferences,
|
preferences: user.preferences,
|
||||||
stats: user.stats,
|
stats: user.stats,
|
||||||
flags: user.flags,
|
flags: user.flags,
|
||||||
items: user.items,
|
items: user.items,
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(user.preferences.disableClasses).to.be.false;
|
expect(user.preferences.disableClasses).to.be.false;
|
||||||
@@ -122,14 +118,12 @@ describe('shared.ops.changeClass', () => {
|
|||||||
user.stats.int = 4;
|
user.stats.int = 4;
|
||||||
user.flags.classSelected = true;
|
user.flags.classSelected = true;
|
||||||
|
|
||||||
let res = changeClass(user);
|
let [data] = changeClass(user);
|
||||||
expect(res).to.eql({
|
expect(data).to.eql({
|
||||||
data: {
|
|
||||||
preferences: user.preferences,
|
preferences: user.preferences,
|
||||||
stats: user.stats,
|
stats: user.stats,
|
||||||
flags: user.flags,
|
flags: user.flags,
|
||||||
items: user.items,
|
items: user.items,
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(user.balance).to.equal(0.25);
|
expect(user.balance).to.equal(0.25);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ describe('shared.ops.clearPMs', () => {
|
|||||||
|
|
||||||
it('clears messages', () => {
|
it('clears messages', () => {
|
||||||
expect(user.inbox.messages).to.not.eql({});
|
expect(user.inbox.messages).to.not.eql({});
|
||||||
let result = clearPMs(user);
|
let [result] = clearPMs(user);
|
||||||
expect(user.inbox.messages).to.eql({});
|
expect(user.inbox.messages).to.eql({});
|
||||||
expect(result).to.eql({});
|
expect(result).to.eql({});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import {
|
|||||||
generateUser,
|
generateUser,
|
||||||
} from '../../helpers/common.helper';
|
} from '../../helpers/common.helper';
|
||||||
|
|
||||||
describe('shared.ops.clearPMs', () => {
|
describe('shared.ops.deletePM', () => {
|
||||||
let user;
|
let user;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -13,7 +13,7 @@ describe('shared.ops.clearPMs', () => {
|
|||||||
|
|
||||||
it('delete message', () => {
|
it('delete message', () => {
|
||||||
expect(user.inbox.messages).to.not.eql({ second: 'message' });
|
expect(user.inbox.messages).to.not.eql({ second: 'message' });
|
||||||
let response = deletePM(user, { params: { id: 'first' } });
|
let [response] = deletePM(user, { params: { id: 'first' } });
|
||||||
expect(user.inbox.messages).to.eql({ second: 'message' });
|
expect(user.inbox.messages).to.eql({ second: 'message' });
|
||||||
expect(response).to.eql({ second: 'message' });
|
expect(response).to.eql({ second: 'message' });
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ describe('shared.ops.deleteWebhook', () => {
|
|||||||
|
|
||||||
it('succeeds', () => {
|
it('succeeds', () => {
|
||||||
user.preferences.webhooks = { 'some-id': {}, 'another-id': {} };
|
user.preferences.webhooks = { 'some-id': {}, 'another-id': {} };
|
||||||
let res = deleteWebhook(user, req);
|
let [data] = deleteWebhook(user, req);
|
||||||
expect(user.preferences.webhooks).to.eql({'another-id': {}});
|
expect(user.preferences.webhooks).to.eql({'another-id': {}});
|
||||||
expect(res).to.equal(user.preferences.webhooks);
|
expect(data).to.equal(user.preferences.webhooks);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -18,13 +18,11 @@ describe('shared.ops.disableClasses', () => {
|
|||||||
user.preferences.autoAllocate = false;
|
user.preferences.autoAllocate = false;
|
||||||
user.stats.points = 2;
|
user.stats.points = 2;
|
||||||
|
|
||||||
let res = disableClasses(user);
|
let [data] = disableClasses(user);
|
||||||
expect(res).to.eql({
|
expect(data).to.eql({
|
||||||
data: {
|
|
||||||
preferences: user.preferences,
|
preferences: user.preferences,
|
||||||
stats: user.stats,
|
stats: user.stats,
|
||||||
flags: user.flags,
|
flags: user.flags,
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(user.stats.class).to.equal('warrior');
|
expect(user.stats.class).to.equal('warrior');
|
||||||
|
|||||||
@@ -37,20 +37,20 @@ describe('shared.ops.equip', () => {
|
|||||||
equip(user, {params: {key: 'weapon_warrior_1'}});
|
equip(user, {params: {key: 'weapon_warrior_1'}});
|
||||||
|
|
||||||
// one-handed to one-handed
|
// one-handed to one-handed
|
||||||
let res = equip(user, {params: {key: 'weapon_warrior_2'}});
|
let [, message] = equip(user, {params: {key: 'weapon_warrior_2'}});
|
||||||
expect(res.message).to.not.exists;
|
expect(message).to.not.exists;
|
||||||
|
|
||||||
// one-handed to two-handed
|
// one-handed to two-handed
|
||||||
res = equip(user, {params: {key: 'weapon_wizard_1'}});
|
[, message] = equip(user, {params: {key: 'weapon_wizard_1'}});
|
||||||
expect(res.message).to.not.exists;
|
expect(message).to.not.exists;
|
||||||
|
|
||||||
// two-handed to two-handed
|
// two-handed to two-handed
|
||||||
res = equip(user, {params: {key: 'weapon_wizard_2'}});
|
[, message] = equip(user, {params: {key: 'weapon_wizard_2'}});
|
||||||
expect(res.message).to.not.exists;
|
expect(message).to.not.exists;
|
||||||
|
|
||||||
// two-handed to one-handed
|
// two-handed to one-handed
|
||||||
res = equip(user, {params: {key: 'weapon_warrior_2'}});
|
[, message] = equip(user, {params: {key: 'weapon_warrior_2'}});
|
||||||
expect(res.message).to.not.exists;
|
expect(message).to.not.exists;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should send messages if equipping a two-hander causes the off-hander to be unequipped', () => {
|
it('should send messages if equipping a two-hander causes the off-hander to be unequipped', () => {
|
||||||
@@ -58,10 +58,11 @@ describe('shared.ops.equip', () => {
|
|||||||
equip(user, {params: {key: 'shield_warrior_1'}});
|
equip(user, {params: {key: 'shield_warrior_1'}});
|
||||||
|
|
||||||
// equipping two-hander
|
// equipping two-hander
|
||||||
let res = equip(user, {params: {key: 'weapon_wizard_1'}});
|
let [data, message] = equip(user, {params: {key: 'weapon_wizard_1'}});
|
||||||
let weapon = content.gear.flat.weapon_wizard_1;
|
let weapon = content.gear.flat.weapon_wizard_1;
|
||||||
let item = content.gear.flat.shield_warrior_1;
|
let item = content.gear.flat.shield_warrior_1;
|
||||||
|
|
||||||
|
let res = {data, message};
|
||||||
expect(res).to.eql({
|
expect(res).to.eql({
|
||||||
message: i18n.t('messageTwoHandedEquip', {twoHandedText: weapon.text(), offHandedText: item.text()}),
|
message: i18n.t('messageTwoHandedEquip', {twoHandedText: weapon.text(), offHandedText: item.text()}),
|
||||||
data: user.items,
|
data: user.items,
|
||||||
@@ -74,8 +75,9 @@ describe('shared.ops.equip', () => {
|
|||||||
let weapon = content.gear.flat.weapon_wizard_1;
|
let weapon = content.gear.flat.weapon_wizard_1;
|
||||||
let shield = content.gear.flat.shield_warrior_1;
|
let shield = content.gear.flat.shield_warrior_1;
|
||||||
|
|
||||||
let res = equip(user, {params: {key: 'shield_warrior_1'}});
|
let [data, message] = equip(user, {params: {key: 'shield_warrior_1'}});
|
||||||
|
|
||||||
|
let res = {data, message};
|
||||||
expect(res).to.eql({
|
expect(res).to.eql({
|
||||||
message: i18n.t('messageTwoHandedUnequip', {twoHandedText: weapon.text(), offHandedText: shield.text()}),
|
message: i18n.t('messageTwoHandedUnequip', {twoHandedText: weapon.text(), offHandedText: shield.text()}),
|
||||||
data: user.items,
|
data: user.items,
|
||||||
|
|||||||
@@ -105,16 +105,14 @@ describe('shared.ops.feed', () => {
|
|||||||
let potionText = content.hatchingPotions[potion] ? content.hatchingPotions[potion].text() : potion;
|
let potionText = content.hatchingPotions[potion] ? content.hatchingPotions[potion].text() : potion;
|
||||||
let eggText = content.eggs[egg] ? content.eggs[egg].text() : egg;
|
let eggText = content.eggs[egg] ? content.eggs[egg].text() : egg;
|
||||||
|
|
||||||
let res = feed(user, {params: {pet: 'Wolf-Base', food: 'Saddle'}});
|
let [data, message] = feed(user, {params: {pet: 'Wolf-Base', food: 'Saddle'}});
|
||||||
expect(res).to.eql({
|
expect(data).to.eql(user.items.pets['Wolf-Base']);
|
||||||
data: user.items.pets['Wolf-Base'],
|
expect(message).to.eql(i18n.t('messageEvolve', {
|
||||||
message: i18n.t('messageEvolve', {
|
|
||||||
egg: i18n.t('petName', {
|
egg: i18n.t('petName', {
|
||||||
potion: potionText,
|
potion: potionText,
|
||||||
egg: eggText,
|
egg: eggText,
|
||||||
}),
|
}),
|
||||||
}),
|
}));
|
||||||
});
|
|
||||||
|
|
||||||
expect(user.items.food.Saddle).to.equal(1);
|
expect(user.items.food.Saddle).to.equal(1);
|
||||||
expect(user.items.pets['Wolf-Base']).to.equal(-1);
|
expect(user.items.pets['Wolf-Base']).to.equal(-1);
|
||||||
@@ -131,17 +129,15 @@ describe('shared.ops.feed', () => {
|
|||||||
let potionText = content.hatchingPotions[potion] ? content.hatchingPotions[potion].text() : potion;
|
let potionText = content.hatchingPotions[potion] ? content.hatchingPotions[potion].text() : potion;
|
||||||
let eggText = content.eggs[egg] ? content.eggs[egg].text() : egg;
|
let eggText = content.eggs[egg] ? content.eggs[egg].text() : egg;
|
||||||
|
|
||||||
let res = feed(user, {params: {pet: 'Wolf-Base', food: 'Meat'}});
|
let [data, message] = feed(user, {params: {pet: 'Wolf-Base', food: 'Meat'}});
|
||||||
expect(res).to.eql({
|
expect(data).to.eql(user.items.pets['Wolf-Base']);
|
||||||
data: user.items.pets['Wolf-Base'],
|
expect(message).to.eql(i18n.t('messageLikesFood', {
|
||||||
message: i18n.t('messageLikesFood', {
|
|
||||||
egg: i18n.t('petName', {
|
egg: i18n.t('petName', {
|
||||||
potion: potionText,
|
potion: potionText,
|
||||||
egg: eggText,
|
egg: eggText,
|
||||||
}),
|
}),
|
||||||
foodText: food.text(),
|
foodText: food.text(),
|
||||||
}),
|
}));
|
||||||
});
|
|
||||||
|
|
||||||
expect(user.items.food.Meat).to.equal(1);
|
expect(user.items.food.Meat).to.equal(1);
|
||||||
expect(user.items.pets['Wolf-Base']).to.equal(10);
|
expect(user.items.pets['Wolf-Base']).to.equal(10);
|
||||||
@@ -156,17 +152,15 @@ describe('shared.ops.feed', () => {
|
|||||||
let potionText = content.hatchingPotions[potion] ? content.hatchingPotions[potion].text() : potion;
|
let potionText = content.hatchingPotions[potion] ? content.hatchingPotions[potion].text() : potion;
|
||||||
let eggText = content.eggs[egg] ? content.eggs[egg].text() : egg;
|
let eggText = content.eggs[egg] ? content.eggs[egg].text() : egg;
|
||||||
|
|
||||||
let res = feed(user, {params: {pet: 'Wolf-Spooky', food: 'Milk'}});
|
let [data, message] = feed(user, {params: {pet: 'Wolf-Spooky', food: 'Milk'}});
|
||||||
expect(res).to.eql({
|
expect(data).to.eql(user.items.pets['Wolf-Spooky']);
|
||||||
data: user.items.pets['Wolf-Spooky'],
|
expect(message).to.eql(i18n.t('messageLikesFood', {
|
||||||
message: i18n.t('messageLikesFood', {
|
|
||||||
egg: i18n.t('petName', {
|
egg: i18n.t('petName', {
|
||||||
potion: potionText,
|
potion: potionText,
|
||||||
egg: eggText,
|
egg: eggText,
|
||||||
}),
|
}),
|
||||||
foodText: food.text(),
|
foodText: food.text(),
|
||||||
}),
|
}));
|
||||||
});
|
|
||||||
|
|
||||||
expect(user.items.food.Milk).to.equal(1);
|
expect(user.items.food.Milk).to.equal(1);
|
||||||
expect(user.items.pets['Wolf-Spooky']).to.equal(10);
|
expect(user.items.pets['Wolf-Spooky']).to.equal(10);
|
||||||
@@ -181,17 +175,15 @@ describe('shared.ops.feed', () => {
|
|||||||
let potionText = content.hatchingPotions[potion] ? content.hatchingPotions[potion].text() : potion;
|
let potionText = content.hatchingPotions[potion] ? content.hatchingPotions[potion].text() : potion;
|
||||||
let eggText = content.eggs[egg] ? content.eggs[egg].text() : egg;
|
let eggText = content.eggs[egg] ? content.eggs[egg].text() : egg;
|
||||||
|
|
||||||
let res = feed(user, {params: {pet: 'Wolf-Base', food: 'Milk'}});
|
let [data, message] = feed(user, {params: {pet: 'Wolf-Base', food: 'Milk'}});
|
||||||
expect(res).to.eql({
|
expect(data).to.eql(user.items.pets['Wolf-Base']);
|
||||||
data: user.items.pets['Wolf-Base'],
|
expect(message).to.eql(i18n.t('messageDontEnjoyFood', {
|
||||||
message: i18n.t('messageDontEnjoyFood', {
|
|
||||||
egg: i18n.t('petName', {
|
egg: i18n.t('petName', {
|
||||||
potion: potionText,
|
potion: potionText,
|
||||||
egg: eggText,
|
egg: eggText,
|
||||||
}),
|
}),
|
||||||
foodText: food.text(),
|
foodText: food.text(),
|
||||||
}),
|
}));
|
||||||
});
|
|
||||||
|
|
||||||
expect(user.items.food.Milk).to.equal(1);
|
expect(user.items.food.Milk).to.equal(1);
|
||||||
expect(user.items.pets['Wolf-Base']).to.equal(7);
|
expect(user.items.pets['Wolf-Base']).to.equal(7);
|
||||||
@@ -206,16 +198,14 @@ describe('shared.ops.feed', () => {
|
|||||||
let potionText = content.hatchingPotions[potion] ? content.hatchingPotions[potion].text() : potion;
|
let potionText = content.hatchingPotions[potion] ? content.hatchingPotions[potion].text() : potion;
|
||||||
let eggText = content.eggs[egg] ? content.eggs[egg].text() : egg;
|
let eggText = content.eggs[egg] ? content.eggs[egg].text() : egg;
|
||||||
|
|
||||||
let res = feed(user, {params: {pet: 'Wolf-Base', food: 'Milk'}});
|
let [data, message] = feed(user, {params: {pet: 'Wolf-Base', food: 'Milk'}});
|
||||||
expect(res).to.eql({
|
expect(data).to.eql(user.items.pets['Wolf-Base']);
|
||||||
data: user.items.pets['Wolf-Base'],
|
expect(message).to.eql(i18n.t('messageEvolve', {
|
||||||
message: i18n.t('messageEvolve', {
|
|
||||||
egg: i18n.t('petName', {
|
egg: i18n.t('petName', {
|
||||||
potion: potionText,
|
potion: potionText,
|
||||||
egg: eggText,
|
egg: eggText,
|
||||||
}),
|
}),
|
||||||
}),
|
}));
|
||||||
});
|
|
||||||
|
|
||||||
expect(user.items.food.Milk).to.equal(1);
|
expect(user.items.food.Milk).to.equal(1);
|
||||||
expect(user.items.pets['Wolf-Base']).to.equal(-1);
|
expect(user.items.pets['Wolf-Base']).to.equal(-1);
|
||||||
|
|||||||
@@ -99,9 +99,9 @@ describe('shared.ops.hatch', () => {
|
|||||||
user.items.eggs = {Wolf: 1};
|
user.items.eggs = {Wolf: 1};
|
||||||
user.items.hatchingPotions = {Base: 1};
|
user.items.hatchingPotions = {Base: 1};
|
||||||
user.items.pets = {};
|
user.items.pets = {};
|
||||||
let res = hatch(user, {params: {egg: 'Wolf', hatchingPotion: 'Base'}});
|
let [data, message] = hatch(user, {params: {egg: 'Wolf', hatchingPotion: 'Base'}});
|
||||||
expect(res.message).to.equal(i18n.t('messageHatched'));
|
expect(message).to.equal(i18n.t('messageHatched'));
|
||||||
expect(res.data).to.eql(user.items);
|
expect(data).to.eql(user.items);
|
||||||
expect(user.items.pets).to.eql({'Wolf-Base': 5});
|
expect(user.items.pets).to.eql({'Wolf-Base': 5});
|
||||||
expect(user.items.eggs).to.eql({Wolf: 0});
|
expect(user.items.eggs).to.eql({Wolf: 0});
|
||||||
expect(user.items.hatchingPotions).to.eql({Base: 0});
|
expect(user.items.hatchingPotions).to.eql({Base: 0});
|
||||||
@@ -111,9 +111,9 @@ describe('shared.ops.hatch', () => {
|
|||||||
user.items.eggs = {Cheetah: 1};
|
user.items.eggs = {Cheetah: 1};
|
||||||
user.items.hatchingPotions = {Base: 1};
|
user.items.hatchingPotions = {Base: 1};
|
||||||
user.items.pets = {};
|
user.items.pets = {};
|
||||||
let res = hatch(user, {params: {egg: 'Cheetah', hatchingPotion: 'Base'}});
|
let [data, message] = hatch(user, {params: {egg: 'Cheetah', hatchingPotion: 'Base'}});
|
||||||
expect(res.message).to.equal(i18n.t('messageHatched'));
|
expect(message).to.equal(i18n.t('messageHatched'));
|
||||||
expect(res.data).to.eql(user.items);
|
expect(data).to.eql(user.items);
|
||||||
expect(user.items.pets).to.eql({'Cheetah-Base': 5});
|
expect(user.items.pets).to.eql({'Cheetah-Base': 5});
|
||||||
expect(user.items.eggs).to.eql({Cheetah: 0});
|
expect(user.items.eggs).to.eql({Cheetah: 0});
|
||||||
expect(user.items.hatchingPotions).to.eql({Base: 0});
|
expect(user.items.hatchingPotions).to.eql({Base: 0});
|
||||||
@@ -123,9 +123,9 @@ describe('shared.ops.hatch', () => {
|
|||||||
user.items.eggs = {Wolf: 1};
|
user.items.eggs = {Wolf: 1};
|
||||||
user.items.hatchingPotions = {Spooky: 1};
|
user.items.hatchingPotions = {Spooky: 1};
|
||||||
user.items.pets = {};
|
user.items.pets = {};
|
||||||
let res = hatch(user, {params: {egg: 'Wolf', hatchingPotion: 'Spooky'}});
|
let [data, message] = hatch(user, {params: {egg: 'Wolf', hatchingPotion: 'Spooky'}});
|
||||||
expect(res.message).to.equal(i18n.t('messageHatched'));
|
expect(message).to.equal(i18n.t('messageHatched'));
|
||||||
expect(res.data).to.eql(user.items);
|
expect(data).to.eql(user.items);
|
||||||
expect(user.items.pets).to.eql({'Wolf-Spooky': 5});
|
expect(user.items.pets).to.eql({'Wolf-Spooky': 5});
|
||||||
expect(user.items.eggs).to.eql({Wolf: 0});
|
expect(user.items.eggs).to.eql({Wolf: 0});
|
||||||
expect(user.items.hatchingPotions).to.eql({Spooky: 0});
|
expect(user.items.hatchingPotions).to.eql({Spooky: 0});
|
||||||
@@ -135,9 +135,9 @@ describe('shared.ops.hatch', () => {
|
|||||||
user.items.eggs = {Wolf: 1};
|
user.items.eggs = {Wolf: 1};
|
||||||
user.items.hatchingPotions = {Base: 1};
|
user.items.hatchingPotions = {Base: 1};
|
||||||
user.items.pets = {'Wolf-Base': -1};
|
user.items.pets = {'Wolf-Base': -1};
|
||||||
let res = hatch(user, {params: {egg: 'Wolf', hatchingPotion: 'Base'}});
|
let [data, message] = hatch(user, {params: {egg: 'Wolf', hatchingPotion: 'Base'}});
|
||||||
expect(res.message).to.eql(i18n.t('messageHatched'));
|
expect(message).to.eql(i18n.t('messageHatched'));
|
||||||
expect(res.data).to.eql(user.items);
|
expect(data).to.eql(user.items);
|
||||||
expect(user.items.pets).to.eql({'Wolf-Base': 5});
|
expect(user.items.pets).to.eql({'Wolf-Base': 5});
|
||||||
expect(user.items.eggs).to.eql({Wolf: 0});
|
expect(user.items.eggs).to.eql({Wolf: 0});
|
||||||
expect(user.items.hatchingPotions).to.eql({Base: 0});
|
expect(user.items.hatchingPotions).to.eql({Base: 0});
|
||||||
|
|||||||
@@ -126,9 +126,9 @@ describe('user.ops.hourglassPurchase', () => {
|
|||||||
it('buys a pet', () => {
|
it('buys a pet', () => {
|
||||||
user.purchased.plan.consecutive.trinkets = 2;
|
user.purchased.plan.consecutive.trinkets = 2;
|
||||||
|
|
||||||
let response = hourglassPurchase(user, {params: {type: 'pets', key: 'MantisShrimp-Base'}});
|
let [, message] = hourglassPurchase(user, {params: {type: 'pets', key: 'MantisShrimp-Base'}});
|
||||||
|
|
||||||
expect(response.message).to.eql(i18n.t('hourglassPurchase'));
|
expect(message).to.eql(i18n.t('hourglassPurchase'));
|
||||||
expect(user.purchased.plan.consecutive.trinkets).to.eql(1);
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(1);
|
||||||
expect(user.items.pets).to.eql({'MantisShrimp-Base': 5});
|
expect(user.items.pets).to.eql({'MantisShrimp-Base': 5});
|
||||||
});
|
});
|
||||||
@@ -136,8 +136,8 @@ describe('user.ops.hourglassPurchase', () => {
|
|||||||
it('buys a mount', () => {
|
it('buys a mount', () => {
|
||||||
user.purchased.plan.consecutive.trinkets = 2;
|
user.purchased.plan.consecutive.trinkets = 2;
|
||||||
|
|
||||||
let response = hourglassPurchase(user, {params: {type: 'mounts', key: 'MantisShrimp-Base'}});
|
let [, message] = hourglassPurchase(user, {params: {type: 'mounts', key: 'MantisShrimp-Base'}});
|
||||||
expect(response.message).to.eql(i18n.t('hourglassPurchase'));
|
expect(message).to.eql(i18n.t('hourglassPurchase'));
|
||||||
expect(user.purchased.plan.consecutive.trinkets).to.eql(1);
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(1);
|
||||||
expect(user.items.mounts).to.eql({'MantisShrimp-Base': true});
|
expect(user.items.mounts).to.eql({'MantisShrimp-Base': true});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -29,10 +29,10 @@ describe('shared.ops.openMysteryItem', () => {
|
|||||||
|
|
||||||
user.purchased.plan.mysteryItems = [mysteryItemKey];
|
user.purchased.plan.mysteryItems = [mysteryItemKey];
|
||||||
|
|
||||||
let response = openMysteryItem(user);
|
let [data, message] = openMysteryItem(user);
|
||||||
|
|
||||||
expect(user.items.gear.owned[mysteryItemKey]).to.be.true;
|
expect(user.items.gear.owned[mysteryItemKey]).to.be.true;
|
||||||
expect(response.message).to.equal(i18n.t('mysteryItemOpened'));
|
expect(message).to.equal(i18n.t('mysteryItemOpened'));
|
||||||
expect(response.data).to.equal(user.items.gear.owned);
|
expect(data).to.equal(user.items.gear.owned);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
generateUser,
|
generateUser,
|
||||||
} from '../../helpers/common.helper';
|
} from '../../helpers/common.helper';
|
||||||
|
|
||||||
describe('shared.ops.feed', () => {
|
describe('shared.ops.purchase', () => {
|
||||||
let user;
|
let user;
|
||||||
let goldPoints = 40;
|
let goldPoints = 40;
|
||||||
let gemsBought = 40;
|
let gemsBought = 40;
|
||||||
@@ -128,7 +128,7 @@ describe('shared.ops.feed', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
context('successful feeding', () => {
|
context('successful purchase', () => {
|
||||||
let userGemAmount = 10;
|
let userGemAmount = 10;
|
||||||
|
|
||||||
before(() => {
|
before(() => {
|
||||||
@@ -138,9 +138,9 @@ describe('shared.ops.feed', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('purchases gems', () => {
|
it('purchases gems', () => {
|
||||||
let purchaseResponse = purchase(user, {params: {type: 'gems', key: 'gem'}});
|
let [, message] = purchase(user, {params: {type: 'gems', key: 'gem'}});
|
||||||
|
|
||||||
expect(purchaseResponse.message).to.equal(i18n.t('plusOneGem'));
|
expect(message).to.equal(i18n.t('plusOneGem'));
|
||||||
expect(user.balance).to.equal(userGemAmount + 0.25);
|
expect(user.balance).to.equal(userGemAmount + 0.25);
|
||||||
expect(user.purchased.plan.gemsBought).to.equal(1);
|
expect(user.purchased.plan.gemsBought).to.equal(1);
|
||||||
expect(user.stats.gp).to.equal(goldPoints - planGemLimits.convRate);
|
expect(user.stats.gp).to.equal(goldPoints - planGemLimits.convRate);
|
||||||
@@ -150,9 +150,9 @@ describe('shared.ops.feed', () => {
|
|||||||
let type = 'eggs';
|
let type = 'eggs';
|
||||||
let key = 'Wolf';
|
let key = 'Wolf';
|
||||||
|
|
||||||
let purchaseResponse = purchase(user, {params: {type, key}});
|
let [, message] = purchase(user, {params: {type, key}});
|
||||||
|
|
||||||
expect(purchaseResponse.message).to.equal(i18n.t('purchased', {type, key}));
|
expect(message).to.equal(i18n.t('purchased', {type, key}));
|
||||||
expect(user.items[type][key]).to.equal(1);
|
expect(user.items[type][key]).to.equal(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -160,9 +160,9 @@ describe('shared.ops.feed', () => {
|
|||||||
let type = 'hatchingPotions';
|
let type = 'hatchingPotions';
|
||||||
let key = 'Base';
|
let key = 'Base';
|
||||||
|
|
||||||
let purchaseResponse = purchase(user, {params: {type, key}});
|
let [, message] = purchase(user, {params: {type, key}});
|
||||||
|
|
||||||
expect(purchaseResponse.message).to.equal(i18n.t('purchased', {type, key}));
|
expect(message).to.equal(i18n.t('purchased', {type, key}));
|
||||||
expect(user.items[type][key]).to.equal(1);
|
expect(user.items[type][key]).to.equal(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -170,9 +170,9 @@ describe('shared.ops.feed', () => {
|
|||||||
let type = 'food';
|
let type = 'food';
|
||||||
let key = 'Meat';
|
let key = 'Meat';
|
||||||
|
|
||||||
let purchaseResponse = purchase(user, {params: {type, key}});
|
let [, message] = purchase(user, {params: {type, key}});
|
||||||
|
|
||||||
expect(purchaseResponse.message).to.equal(i18n.t('purchased', {type, key}));
|
expect(message).to.equal(i18n.t('purchased', {type, key}));
|
||||||
expect(user.items[type][key]).to.equal(1);
|
expect(user.items[type][key]).to.equal(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -180,9 +180,9 @@ describe('shared.ops.feed', () => {
|
|||||||
let type = 'quests';
|
let type = 'quests';
|
||||||
let key = 'gryphon';
|
let key = 'gryphon';
|
||||||
|
|
||||||
let purchaseResponse = purchase(user, {params: {type, key}});
|
let [, message] = purchase(user, {params: {type, key}});
|
||||||
|
|
||||||
expect(purchaseResponse.message).to.equal(i18n.t('purchased', {type, key}));
|
expect(message).to.equal(i18n.t('purchased', {type, key}));
|
||||||
expect(user.items[type][key]).to.equal(1);
|
expect(user.items[type][key]).to.equal(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -190,9 +190,9 @@ describe('shared.ops.feed', () => {
|
|||||||
let type = 'gear';
|
let type = 'gear';
|
||||||
let key = 'headAccessory_special_tigerEars';
|
let key = 'headAccessory_special_tigerEars';
|
||||||
|
|
||||||
let purchaseResponse = purchase(user, {params: {type, key}});
|
let [, message] = purchase(user, {params: {type, key}});
|
||||||
|
|
||||||
expect(purchaseResponse.message).to.equal(i18n.t('purchased', {type, key}));
|
expect(message).to.equal(i18n.t('purchased', {type, key}));
|
||||||
expect(user.items.gear.owned[key]).to.be.true;
|
expect(user.items.gear.owned[key]).to.be.true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ describe('shared.ops.readCard', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('reads a card', () => {
|
it('reads a card', () => {
|
||||||
let response = readCard(user, {params: {cardType: 'greeting'}});
|
let [, message] = readCard(user, {params: {cardType: 'greeting'}});
|
||||||
|
|
||||||
expect(response.message).to.equal(i18n.t('readCard', {cardType}));
|
expect(message).to.equal(i18n.t('readCard', {cardType}));
|
||||||
expect(user.items.special[`${cardType}Received`]).to.be.empty;
|
expect(user.items.special[`${cardType}Received`]).to.be.empty;
|
||||||
expect(user.flags.cardReceived).to.be.false;
|
expect(user.flags.cardReceived).to.be.false;
|
||||||
});
|
});
|
||||||
|
|||||||