Refactor notification service and add tests

This commit is contained in:
Blade Barringer 2015-06-02 07:51:54 -05:00
parent 3291062b31
commit b375c068de
3 changed files with 293 additions and 77 deletions

View file

@ -12,6 +12,7 @@ module.exports = function(config) {
// list of files / patterns to load in the browser
files: [
'website/public/bower_components/jquery/dist/jquery.js',
'website/public/bower_components/pnotify/jquery.pnotify.js',
'website/public/bower_components/angular/angular.js',
'website/public/bower_components/angular-loading-bar/build/loading-bar.min.js',
'website/public/bower_components/angular-resource/angular-resource.min.js',

View file

@ -1,9 +1,14 @@
'use strict';
//TODO mock bootstrapGrowl, add remaining tests
describe('notificationServices', function() {
var notification;
before(function(){
sinon.stub($, 'pnotify', function(){
return { click: function(){}}
});
});
beforeEach(function() {
module(function($provide){
$provide.value('User', {});
@ -14,12 +19,190 @@ describe('notificationServices', function() {
});
});
afterEach(function() {
$.pnotify.reset();
});
it('notifies coins amount', function() {
var SILVER_COIN = "<span class='notification-icon shop_silver'></span>";
var GOLD_COIN = "<span class='notification-icon shop_gold'></span>";
expect(notification.coins(0)).to.not.exist;
expect(notification.coins(0.01)).to.eql("1 " + SILVER_COIN);
expect(notification.coins(0.1)).to.eql("10 " + SILVER_COIN);
expect(notification.coins(1)).to.eql("1 " + GOLD_COIN);
expect(notification.coins(12.34)).to.eql("12 " + GOLD_COIN +" 33 " + SILVER_COIN);
});
it('sends crit notification', function() {
notification.crit(5);
var arg = $.pnotify.args[0][0]
expect($.pnotify).to.have.been.calledOnce;
expect(arg.type).to.eql('crit');
expect(arg.text).to.eql('Critical Hit! Bonus: 5%');
expect(arg.icon).to.eql('glyphicon glyphicon-certificate');
});
it('sends drop notification for unspecified item', function() {
notification.drop('msg');
var arg = $.pnotify.args[0][0]
expect($.pnotify).to.have.been.calledOnce;
expect(arg.type).to.eql('drop');
expect(arg.text).to.eql('msg');
expect(arg.icon).to.eql(false);
});
it('sends drop notification for Egg', function() {
var item = { type: 'Egg', key: 'wolf' };
notification.drop('msg', item);
var arg = $.pnotify.args[0][0]
expect($.pnotify).to.have.been.calledOnce;
expect(arg.type).to.eql('drop');
expect(arg.text).to.eql('msg');
expect(arg.icon).to.eql('Pet_Egg_wolf');
});
it('sends drop notification for Hatching Potion', function() {
var item = { type: 'HatchingPotion', key: 'red' };
notification.drop('msg', item);
var arg = $.pnotify.args[0][0]
expect($.pnotify).to.have.been.calledOnce;
expect(arg.type).to.eql('drop');
expect(arg.text).to.eql('msg');
expect(arg.icon).to.eql('Pet_HatchingPotion_red');
});
it('sends drop notification for Food', function() {
var item = { type: 'Food', key: 'meat' };
notification.drop('msg', item);
var arg = $.pnotify.args[0][0]
expect($.pnotify).to.have.been.calledOnce;
expect(arg.type).to.eql('drop');
expect(arg.text).to.eql('msg');
expect(arg.icon).to.eql('Pet_Food_meat');
});
it('does not send exp notification if val < -50', function() {
notification.exp(-51);
expect($.pnotify).to.not.have.been.called;
});
it('send exp notification if val >= -50', function() {
notification.exp(50);
notification.exp(0);
notification.exp(-50);
var arg = $.pnotify.args[0][0]
expect($.pnotify).to.have.been.calledThrice;
expect(arg.type).to.eql('xp');
expect(arg.text).to.eql('+ 50 XP');
expect(arg.icon).to.eql('glyphicon glyphicon-star');
});
it('send exp notification with rounded value', function() {
notification.exp(50.23333);
var arg = $.pnotify.args[0][0]
expect($.pnotify).to.have.been.calledOnce;
expect(arg.type).to.eql('xp');
expect(arg.text).to.eql('+ 50.2 XP');
expect(arg.icon).to.eql('glyphicon glyphicon-star');
});
it('send error notification', function() {
notification.error('there was an error');
var arg = $.pnotify.args[0][0]
expect($.pnotify).to.have.been.calledOnce;
expect(arg.type).to.eql('danger');
expect(arg.text).to.eql('there was an error');
expect(arg.icon).to.eql('glyphicon glyphicon-exclamation-sign');
});
it('send gp gained notification', function() {
notification.gp(50, 4);
var arg = $.pnotify.args[0][0]
expect($.pnotify).to.have.been.calledOnce;
expect(arg.type).to.eql('gp');
expect(arg.text).to.eql('+ 46 <span class=\'notification-icon shop_gold\'></span>');
expect(arg.icon).to.eql(false);
});
it('send hp notification', function() {
notification.hp(10);
var arg = $.pnotify.args[0][0]
expect($.pnotify).to.have.been.calledOnce;
expect(arg.type).to.eql('hp');
expect(arg.text).to.eql('+ 10 HP');
expect(arg.icon).to.eql('glyphicon glyphicon-heart');
});
it('send level up notification', function() {
notification.lvl(10);
var arg = $.pnotify.args[0][0]
expect($.pnotify).to.have.been.calledOnce;
expect(arg.type).to.eql('lvl');
expect(arg.text).to.eql('Level Up!');
expect(arg.icon).to.eql('glyphicon glyphicon-chevron-up');
});
it('send markdown parsed notification', function() {
notification.markdown(":smile: - task name");
var arg = $.pnotify.args[0][0]
expect($.pnotify).to.have.been.calledOnce;
expect(arg.type).to.eql('info');
expect(arg.text).to.eql('<p><span class="emoji" style="background-image:url(common/img/emoji/unicode/1f604.png)">:smile:</span> - task name</p>\n');
expect(arg.icon).to.eql(false);
});
it('does not send markdown notification if no text is given', function() {
notification.markdown();
expect($.pnotify).to.not.have.been.called;
});
it('send mp notification', function() {
notification.mp(10);
var arg = $.pnotify.args[0][0]
expect($.pnotify).to.have.been.calledOnce;
expect(arg.type).to.eql('mp');
expect(arg.text).to.eql('+ 10 MP');
expect(arg.icon).to.eql('glyphicon glyphicon-fire');
});
it('send streak notification', function() {
notification.streak(10);
var arg = $.pnotify.args[0][0]
expect($.pnotify).to.have.been.calledOnce;
expect(arg.type).to.eql('streak');
expect(arg.text).to.eql('Streak Achievements: 10');
expect(arg.icon).to.eql('glyphicon glyphicon-repeat');
});
it('send text notification', function() {
notification.text('task name');
var arg = $.pnotify.args[0][0]
expect($.pnotify).to.have.been.calledOnce;
expect(arg.type).to.eql('info');
expect(arg.text).to.eql('task name');
expect(arg.icon).to.eql(false);
});
it('does not send text notification if no text is given', function() {
notification.text();
expect($.pnotify).to.not.have.been.called;
});
});

View file

@ -1,24 +1,27 @@
'use strict'
/**
Set up "+1 Exp", "Level Up", etc notifications
*/
angular.module("habitrpg").factory("Notification",
['$filter', function($filter) {
var stack_topright = {"dir1": "down", "dir2": "left", "spacing1": 15, "spacing2": 15, "firstpos1": 60};
function notify(html, type, icon) {
var notice = $.pnotify({
type: type || 'warning', //('info', 'text', 'warning', 'success', 'gp', 'xp', 'hp', 'lvl', 'death', 'mp', 'crit')
text: html,
opacity: 1,
addclass: 'alert-' + type,
delay: 7000,
hide: (type == 'error') ? false : true,
mouse_reset: false,
width: "250px",
stack: stack_topright,
icon: icon || false
}).click(function() { notice.pnotify_remove() });
var notificationService = {
coins: coins,
crit: crit,
drop: drop,
exp: exp,
error: error,
gp: gp,
hp: hp,
lvl: lvl,
markdown: markdown,
mp: mp,
streak: streak,
text: text
};
return notificationService;
/**
Show "+ 5 {gold_coin} 3 {silver_coin}"
*/
@ -34,73 +37,102 @@ angular.module("habitrpg").factory("Notification",
} else if (silver > 0) {
return "" + silver + " <span class='notification-icon shop_silver'></span>";
}
};
}
var sign = function(number){
function crit(val) {
_notify(window.env.t('critBonus') + Math.round(val) + "%", 'crit', 'glyphicon glyphicon-certificate');
}
function drop(val, item) {
var dropClass = "";
if ( item !== undefined ) {
switch ( item.type ) {
case "Egg":
dropClass = 'Pet_Egg_' + item.key;
break;
case "HatchingPotion":
dropClass = 'Pet_HatchingPotion_' + item.key;
break;
case "Food":
dropClass = 'Pet_Food_' + item.key;
break;
default:
dropClass = 'glyphicon glyphicon-gift';
}
}
_notify(val, 'drop', dropClass);
}
function exp(val) {
if (val < -50) return; // don't show when they level up (resetting their exp)
_notify(_sign(val) + " " + _round(val) + " " + window.env.t('xp'), 'xp', 'glyphicon glyphicon-star');
}
function error(error){
_notify(error, "danger", 'glyphicon glyphicon-exclamation-sign');
}
function gp(val, bonus) {
_notify(_sign(val) + " " + coins(val - bonus), 'gp');
}
function hp(val) {
// don't show notifications if user dead
_notify(_sign(val) + " " + _round(val) + " " + window.env.t('hp'), 'hp', 'glyphicon glyphicon-heart');
}
function lvl(){
_notify(window.env.t('levelUp'), 'lvl', 'glyphicon glyphicon-chevron-up');
}
function markdown(val){
if (val) {
var parsed_markdown = $filter("markdown")(val);
_notify(parsed_markdown, 'info');
}
}
function mp(val) {
_notify(_sign(val) + " " + _round(val) + " " + window.env.t('mp'), 'mp', 'glyphicon glyphicon-fire');
}
function streak(val) {
_notify(window.env.t('streakName') + ': ' + val, 'streak', 'glyphicon glyphicon-repeat');
}
function text(val){
if (val) {
_notify(val, 'info');
}
}
//--------------------------------------------------
// Private Methods
//--------------------------------------------------
function _sign(number){
return number?number<0?'-':'+':'+';
}
var round = function(number){
function _round(number){
return Math.abs(number.toFixed(1));
}
return {
coins: coins,
hp: function(val) {
// don't show notifications if user dead
notify(sign(val) + " " + round(val) + " " + window.env.t('hp'), 'hp', 'glyphicon glyphicon-heart');
},
exp: function(val) {
if (val < -50) return; // don't show when they level up (resetting their exp)
notify(sign(val) + " " + round(val) + " " + window.env.t('xp'), 'xp', 'glyphicon glyphicon-star');
},
gp: function(val, bonus) {
notify(sign(val) + " " + coins(val - bonus), 'gp');
},
text: function(val){
if (val) {
notify(val, 'info');
}
},
markdown: function(val){
if (val) {
var parsed_markdown = $filter("markdown")(val);
notify(parsed_markdown, 'info');
}
},
lvl: function(){
notify(window.env.t('levelUp'), 'lvl', 'glyphicon glyphicon-chevron-up');
},
error: function(error){
notify(error, "danger", 'glyphicon glyphicon-exclamation-sign');
},
mp: function(val) {
notify(sign(val) + " " + round(val) + " " + window.env.t('mp'), 'mp', 'glyphicon glyphicon-fire');
},
crit: function(val) {
notify(window.env.t('critBonus') + Math.round(val) + "%", 'crit', 'glyphicon glyphicon-certificate');
},
streak: function(val) {
notify(window.env.t('streakName') + ': ' + val, 'streak', 'glyphicon glyphicon-repeat');
},
drop: function(val, item) {
var dropClass = "";
if ( item !== undefined ) {
switch ( item.type ) {
case "Egg":
dropClass = 'Pet_Egg_' + item.key;
break;
case "HatchingPotion":
dropClass = 'Pet_HatchingPotion_' + item.key;
break;
case "Food":
dropClass = 'Pet_Food_' + item.key;
break;
default:
dropClass = 'glyphicon glyphicon-gift';
}
}
notify(val, 'drop', dropClass);
}
};
// Used to stack notifications, must be outside of _notify
var stack_topright = {"dir1": "down", "dir2": "left", "spacing1": 15, "spacing2": 15, "firstpos1": 60};
function _notify(html, type, icon) {
var notice = $.pnotify({
type: type || 'warning', //('info', 'text', 'warning', 'success', 'gp', 'xp', 'hp', 'lvl', 'death', 'mp', 'crit')
text: html,
opacity: 1,
addclass: 'alert-' + type,
delay: 7000,
hide: (type == 'error') ? false : true,
mouse_reset: false,
width: "250px",
stack: stack_topright,
icon: icon || false
}).click(function() { notice.pnotify_remove() });
}
}]);