v3: port coupons

This commit is contained in:
Matteo Pagliazzi
2016-04-02 16:37:55 +02:00
parent 731ac86244
commit de74fae0b4
12 changed files with 475 additions and 73 deletions
@@ -0,0 +1,39 @@
import {
generateUser,
translate as t,
resetHabiticaDB,
} from '../../../../helpers/api-v3-integration.helper';
describe('GET /coupons/', () => {
let user;
before(async () => {
await resetHabiticaDB();
});
beforeEach(async () => {
user = await generateUser();
});
it('returns an error if user has no sudo permission', async () => {
await user.get('/user'); // needed so the request after this will authenticate with the correct cookie session
await expect(user.get(`/coupons`)).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('noSudoAccess'),
});
});
it('should return the coupons in CSV format ordered by creation date', async () => {
await user.update({
'contributor.sudo': true,
});
let coupons = await user.post('/coupons/generate/wondercon?count=11');
let res = await user.get(`/coupons`);
let splitRes = res.split('\n');
expect(splitRes.length).to.equal(13);
expect(splitRes[0]).to.equal('code,event,date,user');
expect(splitRes[6].split(',')[1]).to.equal(coupons[5].event);
});
});
@@ -0,0 +1,62 @@
import {
generateUser,
translate as t,
resetHabiticaDB,
} from '../../../../helpers/api-v3-integration.helper';
describe('POST /coupons/enter/:code', () => {
let user;
let sudoUser;
before(async () => {
await resetHabiticaDB();
});
beforeEach(async () => {
user = await generateUser();
sudoUser = await generateUser({
'contributor.sudo': true,
});
});
it('returns an error if code is missing', async () => {
await expect(user.post(`/coupons/enter`)).to.eventually.be.rejected.and.eql({
code: 404,
error: 'NotFound',
message: 'Not found.',
});
});
it('returns an error if code is invalid', async () => {
await expect(user.post(`/coupons/enter/notValid`)).to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
message: t('invalidCoupon'),
});
});
it('returns an error if coupon has been used', async () => {
let [coupon] = await sudoUser.post('/coupons/generate/wondercon?count=1');
await user.post(`/coupons/enter/${coupon._id}`); // use coupon
await expect(user.post(`/coupons/enter/${coupon._id}`)).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('couponUsed'),
});
});
it('should apply the coupon to the user', async () => {
let [coupon] = await sudoUser.post('/coupons/generate/wondercon?count=1');
let userRes = await user.post(`/coupons/enter/${coupon._id}`);
expect(userRes._id).to.equal(user._id);
expect(userRes.items.gear.owned.eyewear_special_wondercon_red).to.be.true;
expect(userRes.items.gear.owned.eyewear_special_wondercon_black).to.be.true;
expect(userRes.items.gear.owned.back_special_wondercon_black).to.be.true;
expect(userRes.items.gear.owned.back_special_wondercon_red).to.be.true;
expect(userRes.items.gear.owned.body_special_wondercon_red).to.be.true;
expect(userRes.items.gear.owned.body_special_wondercon_black).to.be.true;
expect(userRes.items.gear.owned.body_special_wondercon_gold).to.be.true;
expect(userRes.extra).to.eql({signupEvent: 'wondercon'});
});
});
@@ -0,0 +1,66 @@
import {
generateUser,
translate as t,
resetHabiticaDB,
} from '../../../../helpers/api-v3-integration.helper';
import couponCode from 'coupon-code';
describe('POST /coupons/generate/:event', () => {
let user;
before(async () => {
await resetHabiticaDB();
});
beforeEach(async () => {
user = await generateUser({
'contributor.sudo': true,
});
});
it('returns an error if user has no sudo permission', async () => {
await user.update({
'contributor.sudo': false,
});
await expect(user.post(`/coupons/generate/aaa`)).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('noSudoAccess'),
});
});
it('returns an error if event is missing', async () => {
await expect(user.post(`/coupons/generate`)).to.eventually.be.rejected.and.eql({
code: 404,
error: 'NotFound',
message: 'Not found.',
});
});
it('returns an error if event is invalid', async () => {
await expect(user.post(`/coupons/generate/notValid?count=1`)).to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
message: 'Coupon validation failed',
});
});
it('returns an error if count is missing', async () => {
await expect(user.post(`/coupons/generate/notValid`)).to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
message: t('invalidReqParams'),
});
});
it('should generate coupons', async () => {
await user.update({
'contributor.sudo': true,
});
let coupons = await user.post('/coupons/generate/wondercon?count=2');
expect(coupons.length).to.equal(2);
expect(coupons[0].event).to.equal('wondercon');
expect(couponCode.validate(coupons[1]._id)).to.not.equal(''); // '' means invalid
});
});
@@ -0,0 +1,36 @@
import {
generateUser,
requester,
resetHabiticaDB,
} from '../../../../helpers/api-v3-integration.helper';
describe('POST /coupons/validate/:code', () => {
let api = requester();
before(async () => {
await resetHabiticaDB();
});
it('returns an error if code is missing', async () => {
await expect(api.post(`/coupons/validate`)).to.eventually.be.rejected.and.eql({
code: 404,
error: 'NotFound',
message: 'Not found.',
});
});
it('returns true if coupon code is valid', async () => {
let sudoUser = await generateUser({
'contributor.sudo': true,
});
let [coupon] = await sudoUser.post('/coupons/generate/wondercon?count=1');
let res = await api.post(`/coupons/validate/${coupon._id}`);
expect(res).to.eql({valid: true});
});
it('returns false if coupon code is valid', async () => {
let res = await api.post(`/coupons/validate/notValid`);
expect(res).to.eql({valid: false});
});
});
@@ -0,0 +1,57 @@
/* eslint-disable global-require */
import {
generateRes,
generateReq,
generateNext,
} from '../../../../helpers/api-unit.helper';
import i18n from '../../../../../common/script/i18n';
import { ensureAdmin, ensureSudo } from '../../../../../website/src/middlewares/api-v3/ensureAccessRight';
import { NotAuthorized } from '../../../../../website/src/libs/api-v3/errors';
describe('ensure access middlewares', () => {
let res, req, next;
beforeEach(() => {
res = generateRes();
req = generateReq();
next = generateNext();
});
context('ensure admin', () => {
it('returns not authorized when user is not an admin', () => {
res.locals = {user: {contributor: {admin: false}}};
ensureAdmin(req, res, next);
expect(next).to.be.calledWith(new NotAuthorized(i18n.t('noAdminAccess')));
});
it('passes when user is an admin', () => {
res.locals = {user: {contributor: {admin: true}}};
ensureAdmin(req, res, next);
expect(next).to.be.calledOnce;
expect(next.args[0]).to.be.empty;
});
});
context('ensure sudo', () => {
it('returns not authorized when user is not a sudo user', () => {
res.locals = {user: {contributor: {sudo: false}}};
ensureSudo(req, res, next);
expect(next).to.be.calledWith(new NotAuthorized(i18n.t('noSudoAccess')));
});
it('passes when user is a sudo user', () => {
res.locals = {user: {contributor: {sudo: true}}};
ensureSudo(req, res, next);
expect(next).to.be.calledOnce;
expect(next.args[0]).to.be.empty;
});
});
});