Ported sell function. Add unit tests. Create sell route. Add integration tests

This commit is contained in:
Keith Holliday
2016-04-06 08:27:18 -05:00
parent 68ff26e6d6
commit 05b41bb41c
7 changed files with 181 additions and 15 deletions

View File

@@ -151,5 +151,8 @@
"countRequired": "\"req.query.count\" is required.", "countRequired": "\"req.query.count\" is required.",
"petsReleased": "Pets released.", "petsReleased": "Pets released.",
"mountsAndPetsReleased": "Mounts and pets released", "mountsAndPetsReleased": "Mounts and pets released",
"mountsReleased": "Mounts released" "mountsReleased": "Mounts released",
"typeNotSellable": "Type is not sellable. Must be one of the following <%= acceptedTypes %>",
"userItemsKeyNotFound": "Key not found for user.items <%= type %>",
"sold": "You sold a <%= key %> <%= type %>"
} }

View File

@@ -121,6 +121,7 @@ import openMysteryItem from './ops/openMysteryItem';
import releasePets from './ops/releasePets'; import releasePets from './ops/releasePets';
import releaseBoth from './ops/releaseBoth'; import releaseBoth from './ops/releaseBoth';
import releaseMounts from './ops/releaseMounts'; import releaseMounts from './ops/releaseMounts';
import sell from './ops/sell';
api.ops = { api.ops = {
scoreTask, scoreTask,
@@ -143,6 +144,7 @@ api.ops = {
releasePets, releasePets,
releaseBoth, releaseBoth,
releaseMounts, releaseMounts,
sell,
}; };
import handleTwoHanded from './fns/handleTwoHanded'; import handleTwoHanded from './fns/handleTwoHanded';

View File

@@ -1,23 +1,42 @@
import content from '../content/index'; import content from '../content/index';
import i18n from '../../../common/script/i18n';
import _ from 'lodash'; import _ from 'lodash';
import splitWhitespace from '../libs/splitWhitespace'; import splitWhitespace from '../libs/splitWhitespace';
import {
NotFound,
NotAuthorized,
BadRequest,
} from '../libs/errors';
module.exports = function(user, req, cb) { const ACCEPTEDTYPES = ['eggs', 'hatchingPotions', 'food'];
var key, ref, type;
ref = req.params, key = ref.key, type = ref.type; module.exports = function sell (user, req = {}) {
if (type !== 'eggs' && type !== 'hatchingPotions' && type !== 'food') { let key = _.get(req.params, 'key');
return typeof cb === "function" ? cb({ let type = _.get(req.params, 'type');
code: 404,
message: ":type not found. Must bes in [eggs, hatchingPotions, food]" if (!type) {
}) : void 0; throw new BadRequest(i18n.t('typeRequired', req.language));
} }
if (!key) {
throw new BadRequest(i18n.t('keyRequired', req.language));
}
if (ACCEPTEDTYPES.indexOf(type) === -1) {
throw new NotAuthorized(i18n.t('typeNotSellable', {acceptedTypes: ACCEPTEDTYPES.join(', ')}, req.language));
}
if (!user.items[type][key]) { if (!user.items[type][key]) {
return typeof cb === "function" ? cb({ throw new NotFound(i18n.t('userItemsKeyNotFound', {type}, req.language));
code: 404,
message: ":key not found for user.items." + type
}) : void 0;
} }
user.items[type][key]--; user.items[type][key]--;
user.stats.gp += content[type][key].value; user.stats.gp += content[type][key].value;
return typeof cb === "function" ? cb(null, _.pick(user, splitWhitespace('stats items'))) : void 0;
let response = {
data: _.pick(user, splitWhitespace('stats items')),
message: i18n.t('sold', {type, key}),
};
return response;
}; };

View File

@@ -30,7 +30,6 @@ const COMMON_FILES = [
'!./common/script/ops/reroll.js', '!./common/script/ops/reroll.js',
'!./common/script/ops/reset.js', '!./common/script/ops/reset.js',
'!./common/script/ops/revive.js', '!./common/script/ops/revive.js',
'!./common/script/ops/sell.js',
'!./common/script/ops/sortTag.js', '!./common/script/ops/sortTag.js',
'!./common/script/ops/sortTask.js', '!./common/script/ops/sortTask.js',
'!./common/script/ops/unlock.js', '!./common/script/ops/unlock.js',

View File

@@ -0,0 +1,42 @@
import {
generateUser,
translate as t,
} from '../../../../helpers/api-integration/v3';
import content from '../../../../../common/script/content';
describe('POST /user/sell/:type/:key', () => {
let user;
let type = 'eggs';
let key = 'Wolf';
beforeEach(async () => {
user = await generateUser();
});
// More tests in common code unit tests
it('returns an error when user does not have item', async () => {
await expect(user.post(`/user/sell/${type}/${key}`))
.to.eventually.be.rejected.and.eql({
code: 404,
error: 'NotFound',
message: t('userItemsKeyNotFound', {type}),
});
});
it('sells an item', async () => {
await user.update({
items: {
eggs: {
Wolf: 1,
},
},
});
let response = await user.post(`/user/sell/${type}/${key}`);
await user.sync();
expect(response.message).to.equal(t('sold', {type, key}));
expect(user.stats.gp).to.equal(content[type][key].value);
});
});

81
test/common/ops/sell.js Normal file
View File

@@ -0,0 +1,81 @@
import sell from '../../../common/script/ops/sell';
import i18n from '../../../common/script/i18n';
import {
generateUser,
} from '../../helpers/common.helper';
import {
NotAuthorized,
BadRequest,
NotFound,
} from '../../../common/script/libs/errors';
import content from '../../../common/script/content/index';
describe('shared.ops.sell', () => {
let user;
let type = 'eggs';
let key = 'Wolf';
let acceptedTypes = ['eggs', 'hatchingPotions', 'food'];
beforeEach(() => {
user = generateUser();
user.items[type][key] = 1;
});
it('returns an error when type is not provided', (done) => {
try {
sell(user);
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(i18n.t('typeRequired'));
done();
}
});
it('returns an error when key is not provided', (done) => {
try {
sell(user, {params: { type } });
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(i18n.t('keyRequired'));
done();
}
});
it('returns an error when non-sellable type is provided', (done) => {
let nonSellableType = 'nonSellableType';
try {
sell(user, {params: { type: nonSellableType, key } });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('typeNotSellable', {acceptedTypes: acceptedTypes.join(', ')}));
done();
}
});
it('returns an error when key is not found with type provided', (done) => {
let fakeKey = 'fakeKey';
try {
sell(user, {params: { type, key: fakeKey } });
} catch (err) {
expect(err).to.be.an.instanceof(NotFound);
expect(err.message).to.equal(i18n.t('userItemsKeyNotFound', {type}));
done();
}
});
it('reduces item count from user', () => {
let response = sell(user, {params: { type, key } });
expect(response.message).to.equal(i18n.t('sold', {type, key}));
expect(user.items[type][key]).to.equal(0);
});
it('increases user\'s gold', () => {
let response = sell(user, {params: { type, key } });
expect(response.message).to.equal(i18n.t('sold', {type, key}));
expect(user.stats.gp).to.equal(content[type][key].value);
});
});

View File

@@ -828,4 +828,24 @@ api.userReleaseMounts = {
}, },
}; };
/*
* @api {post} /user/sell/:type/:key Sells user's items.
* @apiVersion 3.0.0
* @apiName UserSell
* @apiGroup User
*
* @apiSuccess {Object} data `stats items`
*/
api.userSell = {
method: 'POST',
middlewares: [authWithHeaders(), cron],
url: '/user/sell/:type/:key',
async handler (req, res) {
let user = res.locals.user;
let sellResponse = common.ops.sell(user, req);
await user.save();
res.respond(200, sellResponse);
},
};
module.exports = api; module.exports = api;