Fix level up webhook (#10347)

* use user._tmp for level up webhook

* use post save hook to send webhook
This commit is contained in:
Matteo Pagliazzi
2018-05-09 19:04:29 +02:00
committed by GitHub
parent bbbd1f9f73
commit a8655d923a
4 changed files with 83 additions and 58 deletions

View File

@@ -82,48 +82,48 @@ describe('POST /tasks/:id/score/:direction', () => {
expect(body.delta).to.be.greaterThan(0); expect(body.delta).to.be.greaterThan(0);
}); });
// context('sending user activity webhooks', () => { context('sending user activity webhooks', () => {
// before(async () => { before(async () => {
// await server.start(); await server.start();
// }); });
//
// after(async () => { after(async () => {
// await server.close(); await server.close();
// }); });
//
// it('sends user activity webhook when the user levels up', async () => { it('sends user activity webhook when the user levels up', async () => {
// let uuid = generateUUID(); let uuid = generateUUID();
//
// await user.post('/user/webhook', { await user.post('/user/webhook', {
// url: `http://localhost:${server.port}/webhooks/${uuid}`, url: `http://localhost:${server.port}/webhooks/${uuid}`,
// type: 'userActivity', type: 'userActivity',
// enabled: true, enabled: true,
// options: { options: {
// leveledUp: true, leveledUp: true,
// }, },
// }); });
//
// const initialLvl = user.stats.lvl; const initialLvl = user.stats.lvl;
//
// await user.update({ await user.update({
// 'stats.exp': 3000, 'stats.exp': 3000,
// }); });
// let task = await user.post('/tasks/user', { let task = await user.post('/tasks/user', {
// text: 'test habit', text: 'test habit',
// type: 'habit', type: 'habit',
// }); });
//
// await user.post(`/tasks/${task.id}/score/up`); await user.post(`/tasks/${task.id}/score/up`);
// await user.sync(); await user.sync();
// await sleep(); await sleep();
//
// let body = server.getWebhookData(uuid); let body = server.getWebhookData(uuid);
//
// expect(body.type).to.eql('leveledUp'); expect(body.type).to.eql('leveledUp');
// expect(body.initialLvl).to.eql(initialLvl); expect(body.initialLvl).to.eql(initialLvl);
// expect(body.finalLvl).to.eql(user.stats.lvl); expect(body.finalLvl).to.eql(user.stats.lvl);
// }); });
// }); });
}); });
context('todos', () => { context('todos', () => {

View File

@@ -8,7 +8,7 @@ describe('common.fns.updateStats', () => {
beforeEach(() => { beforeEach(() => {
user = generateUser(); user = generateUser();
// user.addNotification = sinon.spy(); user.addNotification = sinon.spy();
}); });
context('No Hp', () => { context('No Hp', () => {
@@ -110,26 +110,25 @@ describe('common.fns.updateStats', () => {
expect(user.stats.points).to.eql(10); expect(user.stats.points).to.eql(10);
}); });
xit('add user notification when drops are enabled', () => { it('add user notification when drops are enabled', () => {
user.stats.lvl = 3; user.stats.lvl = 3;
updateStats(user, { }); updateStats(user, { });
expect(user.addNotification).to.be.calledOnce; expect(user.addNotification).to.be.calledOnce;
expect(user.addNotification).to.be.calledWith('DROPS_ENABLED'); expect(user.addNotification).to.be.calledWith('DROPS_ENABLED');
}); });
xit('add user notification when the user levels up', () => { it('add user notification when the user levels up', () => {
const initialLvl = user.stats.lvl; const initialLvl = user.stats.lvl;
updateStats(user, { updateStats(user, {
exp: 3000, exp: 3000,
}); });
expect(user.addNotification).to.be.calledTwice; // once is for drops enabled expect(user._tmp.leveledUp).to.eql([{
expect(user.addNotification).to.be.calledWith('LEVELED_UP', {
initialLvl, initialLvl,
newLvl: user.stats.lvl, newLvl: user.stats.lvl,
}); }]);
}); });
xit('add user notification when rebirth is enabled', () => { it('add user notification when rebirth is enabled', () => {
user.stats.lvl = 51; user.stats.lvl = 51;
updateStats(user, { }); updateStats(user, { });
expect(user.addNotification).to.be.calledTwice; // once is for drops enabled expect(user.addNotification).to.be.calledTwice; // once is for drops enabled

View File

@@ -20,7 +20,7 @@ module.exports = function updateStats (user, stats, req = {}, analytics) {
if (stats.exp >= experienceToNextLevel) { if (stats.exp >= experienceToNextLevel) {
user.stats.exp = stats.exp; user.stats.exp = stats.exp;
// const initialLvl = user.stats.lvl; const initialLvl = user.stats.lvl;
while (stats.exp >= experienceToNextLevel) { while (stats.exp >= experienceToNextLevel) {
stats.exp -= experienceToNextLevel; stats.exp -= experienceToNextLevel;
@@ -50,13 +50,12 @@ module.exports = function updateStats (user, stats, req = {}, analytics) {
} }
} }
// @TODO: Tmp disable to see if this is causing concurrency const newLvl = user.stats.lvl;
// const newLvl = user.stats.lvl; if (!user._tmp.leveledUp) user._tmp.leveledUp = [];
// user._tmp.leveledUp.push({
// if (user.addNotification) user.addNotification('LEVELED_UP', { initialLvl,
// initialLvl, newLvl,
// newLvl, });
// });
} }
user.stats.exp = stats.exp; user.stats.exp = stats.exp;

View File

@@ -6,7 +6,9 @@ import * as Tasks from '../task';
import { import {
model as UserNotification, model as UserNotification,
} from '../userNotification'; } from '../userNotification';
import {
userActivityWebhook,
} from '../../libs/webhook';
import schema from './schema'; import schema from './schema';
schema.plugin(baseModel, { schema.plugin(baseModel, {
@@ -15,6 +17,11 @@ schema.plugin(baseModel, {
private: ['auth.local.hashed_password', 'auth.local.passwordHashMethod', 'auth.local.salt', '_cronSignature', '_ABtests'], private: ['auth.local.hashed_password', 'auth.local.passwordHashMethod', 'auth.local.salt', '_cronSignature', '_ABtests'],
toJSONTransform: function userToJSON (plainObj, originalDoc) { toJSONTransform: function userToJSON (plainObj, originalDoc) {
plainObj._tmp = originalDoc._tmp; // be sure to send down drop notifs plainObj._tmp = originalDoc._tmp; // be sure to send down drop notifs
if (plainObj._tmp && plainObj._tmp.leveledUp) {
delete plainObj._tmp.leveledUp;
}
delete plainObj.filters; delete plainObj.filters;
if (originalDoc.notifications) { if (originalDoc.notifications) {
@@ -314,3 +321,23 @@ schema.pre('save', true, function preSaveUser (next, done) {
schema.pre('update', function preUpdateUser () { schema.pre('update', function preUpdateUser () {
this.update({}, {$inc: {_v: 1}}); this.update({}, {$inc: {_v: 1}});
}); });
schema.post('save', function postSaveUser () {
// Send a webhook notification when the user has leveled up
if (this._tmp && this._tmp.leveledUp && this._tmp.leveledUp.length > 0) {
const lvlUpNotifications = this._tmp.leveledUp;
const firstLvlNotification = lvlUpNotifications[0];
const lastLvlNotification = lvlUpNotifications[lvlUpNotifications.length - 1];
const initialLvl = firstLvlNotification.initialLvl;
const finalLvl = lastLvlNotification.newLvl;
userActivityWebhook.send(this, {
type: 'leveledUp',
initialLvl,
finalLvl,
});
this._tmp.leveledUp = [];
}
});