Merge branch 'develop' into hairlessbear-quest_invite_modal_on_user_sync
This commit is contained in:
@@ -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;
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -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){
|
||||
@@ -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");
|
||||
}));
|
||||
});
|
||||
@@ -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);
|
||||
}));
|
||||
});
|
||||
});
|
||||
@@ -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]]);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -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);
|
||||
}))
|
||||
});
|
||||
@@ -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]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -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();
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
@@ -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;
|
||||
});
|
||||
});
|
||||
@@ -13,7 +13,7 @@ specHelper = {
|
||||
food: {},
|
||||
pets: {},
|
||||
mounts: {},
|
||||
gear: {equipped: {}, costume: {}},
|
||||
gear: {equipped: {}, costume: {}, owned: {}},
|
||||
},
|
||||
party: {
|
||||
quest: {
|
||||
|
||||
Reference in New Issue
Block a user