Merge branch 'develop' into hairlessbear-quest_invite_modal_on_user_sync

This commit is contained in:
Blade Barringer
2015-06-14 16:33:38 -05:00
679 changed files with 14883 additions and 11486 deletions
+36
View File
@@ -0,0 +1,36 @@
'use strict';
describe('AppJS', function() {
describe('Automatic page refresh', function(){
var clock;
beforeEach(function () {
clock = sinon.useFakeTimers();
sinon.stub(window, "refresher", function(){return true});
});
afterEach(function () {
clock.restore();
window.refresher.restore();
});
it('should not call refresher if idle time is less than 6 hours', function() {
window.awaitIdle();
clock.tick(21599999);
expect(window.refresher).to.not.be.called;
});
it('should not call refresher if awaitIdle is called within 6 hours', function() {
window.awaitIdle();
clock.tick(21500000);
window.awaitIdle();
clock.tick(21500000);
expect(window.refresher).to.not.be.called;
});
it('should call refresher if idle time is 6 hours or greater', function() {
window.awaitIdle();
clock.tick(21600000);
expect(window.refresher).to.be.called;
});
});
});
+177
View File
@@ -0,0 +1,177 @@
'use strict';
describe('Challenges Controller', function() {
var $rootScope, scope, user, ctrl, challenges, groups;
beforeEach(function() {
module(function($provide) {
$provide.value('User', {});
});
inject(function($rootScope, $controller, Challenges, Groups){
user = specHelper.newUser();
user._id = "unique-user-id";
scope = $rootScope.$new();
// Load RootCtrl to ensure shared behaviors are loaded
$controller('RootCtrl', {$scope: scope, User: {user: user}});
ctrl = $controller('ChallengesCtrl', {$scope: scope, User: {user: user}});
challenges = Challenges;
groups = Groups;
});
});
describe('filterChallenges', function() {
var ownMem, ownNotMem, notOwnMem, notOwnNotMem;
beforeEach(function() {
ownMem = new challenges.Challenge({
name: 'test',
description: 'You are the owner and member',
habits: [],
dailys: [],
todos: [],
rewards: [],
leader: user._id,
group: "test",
timestamp: +(new Date),
members: [user],
official: false,
_isMember: true
});
ownNotMem = new challenges.Challenge({
name: 'test',
description: 'You are the owner, but not a member',
habits: [],
dailys: [],
todos: [],
rewards: [],
leader: user._id,
group: "test",
timestamp: +(new Date),
members: [],
official: false,
_isMember: false
});
notOwnMem = new challenges.Challenge({
name: 'test',
description: 'Not owner but a member',
habits: [],
dailys: [],
todos: [],
rewards: [],
leader: {_id:"test"},
group: "test",
timestamp: +(new Date),
members: [user],
official: false,
_isMember: true
});
notOwnNotMem = new challenges.Challenge({
name: 'test',
description: 'Not owner or member',
habits: [],
dailys: [],
todos: [],
rewards: [],
leader: {_id:"test"},
group: "test",
timestamp: +(new Date),
members: [],
official: false,
_isMember: false
});
scope.search = {
group: _.transform(groups, function(m,g){m[g._id]=true;})
};
});
it('displays challenges that match membership: either and owner: either', function() {
scope.search._isMember = 'either';
scope.search._isOwner = 'either';
expect(scope.filterChallenges(ownMem)).to.eql(true);
expect(scope.filterChallenges(ownNotMem)).to.eql(true);
expect(scope.filterChallenges(notOwnMem)).to.eql(true);
expect(scope.filterChallenges(notOwnNotMem)).to.eql(true);
});
it('displays challenges that match membership: either and owner: true', function() {
scope.search._isMember = 'either';
scope.search._isOwner = true;
expect(scope.filterChallenges(ownMem)).to.eql(true);
expect(scope.filterChallenges(ownNotMem)).to.eql(true);
expect(scope.filterChallenges(notOwnMem)).to.eql(false);
expect(scope.filterChallenges(notOwnNotMem)).to.eql(false);
});
it('displays challenges that match membership: either and owner: false', function() {
scope.search._isMember = 'either';
scope.search._isOwner = false;
expect(scope.filterChallenges(ownMem)).to.eql(false);
expect(scope.filterChallenges(ownNotMem)).to.eql(false);
expect(scope.filterChallenges(notOwnMem)).to.eql(true);
expect(scope.filterChallenges(notOwnNotMem)).to.eql(true);
});
it('displays challenges that match membership: true and owner: either', function() {
scope.search._isMember = true;
scope.search._isOwner = 'either';
expect(scope.filterChallenges(ownMem)).to.eql(true);
expect(scope.filterChallenges(ownNotMem)).to.eql(false);
expect(scope.filterChallenges(notOwnMem)).to.eql(true);
expect(scope.filterChallenges(notOwnNotMem)).to.eql(false);
});
it('displays challenges that match membership: true and owner: true', function() {
scope.search._isMember = true;
scope.search._isOwner = true;
expect(scope.filterChallenges(ownMem)).to.eql(true);
expect(scope.filterChallenges(ownNotMem)).to.eql(false);
expect(scope.filterChallenges(notOwnMem)).to.eql(false);
expect(scope.filterChallenges(notOwnNotMem)).to.eql(false);
});
it('displays challenges that match membership: true and owner: false', function() {
scope.search._isMember = true;
scope.search._isOwner = false;
expect(scope.filterChallenges(ownMem)).to.eql(false);
expect(scope.filterChallenges(ownNotMem)).to.eql(false);
expect(scope.filterChallenges(notOwnMem)).to.eql(true);
expect(scope.filterChallenges(notOwnNotMem)).to.eql(false);
});
it('displays challenges that match membership: false and owner: either', function() {
scope.search._isMember = false;
scope.search._isOwner = 'either';
expect(scope.filterChallenges(ownMem)).to.eql(false);
expect(scope.filterChallenges(ownNotMem)).to.eql(true);
expect(scope.filterChallenges(notOwnMem)).to.eql(false);
expect(scope.filterChallenges(notOwnNotMem)).to.eql(true);
});
it('displays challenges that match membership: false and owner: true', function() {
scope.search._isMember = false;
scope.search._isOwner = true;
expect(scope.filterChallenges(ownMem)).to.eql(false);
expect(scope.filterChallenges(ownNotMem)).to.eql(true);
expect(scope.filterChallenges(notOwnMem)).to.eql(false);
expect(scope.filterChallenges(notOwnNotMem)).to.eql(false);
});
it('displays challenges that match membership: false and owner: false', function() {
scope.search._isMember = false;
scope.search._isOwner = false;
expect(scope.filterChallenges(ownMem)).to.eql(false);
expect(scope.filterChallenges(ownNotMem)).to.eql(false);
expect(scope.filterChallenges(notOwnMem)).to.eql(false);
expect(scope.filterChallenges(notOwnNotMem)).to.eql(true);
});
});
});
+39
View File
@@ -0,0 +1,39 @@
'use strict';
describe('Filters Controller', function() {
var scope, user;
beforeEach(inject(function($rootScope, $controller, Shared) {
user = specHelper.newUser();
Shared.wrap(user);
scope = $rootScope.$new();
$controller('FiltersCtrl', {$scope: scope, User: {user: user}});
}));
describe('tags', function(){
it('creates a tag', function(){
scope._newTag = {name:'tagName'}
scope.createTag();
expect(user.tags).to.have.length(1);
expect(user.tags[0].name).to.eql('tagName');
expect(user.tags[0]).to.have.property('id');
});
it('toggles tag filtering', inject(function(Shared){
var tag = {id: Shared.uuid(), name: 'myTag'};
scope.toggleFilter(tag);
expect(user.filters[tag.id]).to.eql(true);
scope.toggleFilter(tag);
expect(user.filters[tag.id]).to.eql(false);
}));
});
describe('updateTaskFilter', function(){
it('updatest user\'s filter query with the value of filterQuery', function () {
scope.filterQuery = 'task';
scope.updateTaskFilter();
expect(user.filterQuery).to.eql(scope.filterQuery);
});
});
});
+56
View File
@@ -0,0 +1,56 @@
'use strict';
describe('Header Controller', function() {
var scope, ctrl, user, $location, $rootScope;
beforeEach(function() {
module(function($provide) {
$provide.value('User', {});
});
inject(function(_$rootScope_, _$controller_, _$location_){
user = specHelper.newUser();
user._id = "unique-user-id"
scope = _$rootScope_.$new();
$rootScope = _$rootScope_;
$location = _$location_;
// Load RootCtrl to ensure shared behaviors are loaded
_$controller_('RootCtrl', {$scope: scope, User: {user: user}});
ctrl = _$controller_('HeaderCtrl', {$scope: scope, User: {user: user}});
});
});
context('inviteOrStartParty', function(){
beforeEach(function(){
sinon.stub($location, 'path');
sinon.stub($rootScope, 'openModal');
});
afterEach(function(){
$location.path.restore();
$rootScope.openModal.restore();
});
it('redirects to party page if user does not have a party', function(){
var group = {};
scope.inviteOrStartParty(group);
expect($location.path).to.be.calledWith("/options/groups/party");
expect($rootScope.openModal).to.not.be.called;
});
it('Opens invite-friends modal if user has a party', function(){
var group = {
type: 'party'
};
scope.inviteOrStartParty(group);
expect($rootScope.openModal).to.be.calledOnce;
expect($location.path).to.not.be.called;
});
});
});
@@ -10,8 +10,12 @@ describe('Inventory Controller', function() {
inject(function($rootScope, $controller, Shared){
user = specHelper.newUser();
user.balance = 4,
user.items = {eggs: {Cactus: 1}, hatchingPotions: {Base: 1}, food: {Meat: 1}, pets: {}, mounts: {}};
user.balance = 4;
user.items.eggs = {Cactus: 1};
user.items.hatchingPotions = {Base: 1};
user.items.food = {Meat: 1};
user.items.pets = {}
user.items.mounts = {};
Shared.wrap(user);
var mockWindow = {
confirm: function(msg){
+194
View File
@@ -0,0 +1,194 @@
'use strict';
describe('Root Controller', function() {
var scope, rootscope, user, User, notification, ctrl, $httpBackend;
beforeEach(function () {
module(function($provide) {
$provide.value('User', {});
$provide.service('$templateCache', function () {
return {
get: function () {},
put: function () {}
}
});
});
inject(function($rootScope, $controller, _$httpBackend_, Notification) {
scope = $rootScope.$new();
scope.loginUsername = 'user';
scope.loginPassword = 'pass';
rootscope = $rootScope;
$httpBackend = _$httpBackend_;
notification = Notification;
sinon.stub(notification, 'text');
sinon.stub(notification, 'markdown');
user = specHelper.newUser();
User = {user: user};
User.save = sinon.spy();
User.sync = sinon.spy();
$httpBackend.whenGET(/partials/).respond();
ctrl = $controller('RootCtrl', {$scope: scope, User: User});
});
});
afterEach(function() {
notification.text.reset();
notification.markdown.reset();
User.save.reset();
User.sync.reset();
});
describe('contribText', function(){
it('shows contributor level text', function(){
expect(scope.contribText()).to.eql(undefined);
expect(scope.contribText(null, {npc: 'NPC'})).to.eql('NPC');
expect(scope.contribText({level: 0, text: 'Blacksmith'})).to.eql(undefined);
expect(scope.contribText({level: 1, text: 'Blacksmith'})).to.eql('Friend Blacksmith');
expect(scope.contribText({level: 2, text: 'Blacksmith'})).to.eql('Friend Blacksmith');
expect(scope.contribText({level: 3, text: 'Blacksmith'})).to.eql('Elite Blacksmith');
expect(scope.contribText({level: 4, text: 'Blacksmith'})).to.eql('Elite Blacksmith');
expect(scope.contribText({level: 5, text: 'Blacksmith'})).to.eql('Champion Blacksmith');
expect(scope.contribText({level: 6, text: 'Blacksmith'})).to.eql('Champion Blacksmith');
expect(scope.contribText({level: 7, text: 'Blacksmith'})).to.eql('Legendary Blacksmith');
expect(scope.contribText({level: 8, text: 'Blacksmith'})).to.eql('Guardian Blacksmith');
expect(scope.contribText({level: 9, text: 'Blacksmith'})).to.eql('Heroic Blacksmith');
expect(scope.contribText({level: 9, text: 'Blacksmith'}, {npc: 'NPC'})).to.eql('NPC');
});
});
describe('castEnd', function(){
var task_target, type;
beforeEach(function(){
task_target = {
id: 'task-id',
text: 'task'
};
type = 'task';
scope.spell = {
target: 'task',
key: 'fireball',
mana: 10,
text: function() { return env.t('spellWizardFireballText') },
cast: function(){}
};
rootscope.applyingAction = true;
});
context('fails', function(){
it('exits early if there is no applying action', function(){
rootscope.applyingAction = null;
expect(scope.castEnd(task_target, type)).to.be.eql('No applying action');
});
it('sends notification if target is invalid', function(){
scope.spell.target = 'not_the_same_target';
scope.castEnd(task_target, type);
notification.text.should.have.been.calledWith(window.env.t('invalidTarget'));
});
});
context('succeeds', function(){
it('sets scope.spell and rootScope.applyingAction to falsy values', function(){
scope.castEnd(task_target, type);
expect(rootscope.applyingAction).to.eql(false);
expect(scope.spell).to.eql(null);
});
it('calls $scope.spell.cast', function(){
// Kind of a hack, would prefer to use sinon.spy,
// but scope.spell gets turned to null in scope.castEnd
var spellWasCast = false;
scope.spell.cast = function(){ spellWasCast = true };
scope.castEnd(task_target, type);
expect(spellWasCast).to.eql(true);
});
it('calls cast endpoint', function() {
$httpBackend.expectPOST(/cast/).respond(201);
scope.castEnd(task_target, type);
$httpBackend.flush();
});
it('sends notification that spell was cast on task', function() {
$httpBackend.expectPOST(/cast/).respond(201);
scope.castEnd(task_target, type);
$httpBackend.flush();
expect(notification.markdown).to.be.calledOnce;
expect(notification.markdown).to.be.calledWith('You cast Burst of Flames on task.');
expect(User.sync).to.be.calledOnce;
});
it('sends notification that spell was cast on user', function() {
var user_target = {
profile: { name: 'Lefnire' }
};
scope.spell = {
target: 'user',
key: 'snowball',
mana: 0,
text: function() { return env.t('spellSpecialSnowballAuraText') },
cast: function(){}
};
$httpBackend.expectPOST(/cast/).respond(201);
scope.castEnd(user_target, 'user');
$httpBackend.flush();
expect(notification.markdown).to.be.calledOnce;
expect(notification.markdown).to.be.calledWith('You cast Snowball on Lefnire.');
expect(User.sync).to.be.calledOnce;
});
it('sends notification that spell was cast on party', function() {
var party_target = {};
scope.spell = {
target: 'party',
key: 'healAll',
mana: 25,
text: function() { return env.t('spellHealerHealAllText') },
cast: function(){}
};
$httpBackend.expectPOST(/cast/).respond(201);
scope.castEnd(party_target, 'party');
$httpBackend.flush();
expect(notification.markdown).to.be.calledOnce;
expect(notification.markdown).to.be.calledWith('You cast Blessing for the party.');
expect(User.sync).to.be.calledOnce;
});
it('sends notification that spell was cast on self', function() {
var self_target = {};
scope.spell = {
target: 'self',
key: 'stealth',
mana: 45,
text: function() { return env.t('spellRogueStealthText') },
cast: function(){}
};
$httpBackend.expectPOST(/cast/).respond(201);
scope.castEnd(self_target, 'self');
$httpBackend.flush();
expect(notification.markdown).to.be.calledOnce;
expect(notification.markdown).to.be.calledWith('You cast Stealth.');
expect(User.sync).to.be.calledOnce;
});
});
});
});
@@ -0,0 +1,28 @@
'use strict';
describe('focusMe Directive', function() {
var element, scope;
beforeEach(module('habitrpg'));
beforeEach(inject(function($rootScope, $compile) {
scope = $rootScope.$new();
element = "<input focus-me></input>";
element = $compile(element)(scope);
scope.$digest();
}));
it('focuses the element when appended to the DOM', function() {
inject(function($timeout) {
var focusSpy = sinon.spy();
element.appendTo(document.body);
element.on('focus', focusSpy);
$timeout.flush();
expect(focusSpy).to.have.been.called;
});
});
});
@@ -0,0 +1,89 @@
'use strict';
describe('fromNow Directive', function() {
var element, scope;
var fromNow = 'recently';
var diff = 0;
beforeEach(module('habitrpg'));
beforeEach(inject(function($rootScope, $compile) {
scope = $rootScope.$new();
scope.message = {};
sinon.stub(window, 'moment').returns({
fromNow: function() { return fromNow },
diff: function() { return diff }
});
element = "<p from-now></p>";
element = $compile(element)(scope);
scope.$digest();
}));
afterEach(function() {
window.moment.restore();
});
it('sets the element text to the elapsed time', function() {
expect(element.text()).to.eql('recently');
});
describe('when the elapsed time is less than an hour', function() {
beforeEach(inject(function($compile) {
fromNow = 'recently';
diff = 0;
element = $compile('<p from-now></p>')(scope);
scope.$digest();
}));
it('updates the elapsed time every minute', inject(function($interval) {
fromNow = 'later';
expect(element.text()).to.eql('recently');
$interval.flush(60001);
expect(element.text()).to.eql('later');
}));
it('moves to hourly updates after an hour', inject(function($timeout, $interval) {
diff = 61;
$timeout.flush();
$interval.flush(60001);
fromNow = 'later';
$interval.flush(60001);
expect(element.text()).to.eql('recently');
$interval.flush(3600000);
expect(element.text()).to.eql('later');
}));
});
describe('when the elapsed time is more than an hour', function() {
beforeEach(inject(function($compile) {
fromNow = 'recently';
diff = 65;
element = $compile('<p from-now></p>')(scope);
scope.$digest();
}));
it('updates the elapsed time every hour', inject(function($interval) {
fromNow = 'later';
expect(element.text()).to.eql('recently');
$interval.flush(60001);
expect(element.text()).to.eql('recently');
$interval.flush(3600000);
expect(element.text()).to.eql('later');
}));
});
});
@@ -0,0 +1,33 @@
describe('roundLargeNumbers', function() {
beforeEach(module('habitrpg'));
it('returns same number if less than 1000', inject(function(roundLargeNumbersFilter) {
for(var num = 0; num < 1000; num++) {
expect(roundLargeNumbersFilter(num)).to.eql(num);
};
}));
it('truncates number and appends "k" if number is 1000-999999', inject(function(roundLargeNumbersFilter) {
expect(roundLargeNumbersFilter(999.01)).to.eql("1.0k");
expect(roundLargeNumbersFilter(1000)).to.eql("1.0k");
expect(roundLargeNumbersFilter(3284.12)).to.eql("3.3k");
expect(roundLargeNumbersFilter(52983.99)).to.eql("53.0k");
expect(roundLargeNumbersFilter(452983.99)).to.eql("453.0k");
expect(roundLargeNumbersFilter(999999)).to.eql("1000.0k");
}));
it('truncates number and appends "m" if number is 1000000-999999999', inject(function(roundLargeNumbersFilter) {
expect(roundLargeNumbersFilter(999999.01)).to.eql("1.0m");
expect(roundLargeNumbersFilter(1000000)).to.eql("1.0m");
expect(roundLargeNumbersFilter(3284124.12)).to.eql("3.3m");
expect(roundLargeNumbersFilter(52983105.99)).to.eql("53.0m");
expect(roundLargeNumbersFilter(452983410.99)).to.eql("453.0m");
expect(roundLargeNumbersFilter(999999999)).to.eql("1000.0m");
}));
it('truncates number and appends b" if number is greater than 999999999', inject(function(roundLargeNumbersFilter) {
expect(roundLargeNumbersFilter(999999999.01)).to.eql("1.0b");
expect(roundLargeNumbersFilter(1423985738.54)).to.eql("1.4b");
}));
});
+35
View File
@@ -0,0 +1,35 @@
describe('filter', function() {
beforeEach(module('habitrpg'));
describe('gold', function() {
it('rounds down decimal values', inject(function(goldFilter) {
expect(goldFilter(10)).to.eql(10);
expect(goldFilter(10.0)).to.eql(10);
expect(goldFilter(10.1)).to.eql(10);
expect(goldFilter(10.2)).to.eql(10);
expect(goldFilter(10.3)).to.eql(10);
expect(goldFilter(10.4)).to.eql(10);
expect(goldFilter(10.5)).to.eql(10);
expect(goldFilter(10.6)).to.eql(10);
expect(goldFilter(10.7)).to.eql(10);
expect(goldFilter(10.8)).to.eql(10);
expect(goldFilter(10.9)).to.eql(10);
expect(goldFilter(11)).to.eql(11);
}));
});
describe('silver', function() {
it('converts decimal value of gold to silver', inject(function(silverFilter) {
expect(silverFilter(10)).to.be.closeTo(0, 1);
expect(silverFilter(10.01)).to.be.closeTo(1, 1);
expect(silverFilter(10.05)).to.be.closeTo(5, 1);
expect(silverFilter(10.17)).to.be.closeTo(17, 1);
expect(silverFilter(10.23)).to.be.closeTo(23, 1);
expect(silverFilter(10.25)).to.be.closeTo(25, 1);
expect(silverFilter(10.53)).to.be.closeTo(53, 1);
expect(silverFilter(10.75)).to.be.closeTo(75, 1);
expect(silverFilter(10.99)).to.be.closeTo(99, 1);
}));
});
});
+54
View File
@@ -0,0 +1,54 @@
'use strict';
describe('Task Ordering Filters', function() {
var filter
, orderBySpy = sinon.spy();
beforeEach(function() {
module(function($provide) {
$provide.value('orderByFilter', orderBySpy);
});
inject(function($rootScope, $filter) {
filter = $filter;
});
});
describe('conditionalOrderBy', function() {
describe('when the predicate is true', function() {
it('delegates the arguments to the orderBy filter', function() {
filter('conditionalOrderBy')('array', true, 'sortPredicate', 'reverseOrder');
expect(orderBySpy).to.have.been.calledWith('array','sortPredicate','reverseOrder');
});
});
describe('when the predicate is false', function() {
it('returns the initial array', function() {
expect(filter('conditionalOrderBy')([1,2,3], false)).to.eql([1,2,3]);
});
});
});
describe('filterByTextAndNotes', function () {
it('returns undefined when no input given', function () {
expect(filter('filterByTextAndNotes')()).to.eql(undefined);
});
it('returns input if term is not a string', function () {
var input = [1, 2, 3];
expect(filter('filterByTextAndNotes')(input, '')).to.eql(input);
expect(filter('filterByTextAndNotes')(input, undefined)).to.eql(input);
expect(filter('filterByTextAndNotes')(input, [])).to.eql(input);
expect(filter('filterByTextAndNotes')(input, new Date())).to.eql(input);
});
it('filters items by notes and text', function () {
var tasks = [
{ text: 'foo' },
{ text: 'foo', notes: 'bar' }
];
expect(filter('filterByTextAndNotes')(tasks, 'bar')).to.eql([tasks[1]]);
expect(filter('filterByTextAndNotes')(tasks, 'foo')).to.eql([tasks[0], tasks[1]]);
});
});
});
-28
View File
@@ -1,28 +0,0 @@
'use strict';
describe('Filters Controller', function() {
var scope, user;
beforeEach(inject(function($rootScope, $controller, Shared) {
user = specHelper.newUser();
Shared.wrap(user);
scope = $rootScope.$new();
$controller('FiltersCtrl', {$scope: scope, User: {user: user}});
}));
it('creates a tag', function(){
scope._newTag = {name:'tagName'}
scope.createTag();
expect(user.tags).to.have.length(1);
expect(user.tags[0].name).to.eql('tagName');
expect(user.tags[0]).to.have.property('id');
});
it('toggles tag filtering', inject(function(Shared){
var tag = {id: Shared.uuid(), name: 'myTag'};
scope.toggleFilter(tag);
expect(user.filters[tag.id]).to.eql(true);
scope.toggleFilter(tag);
expect(user.filters[tag.id]).to.eql(false);
}))
});
-30
View File
@@ -1,30 +0,0 @@
'use strict';
describe('Custom Filters', function() {
var filter
, orderBySpy = sinon.spy();
beforeEach(function() {
module(function($provide) {
$provide.value('orderByFilter', orderBySpy);
});
inject(function($rootScope, $filter) {
filter = $filter;
});
});
describe('conditionalOrderBy', function() {
describe('when the predicate is true', function() {
it('delegates the arguments to the orderBy filter', function() {
filter('conditionalOrderBy')('array', true, 'sortPredicate', 'reverseOrder');
expect(orderBySpy).to.have.been.calledWith('array','sortPredicate','reverseOrder');
});
});
describe('when the predicate is false', function() {
it('returns the initial array', function() {
expect(filter('conditionalOrderBy')([1,2,3], false)).to.eql([1,2,3]);
});
});
});
});
+30
View File
@@ -0,0 +1,30 @@
'use strict'
//Adapted from http://stackoverflow.com/questions/23785603/angularjs-testing-with-jasmine-and-mixpanel
// @TODO: replace with an injectable mixpanel instance for testing
var MixpanelMock;
MixpanelMock = (function() {
function MixpanelMock() {}
MixpanelMock.prototype.track = function() {
return console.log("mixpanel.track", arguments);
};
MixpanelMock.prototype.register_once = function() {
return console.log("mixpanel.register_once", arguments);
};
MixpanelMock.prototype.identify = function() {
return console.log("mixpanel.identify", arguments);
};
MixpanelMock.prototype.register = function() {
return console.log("mixpanel.register", arguments);
};
return MixpanelMock;
})();
window.mixpanel = new MixpanelMock();
-25
View File
@@ -1,25 +0,0 @@
'use strict';
//TODO mock bootstrapGrowl, add remaining tests
describe('notificationServices', function() {
var notification;
beforeEach(function() {
module(function($provide){
$provide.value('User', {});
});
inject(function(Notification) {
notification = Notification;
});
});
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.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);
});
});
-38
View File
@@ -1,38 +0,0 @@
'use strict';
// @TODO: Something here is calling a full page reload
describe('Root Controller', function() {
var scope, user, ctrl;
beforeEach(function () {
module(function($provide) {
$provide.value('User', {});
});
inject(function($rootScope, $controller) {
scope = $rootScope.$new();
scope.loginUsername = 'user'
scope.loginPassword = 'pass'
user = specHelper.newUser();
ctrl = $controller('RootCtrl', {$scope: scope, User: {user: user}});
});
});
it('shows contributor level text', function(){
expect(scope.contribText()).to.eql(undefined);
expect(scope.contribText(null, {npc: 'NPC'})).to.eql('NPC');
expect(scope.contribText({level: 0, text: 'Blacksmith'})).to.eql(undefined);
expect(scope.contribText({level: 1, text: 'Blacksmith'})).to.eql('Friend Blacksmith');
expect(scope.contribText({level: 2, text: 'Blacksmith'})).to.eql('Friend Blacksmith');
expect(scope.contribText({level: 3, text: 'Blacksmith'})).to.eql('Elite Blacksmith');
expect(scope.contribText({level: 4, text: 'Blacksmith'})).to.eql('Elite Blacksmith');
expect(scope.contribText({level: 5, text: 'Blacksmith'})).to.eql('Champion Blacksmith');
expect(scope.contribText({level: 6, text: 'Blacksmith'})).to.eql('Champion Blacksmith');
expect(scope.contribText({level: 7, text: 'Blacksmith'})).to.eql('Legendary Blacksmith');
expect(scope.contribText({level: 8, text: 'Blacksmith'})).to.eql('Guardian Blacksmith');
expect(scope.contribText({level: 9, text: 'Blacksmith'})).to.eql('Heroic Blacksmith');
expect(scope.contribText({level: 9, text: 'Blacksmith'}, {npc: 'NPC'})).to.eql('NPC');
});
});
@@ -0,0 +1,208 @@
'use strict';
describe('notificationServices', function() {
var notification;
before(function(){
sinon.stub($, 'pnotify', function(){
return { click: function(){}}
});
});
beforeEach(function() {
module(function($provide){
$provide.value('User', {});
});
inject(function(Notification) {
notification = Notification;
});
});
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('sends 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('sends 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('sends 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('sends 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('sends 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('sends 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('sends 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('sends 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('sends 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('sends 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;
});
});
+1 -1
View File
@@ -13,7 +13,7 @@ specHelper = {
food: {},
pets: {},
mounts: {},
gear: {equipped: {}, costume: {}},
gear: {equipped: {}, costume: {}, owned: {}},
},
party: {
quest: {