mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 22:57:21 +01:00
Ported sell function. Add unit tests. Create sell route. Add integration tests
This commit is contained in:
@@ -151,5 +151,8 @@
|
||||
"countRequired": "\"req.query.count\" is required.",
|
||||
"petsReleased": "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 %>"
|
||||
}
|
||||
|
||||
@@ -121,6 +121,7 @@ import openMysteryItem from './ops/openMysteryItem';
|
||||
import releasePets from './ops/releasePets';
|
||||
import releaseBoth from './ops/releaseBoth';
|
||||
import releaseMounts from './ops/releaseMounts';
|
||||
import sell from './ops/sell';
|
||||
|
||||
api.ops = {
|
||||
scoreTask,
|
||||
@@ -143,6 +144,7 @@ api.ops = {
|
||||
releasePets,
|
||||
releaseBoth,
|
||||
releaseMounts,
|
||||
sell,
|
||||
};
|
||||
|
||||
import handleTwoHanded from './fns/handleTwoHanded';
|
||||
|
||||
@@ -1,23 +1,42 @@
|
||||
import content from '../content/index';
|
||||
import i18n from '../../../common/script/i18n';
|
||||
import _ from 'lodash';
|
||||
import splitWhitespace from '../libs/splitWhitespace';
|
||||
import {
|
||||
NotFound,
|
||||
NotAuthorized,
|
||||
BadRequest,
|
||||
} from '../libs/errors';
|
||||
|
||||
module.exports = function(user, req, cb) {
|
||||
var key, ref, type;
|
||||
ref = req.params, key = ref.key, type = ref.type;
|
||||
if (type !== 'eggs' && type !== 'hatchingPotions' && type !== 'food') {
|
||||
return typeof cb === "function" ? cb({
|
||||
code: 404,
|
||||
message: ":type not found. Must bes in [eggs, hatchingPotions, food]"
|
||||
}) : void 0;
|
||||
const ACCEPTEDTYPES = ['eggs', 'hatchingPotions', 'food'];
|
||||
|
||||
module.exports = function sell (user, req = {}) {
|
||||
let key = _.get(req.params, 'key');
|
||||
let type = _.get(req.params, 'type');
|
||||
|
||||
if (!type) {
|
||||
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]) {
|
||||
return typeof cb === "function" ? cb({
|
||||
code: 404,
|
||||
message: ":key not found for user.items." + type
|
||||
}) : void 0;
|
||||
throw new NotFound(i18n.t('userItemsKeyNotFound', {type}, req.language));
|
||||
}
|
||||
|
||||
user.items[type][key]--;
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -30,7 +30,6 @@ const COMMON_FILES = [
|
||||
'!./common/script/ops/reroll.js',
|
||||
'!./common/script/ops/reset.js',
|
||||
'!./common/script/ops/revive.js',
|
||||
'!./common/script/ops/sell.js',
|
||||
'!./common/script/ops/sortTag.js',
|
||||
'!./common/script/ops/sortTask.js',
|
||||
'!./common/script/ops/unlock.js',
|
||||
|
||||
42
test/api/v3/integration/user/POST-user_sell.test.js
Normal file
42
test/api/v3/integration/user/POST-user_sell.test.js
Normal 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
81
test/common/ops/sell.js
Normal 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);
|
||||
});
|
||||
});
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user