API v3 [WIP] (#6144)

* Fixed more tests

* Added tags into user service

* Added api-v3 auth urls

* v3: fix package.json

* v3: fix package.json

* Fixed auth tests. Updated Authctrl response

* v3: remove newrelic config file in favour of env variables

* v3: upgrade some deps

* switch from Q to Bluebird

* v3 fix tests with deferred

* Removed extra consoles.log. Changed data.data to res.data

* v3 fix tests and use coroutines instead of regenerator

* v3: fix tests

* v3: do not await a non promise

* v3: q -> bluebird

* Changed id param for registration response

* Updated party query and create

* Ensured login callback happens after user sync

* Add challenges to groups. Fixed isMemberOfGuild check

* Updated party and group tests

* Fixed cron test

* return user.id and send analytics event before changing page

* fix trailing spaces

* disable redirects

* Api v3 party tavern fixes (#7191)

* Added check if user is in party before query

* Cached party query. Prevented party request when user is not in party. Updated Party create with no invites

* Update tavern ctrl to use new promise

* v3: misc fixes

* Api v3 task fixes (#7193)

* Update task view to use _id

* Added try catch to user service ops calls

* v3 client: saving after syncing is complete

* Fixed test broken by part sync change (#7195)

* v3: fix todo scoring and try to fix production testing problem

* revert changes to mongoose config

* mongoose: increase keepAlive

* test mongoose fix

* fix: Only apply captureStackTrace if it exists on the error object

* v3: fix reminders with no startDate

* mongoose: use options

* chore(): rename website/src -> website/server and website/public -> website/client (#7199)

* v3 fix GET /groups: return an error only if an invalid type is supplied not when there are 0 results (#7203)

* [API v3] Fix calls to user.ops and deleting tags (#7204)

* v3: fixes calls to user.ops from views and deleting tags

* v3: fix tests that use user._statsComputed

* Api v3 fixes continued (#7205)

* Added timzeone offset back

* Added APIToken back to settings page

* Fixed fetch recent messages for party

* Fixed returning group description

* Fixed check if user is member of challenge

* Fixed party members appearing in header

* Updated get myGroups param to include public groups. Fixed isMemberOf group

* Fixed hourglass purchase

* Fixed challenge addding tasks on first creating

* Updated tests to accomidate new changes

* fix: Correct checklist on client

Closes #7207

* fix: Pin eslint to 2.9

* minor improvements to cron code for clarity; fix inaccurate comments; add TODOs for rest-in-inn actions

* fix: Add missing type param to equip call

closes #7212

* rename and reword pubChalsMinPrize to reflect that it's only for Tavern challenges

* allows players to send gems to each other; other minor related changes - fixes https://github.com/HabitRPG/habitrpg/issues/7227

* fix tests for /members/transfer-gems

* fix: Set gems sent notification as translatable string

* chore: Remove unusued variable

* fix: Remove requirement on message paramter in transfer-gems

* add a missing variable declaration

* chore: clarify comments on cron code

* fix: Correct client request from habitrpg -> tavern

* update apidoc URL in package.json

Closes #7222

* Fixed start party by invites

* Updated spell casting to v3

* Fixed adding and removing tags on tasks

* Fixed page reload on settings change

* Fixed battle monsters with friends button

* Loaded completed todos when done is clicked

* chore: Reinstate floating version number for eslint

babel-eslint regression fixed

* Fixed reload tests

* change "an user" to "a user" in comments and text (no code changes) (#7257)

* fix: Alert user that drops were recieved

* remove userServices.js from karma.conf - it's been moved to website/client/js/services

* feat: Create debug update user route

* fix: Correct set cron debug function

* feat: Add make admin button to debug menu

* lint: Add missing semicolons in test

* fix: Temporarilly comment out udpate user debug route

* v3: fix _tmp for crit and streakBonus

* v3: execute all actions when leaving a solo party

* v3 client: fix group not found when leaving party

* v3 migration: fix challenge prize

* v3 cron: only save modified tasks

* v3: add CHALLENGE_TASK_NOT_FOUND to valid broken reasons

* v3: fix tasks chart

* v3 client: fix ability to leave challenge

* v3 client: fix filtering by tag and correctly show tag tooltip

* v3 common: fix tags tests

* v3 client: support unlinking not found challenges tasks

* v3: disable Bluebird warning for missing return, fixes #7269

* feat: Separate out update-user into set-cron and make-admin debug routes

* chore: Disable make admin debug route for v3 prod testing

* v3: misc fixes

* v3: misc fixes

* v3: fix adding multiple tasks

* Fixed join/leave button updates

* Queried only user groups to be available when creating challenges

* Fixed bulk add tasks to challenge

* Synced challenge tasks after leave and join.

* Fixed default selected group

* Fixed challenge member info. Fixed challenge winner selection

* Fixed deleting challenge tasks

* Fixed particiapting filter

* v3 client: fix casting spells

* v3: do not log sensitive data

* v3: always save user when casting spell

* v3: always save user when casting spell

* v3: more fixes for spells

* fix typos and missing information in apidocs - fixes https://github.com/HabitRPG/habitrpg/issues/7277 (#7282)

* v3: add TODO for client side spells

* feat: Add modify inventory debug menu

* Fixed viewing user progress on challenge

* Updated tests

* fix: Fix quest progress button

* fix incorrect Armoire test; remove unneeded param details from apidocs; disambiguate health potion

* v3: fix stealth casting

* v3: fix tasks saving and selection for rebirth reroll and reset (server-only)

* v3: fix auto allocation

* v3 client: misc fixes

* rename buyPotion and buy-potion to buyHealthPotion and buy-health-potion; fix apidoc param error

* Added delete for saved challenge task

* Fixed member modal on front page

* adjust text in apidocs for errors / clarity / consistency / standard terminology (no code changes) (#7298)

* fix bug in Rebirth test, add new tests, adjust apidocs (#7293)

* Updated task model to allow setting streak (#7306)

* fix: Correct missing * in apidoc comments

* Api v3 challenge fixes (#7287)

* Fixed join/leave button updates

* Queried only user groups to be available when creating challenges

* Fixed bulk add tasks to challenge

* Synced challenge tasks after leave and join.

* Fixed default selected group

* Fixed challenge member info. Fixed challenge winner selection

* Fixed deleting challenge tasks

* Fixed particiapting filter

* Fixed viewing user progress on challenge

* Updated tests

* Added delete for saved challenge task

* v3: fix sorting

* [API v3] add CRON_SAFE_MODE (#7286)

* add CRON_SAFE_MODE to example config file, fix some bugs, add an unrelated low-priority TODO

* create CRON_SAFE_MODE to disable parts of cron for use after extended outage - fixes https://github.com/HabitRPG/habitrpg/issues/7161

* fix a bug with CRON_SAFE_MODE, remove duplicated code, remove completed TODO comment

* fix check for CRON_SAFE_MODE

* v3 client: fix typo

* adjust debug menu Modify Inventory: hungrier pets, fewer Special items, "Hide" buttons

* completed To-Dos: return the 30 most recent instead of 30 oldest (#7318)

* v3 migration: fix createdAt date

* adjust locales text, key names, and files for Rebirth, Reset, and Fortify / ReRoll for consistency with existing strings (#7321)

* v3: fix unlinking multiple tasks

* v3 fix releasing pets

* v3: fix authenticating with apiUrl

* v3: fix typo

* v3 fix client tests for unlinking

* v3 client: do not show start quest button when quest is active

* v3 client: fix ability to send cards

* v3 client: fix misc challenge issues

* v3: fix notifications

* v3 client: more user friendly errors

* v3 client: only load completed todos once

* v3 client: fix tests

* v3: move TAVERN_ID to common code

* fix: Provide default type and text for new task creation in score route

* fix: Provide default history [] for habit in score route

* fix: Add _legacyId prop to tasks to support non-uuid identifiers

* chore: Change v3 migration to use _legacyId instead of legacyId

* fix: check for _legacyId in tasks if id does not exist

* refactor: Extract out finding task by id or _legacyId into a function

* Api v3 party quest fixes (#7341)

* Fix display of add challenge message when group challenges are empty

* Fixed forced quest start to update quest without reload

* Fixed needing to reload when accepting party invite

* Fix group leave and join reload

* Fixed leave current party and join another

* Updated party tests

* v3 client: remove console.log statement

* v3: misc fixes

* v3 client: fix predicatbale random

* v3: info about API v3

* v3: update footer with links to developer resources

* v3: support party invitation from email

* v3 client: fix chat flagging

* fix: Correct get tasks route to properly get todos (#7349)

* move locales strings from api-v3.json to other locales files (#7347)

* move locales strings from api-v3.json: authentication strings -> front.json

* move locales strings from api-v3.json: authentication strings -> tasks.json

* move locales strings from api-v3.json: authentication strings -> groups.json

* move locales strings from api-v3.json: authentication strings -> challenge.json

* move locales strings from api-v3.json: authentication strings -> groups.json (again)

* move locales strings from api-v3.json: authentication strings -> quests.json

* move locales strings from api-v3.json: authentication strings -> subscriber.json

* move locales strings from api-v3.json: authentication strings -> spells.json

* move locales strings from api-v3.json: authentication strings -> character.json

* move locales strings from api-v3.json: authentication strings -> groups.json (PMs)

* move locales strings from api-v3.json: authentication strings -> npc.json

* move locales strings from api-v3.json: authentication strings -> pets.json

* move locales strings from api-v3.json: authentication strings -> miscellaneous

* move locales strings from api-v3.json: authentication strings -> contrib.json and settings.json

* move locales strings from api-v3.json: delete unused string (invalidTasksOwner), delete api-v3.json, whitespace cleanup

* v3 client: fix sticky header

* v3: remove unused code

* v3 client: correctly redirect after inviting

* Removed v2 calls from views (#7351)

* v3: fix tests for challenge export

* v3: fallbackto authWithHeaders if wuthWithSession or authWithUrl fails

* Added force cache update when fetching new messages (#7360)

* v3: fetch whole user when booting from group tto avoid issues with pre save hook expecting all data

* v3: misc fixes for payments

* v3: limit fields of challenge tasks that can be updated

* fix(tests): never connect to NODE_DB_URI for tests

* Added new route for setting last cron and updated front end

* v3: fix iap url

* v3: fix build and ios IAP

* Changed route to user set custom day start

* v3: iap accessible under /api/v3, fixes to spells and groups invitations

* v3: correctly use v3 routes in client

* remove XP, GP when unticking a Daily with a completed checklist - fixes https://github.com/HabitRPG/habitrpg/issues/7246

* use natural language for error message about skills on challenge tasks (#7336), fix other gramatical error

* Updated ui when user rejects a guild invite (#7368)

* feat: complete custom day start route

Closes #7363

* fix: Correct spelling of healAll skill

fix: Correct sprite name of healAll skill

* fix: Change all instances of spookDust -> spookySparkles

* add dateCreated to all tasks; add empty challenge object to tasks that don't have one (#7386)

* add plumilla to artists for Tangle Tree in Bailey message

* Fixed quest drop modal (#7377)

* Fixed quest drop modal

* Fixed broken party test

* [API v3] Maintenance Mode (#7367)

* WIP(maintenance): maintenance

* WIP(maintenance): working locale features

* fix(maintenance): don't translate info page target

* WIP(maintenance): start adding info page

* fix(maintenance): linting

* feat: Add container to maintenance info page

* fix(maintenance): add config.json edits
Also DRY variables for main vs info pages

* fix(maintenance): linting

* refactor(maintenance): further slim down variables

* refactor: Remove unnecessary variables

* fix: Correct string interpolation in maintenace view

* feat: Dynamically add time to maintenance pages

* maintenance mode: do not connect to mongodb

* fix(maintenance): clean up timezones etc.

* fix(maintenance): remove unneeded sprite

* Tavern party challenges invites fix (#7394)

* Added challenges and invitations to party

* Loaded tavern challenges

* Updated group and quest services tests

* v3: implement automatic syncing if user is not up to date

* Removed unnecessary fields when updating groups and challenges (#7395)

* v3: do not saved populated user

* v3: correctly return user subset

* Chained party promises together (#7396)

* v3: $w -> splitWhitespace

* use bluebird

* use babel polyfill

* migration: fix items

* update links for v3

* Updated shortname validation to support multiple browsers

* Docs changes (#7401)

* chore: Clarify transfer-gems documentation

* chore: Clarify api status route documentation

* chore: Mark webhooks as BETA

* Added tags update route. Added sort to user service (#7381)

* Added tags update route. Added sort to user service

* Change update tasks route to reorder tasks

* Fixed linting issue

* Changed params for reorder tags route

* Fixed not found tag and added test

* Added password confirmation when deleteing account (#7402)

* fix production logging

* feat(commit): push

* empty commit

* feat(maintenance): post-downtime news & awards (#7406)

* fix exporting avatar

* second attempt at fixing exporting avatar

* fix production logging

* s3: convert moment to date instance

* fix avatar sharing and caching (30 minutes)

* fix: Correct missing parameter

Closes #7433

* fix: Validate challenge shortname on server

* adjust text strings - fixes https://github.com/HabitRPG/habitrpg/issues/5631 and also Short Name -> Tag Name
This commit is contained in:
Matteo Pagliazzi
2016-05-23 13:58:31 +02:00
parent ef3a2fc286
commit 28f2e9c356
993 changed files with 44888 additions and 12883 deletions
+86
View File
@@ -0,0 +1,86 @@
import autoAllocate from '../../../common/script/fns/autoAllocate';
import {
generateUser,
} from '../../helpers/common.helper';
describe('shared.fns.autoAllocate', () => {
let user;
beforeEach(() => {
user = generateUser();
});
it('user.preferences.allocationMode === flat', () => {
user.stats.con = 5;
user.stats.int = 5;
user.stats.per = 3;
user.stats.str = 8;
user.preferences.allocationMode = 'flat';
autoAllocate(user);
expect(user.stats.con).to.equal(5);
expect(user.stats.int).to.equal(5);
expect(user.stats.per).to.equal(4);
expect(user.stats.str).to.equal(8);
});
it('user.preferences.allocationMode === taskbased', () => {
user.stats.con = 5;
user.stats.int = 5;
user.stats.per = 3;
user.stats.str = 8;
user.stats.training.con = 2;
user.stats.training.int = 5;
user.stats.training.per = 7;
user.stats.training.str = 4;
user.preferences.allocationMode = 'taskbased';
autoAllocate(user);
expect(user.stats.con).to.equal(5);
expect(user.stats.int).to.equal(5);
expect(user.stats.per).to.equal(4);
expect(user.stats.str).to.equal(8);
expect(user.stats.training.con).to.equal(0);
expect(user.stats.training.int).to.equal(0);
expect(user.stats.training.per).to.equal(0);
expect(user.stats.training.str).to.equal(0);
});
it('user.preferences.allocationMode === classbased', () => {
user.stats.lvl = 35;
user.stats.class = 'healer';
user.stats.con = 5;
user.stats.int = 5;
user.stats.per = 3;
user.stats.str = 8;
user.preferences.allocationMode = 'classbased';
autoAllocate(user);
expect(user.stats.con).to.equal(6);
expect(user.stats.int).to.equal(5);
expect(user.stats.per).to.equal(3);
expect(user.stats.str).to.equal(8);
});
it('user.preferences.allocationMode === anything', () => {
user.stats.con = 5;
user.stats.int = 5;
user.stats.per = 3;
user.stats.str = 8;
user.preferences.allocationMode = 'wrong';
autoAllocate(user);
expect(user.stats.con).to.equal(5);
expect(user.stats.int).to.equal(5);
expect(user.stats.per).to.equal(3);
expect(user.stats.str).to.equal(9);
});
});
+17
View File
@@ -0,0 +1,17 @@
import crit from '../../../common/script/fns/crit';
import {
generateUser,
} from '../../helpers/common.helper';
describe('crit', () => {
let user;
beforeEach(() => {
user = generateUser();
});
it('computes', () => {
let result = crit(user);
expect(result).to.eql(1);
});
});
+38
View File
@@ -0,0 +1,38 @@
import handleTwoHanded from '../../../common/script/fns/handleTwoHanded';
import content from '../../../common/script/content/index';
import i18n from '../../../common/script/i18n';
import {
generateUser,
} from '../../helpers/common.helper';
describe('shared.fns.handleTwoHanded', () => {
let user;
beforeEach(() => {
user = generateUser();
});
it('uses "messageTwoHandedUnequip" message if item is a shield and current weapon is two handed (and sets the user\'s weapon to the base one)', () => {
let item = content.gear.tree.shield.warrior['2'];
let currentWeapon = content.gear.tree.weapon.armoire.rancherLasso;
user.items.gear.equipped.weapon = 'weapon_armoire_rancherLasso';
let message = handleTwoHanded(user, item);
expect(message).to.equal(i18n.t('messageTwoHandedUnequip', {
twoHandedText: currentWeapon.text(), offHandedText: item.text(),
}));
expect(user.items.gear.equipped.weapon).to.equal('weapon_base_0');
});
it('uses "messageTwoHandedEquip" message if item is two handed and currentShield exists but is not "shield_base_0" (and sets the user\'s shield to the base one)', () => {
let item = content.gear.tree.weapon.armoire.rancherLasso;
let currentShield = content.gear.tree.shield.armoire.gladiatorShield;
user.items.gear.equipped.shield = 'shield_armoire_gladiatorShield';
let message = handleTwoHanded(user, item);
expect(message).to.equal(i18n.t('messageTwoHandedEquip', {
twoHandedText: item.text(), offHandedText: currentShield.text(),
}));
expect(user.items.gear.equipped.shield).to.equal('shield_base_0');
});
});
+51
View File
@@ -0,0 +1,51 @@
import predictableRandom from '../../../common/script/fns/predictableRandom';
import {
generateUser,
} from '../../helpers/common.helper';
describe('shared.fns.predictableRandom', () => {
let user;
beforeEach(() => {
user = generateUser();
});
it('returns a number', () => {
expect(predictableRandom(user)).to.be.a('number');
});
it('returns the same value when user.stats is the same and no seed is passed', () => {
user.stats.hp = 43;
user.stats.gp = 34;
let val1 = predictableRandom(user);
let val2 = predictableRandom(user);
expect(val2).to.equal(val1);
});
it('returns a different value when user.stats is not the same and no seed is passed', () => {
user.stats.hp = 43;
user.stats.gp = 34;
let val1 = predictableRandom(user);
user.stats.gp = 35;
let val2 = predictableRandom(user);
expect(val2).to.not.equal(val1);
});
it('returns the same value when the same seed is passed', () => {
let val1 = predictableRandom(user, 4452673762);
let val2 = predictableRandom(user, 4452673762);
expect(val2).to.equal(val1);
});
it('returns a different value when a different seed is passed', () => {
let val1 = predictableRandom(user, 4452673761);
let val2 = predictableRandom(user, 4452673762);
expect(val2).to.not.equal(val1);
});
});
+165
View 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
});
});
});
});
+119
View File
@@ -0,0 +1,119 @@
import randomVal from '../../../common/script/fns/randomVal';
import {
generateUser,
} from '../../helpers/common.helper';
describe('shared.fns.randomVal', () => {
let user;
let obj = {
a: 1,
b: 2,
c: 3,
d: 4,
};
beforeEach(() => {
user = generateUser();
});
describe('returns a random property value from an object', () => {
it('returns the same value when the seed is the same', () => {
let val1 = randomVal(user, obj, {
seed: 222,
});
let val2 = randomVal(user, obj, {
seed: 222,
});
expect(val2).to.equal(val1);
});
it('returns the same value when user.stats is the same', () => {
user.stats.gp = 34;
let val1 = randomVal(user, obj);
let val2 = randomVal(user, obj);
expect(val2).to.equal(val1);
});
it('returns a different value when the seed is different', () => {
let val1 = randomVal(user, obj, {
seed: 222,
});
let val2 = randomVal(user, obj, {
seed: 333,
});
expect(val2).to.not.equal(val1);
});
it('returns a different value when user.stats is different', () => {
user.stats.gp = 34;
let val1 = randomVal(user, obj);
user.stats.gp = 343;
let val2 = randomVal(user, obj);
expect(val2).to.not.equal(val1);
});
});
describe('returns a random key from an object', () => {
it('returns the same key when the seed is the same', () => {
let key1 = randomVal(user, obj, {
key: true,
seed: 222,
});
let key2 = randomVal(user, obj, {
key: true,
seed: 222,
});
expect(key2).to.equal(key1);
});
it('returns the same key when user.stats is the same', () => {
user.stats.gp = 45;
let key1 = randomVal(user, obj, {
key: true,
});
let key2 = randomVal(user, obj, {
key: true,
});
expect(key2).to.equal(key1);
});
it('returns a different key when the seed is different', () => {
let key1 = randomVal(user, obj, {
key: true,
seed: 222,
});
let key2 = randomVal(user, obj, {
key: true,
seed: 333,
});
expect(key2).to.not.equal(key1);
});
it('returns a different key when user.stats is different', () => {
user.stats.gp = 45;
let key1 = randomVal(user, obj, {
key: true,
});
user.stats.gp = 43;
let key2 = randomVal(user, obj, {
key: true,
});
expect(key2).to.not.equal(key1);
});
});
});
+28
View File
@@ -0,0 +1,28 @@
import statsComputed from '../../../common/script/libs/statsComputed';
import {
generateUser,
} from '../../helpers/common.helper';
describe('common.fns.statsComputed', () => {
let user;
beforeEach(() => {
user = generateUser();
});
it('returns the same result if called directly, through user.fns.statsComputed, or user._statsComputed', () => {
let result = statsComputed(user);
let result2 = user._statsComputed;
let result3 = user.fns.statsComputed();
expect(result).to.eql(result2);
expect(result).to.eql(result3);
});
it('returns default values', () => {
let result = statsComputed(user);
expect(result.per).to.eql(0);
expect(result.con).to.eql(0);
expect(result.str).to.eql(0);
expect(result.maxMP).to.eql(30);
});
});
+33
View File
@@ -0,0 +1,33 @@
import ultimateGear from '../../../common/script/fns/ultimateGear';
import {
generateUser,
} from '../../helpers/common.helper';
describe('shared.fns.ultimateGear', () => {
let user;
beforeEach(() => {
user = generateUser();
});
it('sets armoirEnabled when partial achievement already achieved', () => {
let items = {
gear: {
owned: {
toObject: () => {
return {
armor_warrior_5: true, // eslint-disable-line camelcase
shield_warrior_5: true, // eslint-disable-line camelcase
head_warrior_5: true, // eslint-disable-line camelcase
weapon_warrior_6: true, // eslint-disable-line camelcase
};
},
},
},
};
user.items = items;
ultimateGear(user);
expect(user.flags.armoireEnabled).to.equal(true);
});
});
+170
View File
@@ -0,0 +1,170 @@
import updateStats from '../../../common/script/fns/updateStats';
import {
generateUser,
} from '../../helpers/common.helper';
describe('common.fns.updateStats', () => {
let user;
beforeEach(() => {
user = generateUser();
});
context('No Hp', () => {
it('updates user\s hp', () => {
let stats = { hp: 0 };
expect(user.stats.hp).to.not.eql(0);
updateStats(user, stats);
expect(user.stats.hp).to.eql(0);
updateStats(user, { hp: 2 });
expect(user.stats.hp).to.eql(2);
});
it('does not lower hp below 0', () => {
let stats = {
hp: -5,
};
updateStats(user, stats);
expect(user.stats.hp).to.eql(0);
});
});
context('Stat Allocation', () => {
it('adds only attribute points up to user\'s level', () => {
let stats = {
exp: 261,
};
expect(user.stats.points).to.eql(0);
user.stats.lvl = 10;
updateStats(user, stats);
expect(user.stats.points).to.eql(11);
});
it('adds an attibute point when user\'s stat points are less than max level', () => {
let stats = {
exp: 3581,
};
user.stats.lvl = 99;
user.stats.str = 25;
user.stats.int = 25;
user.stats.con = 25;
user.stats.per = 24;
updateStats(user, stats);
expect(user.stats.points).to.eql(1);
});
it('does not add an attibute point when user\'s stat points are equal to max level', () => {
let stats = {
exp: 3581,
};
user.stats.lvl = 99;
user.stats.str = 25;
user.stats.int = 25;
user.stats.con = 25;
user.stats.per = 25;
updateStats(user, stats);
expect(user.stats.points).to.eql(0);
});
it('does not add an attibute point when user\'s stat points + unallocated points are equal to max level', () => {
let stats = {
exp: 3581,
};
user.stats.lvl = 99;
user.stats.str = 25;
user.stats.int = 25;
user.stats.con = 25;
user.stats.per = 15;
user.stats.points = 10;
updateStats(user, stats);
expect(user.stats.points).to.eql(10);
});
it('only awards stat points up to level 100 if user is missing unallocated stat points and is over level 100', () => {
let stats = {
exp: 5581,
};
user.stats.lvl = 104;
user.stats.str = 25;
user.stats.int = 25;
user.stats.con = 25;
user.stats.per = 15;
user.stats.points = 0;
updateStats(user, stats);
expect(user.stats.points).to.eql(10);
});
context('assigns flags.levelDrops', () => {
it('for atom1', () => {
user.stats.lvl = 16;
user.flags.levelDrops.atom1 = false;
expect(user.items.quests.atom1).to.eql(undefined);
updateStats(user, { atom1: true });
expect(user.items.quests.atom1).to.eql(1);
expect(user.flags.levelDrops.atom1).to.eql(true);
updateStats(user, { atom1: true });
expect(user.items.quests.atom1).to.eql(1); // no change
});
it('for vice1', () => {
user.stats.lvl = 31;
user.flags.levelDrops.vice1 = false;
expect(user.items.quests.vice1).to.eql(undefined);
updateStats(user, { vice1: true });
expect(user.items.quests.vice1).to.eql(1);
expect(user.flags.levelDrops.vice1).to.eql(true);
updateStats(user, { vice1: true });
expect(user.items.quests.vice1).to.eql(1);
});
it('moonstone', () => {
user.stats.lvl = 60;
user.flags.levelDrops.moonstone1 = false;
expect(user.items.quests.moonstone1).to.eql(undefined);
updateStats(user, { moonstone1: true });
expect(user.flags.levelDrops.moonstone1).to.eql(true);
expect(user.items.quests.moonstone1).to.eql(1);
updateStats(user, { moonstone1: true });
expect(user.items.quests.moonstone1).to.eql(1);
});
it('for goldenknight1', () => {
user.stats.lvl = 40;
user.flags.levelDrops.goldenknight1 = false;
expect(user.items.quests.goldenknight1).to.eql(undefined);
updateStats(user, { goldenknight1: true });
expect(user.items.quests.goldenknight1).to.eql(1);
expect(user.flags.levelDrops.goldenknight1).to.eql(true);
updateStats(user, { goldenknight1: true });
expect(user.items.quests.goldenknight1).to.eql(1);
});
});
// @TODO: Set up sinon sandbox
xit('auto allocates stats if automaticAllocation is turned on', () => {
sandbox.stub(user.fns, 'autoAllocate');
let stats = {
exp: 261,
};
user.stats.lvl = 10;
user.fns.updateStats(stats);
expect(user.fns.autoAllocate).to.be.calledOnce;
});
});
});