Organized spec folder

This commit is contained in:
Blade Barringer
2015-06-13 09:58:08 -05:00
parent 5d56bd02ef
commit 719907189f
14 changed files with 3 additions and 3 deletions
+36
View File
@@ -0,0 +1,36 @@
'use strict';
describe('Auth Controller', function() {
describe('AuthCtrl', function(){
var scope, ctrl, user, $httpBackend, $window;
beforeEach(inject(function(_$httpBackend_, $rootScope, $controller) {
$httpBackend = _$httpBackend_;
scope = $rootScope.$new();
scope.loginUsername = 'user';
scope.loginPassword = 'pass';
$window = { location: { href: ""}, alert: sinon.spy() };
user = { user: {}, authenticate: sinon.spy() };
ctrl = $controller('AuthCtrl', {$scope: scope, $window: $window, User: user});
}));
it('should log in users with correct uname / pass', function() {
$httpBackend.expectPOST('/api/v2/user/auth/local').respond({id: 'abc', token: 'abc'});
scope.auth();
$httpBackend.flush();
sinon.assert.calledOnce(user.authenticate);
sinon.assert.notCalled($window.alert);
});
it('should not log in users with incorrect uname / pass', function() {
$httpBackend.expectPOST('/api/v2/user/auth/local').respond(404, '');
scope.auth();
$httpBackend.flush();
sinon.assert.notCalled(user.authenticate);
sinon.assert.calledOnce($window.alert);
});
});
});
+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);
});
});
});
+312
View File
@@ -0,0 +1,312 @@
'use strict';
describe('Groups Controller', function() {
var scope, ctrl, groups, user, guild, party, $rootScope;
beforeEach(function() {
module(function($provide) {
$provide.value('User', {});
});
inject(function($rootScope, $controller, 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('GroupsCtrl', {$scope: scope, User: {user: user}});
groups = Groups;
});
});
describe("isMemberOfGroup", function() {
it("returns true if group is the user's party", function() {
party = specHelper.newGroup("test-party");
party._id = "unique-party-id";
party.type = 'party';
party.members = []; // Ensure we wouldn't pass automatically.
var partyStub = sinon.stub(groups,"party", function() {
return party;
});
expect(scope.isMemberOfGroup(user._id, party)).to.be.ok;
});
it('returns true if guild is included in myGuilds call', function(){
guild = specHelper.newGroup("leaders-user-id");
guild._id = "unique-guild-id";
guild.type = 'guild';
guild.members.push(user._id);
var myGuilds = sinon.stub(groups,"myGuilds", function() {
return [guild];
});
expect(scope.isMemberOfGroup(user._id, guild)).to.be.ok;
expect(myGuilds).to.be.called;
});
it('does not return true if guild is not included in myGuilds call', function(){
guild = specHelper.newGroup("leaders-user-id");
guild._id = "unique-guild-id";
guild.type = 'guild';
var myGuilds = sinon.stub(groups,"myGuilds", function() {
return [];
});
expect(scope.isMemberOfGroup(user._id, guild)).to.not.be.ok;
expect(myGuilds).to.be.called;
});
});
});
describe("Chat Controller", function() {
var scope, ctrl, user, $rootScope, $controller;
beforeEach(function() {
module(function($provide) {
$provide.value('User', {});
});
inject(function(_$rootScope_, _$controller_){
user = specHelper.newUser();
user._id = "unique-user-id";
$rootScope = _$rootScope_;
scope = _$rootScope_.$new();
$controller = _$controller_;
// Load RootCtrl to ensure shared behaviors are loaded
$controller('RootCtrl', {$scope: scope, User: {user: user}});
ctrl = $controller('ChatCtrl', {$scope: scope});
});
});
describe('copyToDo', function() {
it('when copying a user message it opens modal with information from message', function() {
scope.group = {
name: "Princess Bride"
};
var modalSpy = sinon.spy($rootScope, "openModal");
var message = {
uuid: 'the-dread-pirate-roberts',
user: 'Wesley',
text: 'As you wish'
};
scope.copyToDo(message);
modalSpy.should.have.been.calledOnce;
modalSpy.should.have.been.calledWith('copyChatToDo', sinon.match(function(callArgToMatch){
return callArgToMatch.controller == 'CopyMessageModalCtrl'
&& callArgToMatch.scope.text == message.text
}));
});
it('when copying a system message it opens modal with information from message', function() {
scope.group = {
name: "Princess Bride"
};
var modalSpy = sinon.spy($rootScope, "openModal");
var message = {
uuid: 'system',
text: 'Wesley attacked the ROUS in the Fire Swamp'
};
scope.copyToDo(message);
modalSpy.should.have.been.calledOnce;
modalSpy.should.have.been.calledWith('copyChatToDo', sinon.match(function(callArgToMatch){
return callArgToMatch.controller == 'CopyMessageModalCtrl'
&& callArgToMatch.scope.text == message.text
}));
});
});
});
describe("Autocomplete controller", function() {
var scope, ctrl, user, $rootScope, $controller;
beforeEach(function() {
module(function($provide) {
$provide.value('User', {});
});
inject(function($rootScope, _$controller_){
user = specHelper.newUser();
user._id = "unique-user-id";
scope = $rootScope.$new();
scope.group = {}
scope.group.chat = [];
$controller = _$controller_;
// Load RootCtrl to ensure shared behaviors are loaded
$controller('RootCtrl', {$scope: scope, User: {user: user}});
ctrl = $controller('AutocompleteCtrl', {$scope: scope});
});
});
describe("clearUserList", function() {
it('calling the function clears the list of usernames and responses', function() {
scope.response.push("blah");
scope.usernames.push("blub");
scope.clearUserlist();
expect(scope.response).to.be.empty;
expect(scope.usernames).to.be.empty;
});
it('the function is called upon initialization of the controller', function() {
scope.response.push("blah");
scope.response.push("blub");
ctrl = $controller('AutocompleteCtrl', {$scope: scope});
expect(scope.response).to.be.empty;
expect(scope.usernames).to.be.empty;
});
})
describe("filterUser", function() {
it('filters with undefined query (not loaded yet) and returns false (so it will not be rendered)', function() {
expect(scope.filterUser({user: "boo"})).to.be.eq(false);
});
it('filters with null query (no typing yet) and returns false (so it will not be rendered)', function() {
scope.query = null
expect(scope.filterUser({user: "boo"})).to.be.eq(false);
});
it('filters with empty prefix and returns true', function() {
scope.query = {text: ""};
expect(scope.filterUser({user: "prefix"})).to.be.eq(true);
});
it('filters with prefix element and returns true', function() {
scope.query = {text: "pre"}
expect(scope.filterUser({user: "prefix"})).to.be.eq(true);
});
it('filters with prefix element of a different case and returns true', function() {
scope.query = {text: "pre"}
expect(scope.filterUser({user: "Prefix"})).to.be.eq(true);
});
it('filters with nonprefix element and returns false', function() {
scope.query = {text: "noprefix"}
expect(scope.filterUser({user: "prefix"})).to.be.eq(false);
});
it('filters out system messages (messages without username)', function() {
scope.query = {text: "myquery"}
expect(scope.filterUser({uuid: "system"})).to.be.eq(false);
});
});
describe("performCompletion", function() {
it('triggers autoComplete', function() {
scope.autoComplete = sinon.spy();
var msg = {user: "boo"}; // scope.autoComplete only cares about user
scope.query = {text: "b"};
scope.performCompletion(msg);
expect(scope.query).to.be.eq(null);
expect(scope.autoComplete.callCount).to.be.eq(1);
expect(scope.autoComplete).to.have.been.calledWith(msg);
});
});
describe("addNewUser", function() {
it('a new message from a new user will modify the usernames', function() {
expect(scope.response).to.be.empty;
expect(scope.usernames).to.be.empty;
var msg = {user: "boo"};
scope.addNewUser(msg);
expect(scope.response[0]).to.be.eq(msg);
expect(scope.usernames[0]).to.be.eq("boo");
});
});
describe("chatChanged", function() {
it('if a new chat arrives, the new user name is extracted', function() {
var chatChanged = sinon.spy(scope, 'chatChanged');
scope.$watch('group.chat',scope.chatChanged); // reinstantiate watch so spy works
scope.$digest(); // trigger watch
scope.group.chat.push({msg: "new chat", user: "boo"});
expect(chatChanged.callCount).to.be.eq(1);
});
});
});
describe("CopyMessageModal controller", function() {
var scope, ctrl, user, Notification, $rootScope, $controller;
beforeEach(function() {
module(function($provide) {
$provide.value('User', {});
});
inject(function($rootScope, _$controller_, _Notification_){
user = specHelper.newUser();
user._id = "unique-user-id";
user.ops = {
addTask: sinon.spy()
};
scope = $rootScope.$new();
scope.$close = sinon.spy();
$controller = _$controller_;
// Load RootCtrl to ensure shared behaviors are loaded
$controller('RootCtrl', {$scope: scope, User: {user: user}});
ctrl = $controller('CopyMessageModalCtrl', {$scope: scope, User: {user: user}});
Notification = _Notification_;
Notification.text = sinon.spy();
});
});
describe("saveTodo", function() {
it('saves todo', function() {
scope.text = "A Tavern msg";
scope.notes = "Some notes";
var payload = {
body: {
text: scope.text,
type: 'todo',
notes: scope.notes
}
};
scope.saveTodo();
user.ops.addTask.should.have.been.calledOnce;
user.ops.addTask.should.have.been.calledWith(payload);
Notification.text.should.have.been.calledOnce;
Notification.text.should.have.been.calledWith(window.env.t('messageAddedAsToDo'));
scope.$close.should.have.been.calledOnce;
});
});
});
+36
View File
@@ -0,0 +1,36 @@
'use strict';
describe('Hall of Heroes Controller', function() {
var scope, ctrl, user, $rootScope;
beforeEach(function() {
module(function($provide) {
$provide.value('User', {});
});
inject(function($rootScope, $controller){
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('HallHeroesCtrl', {$scope: scope, User: {user: user}});
});
});
it('populates contributor input with selected hero id', function(){
var loadHero = sinon.spy(scope, "loadHero");
var scrollTo = sinon.spy(window, "scrollTo");
scope.populateContributorInput(user._id);
expect(scope._heroID).to.eql(user._id);
expect(loadHero.callCount).to.eql(1);
expect(scrollTo.callCount).to.eql(1);
scope.loadHero.restore();
window.scrollTo.restore();
});
});
+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;
});
});
});
@@ -0,0 +1,92 @@
'use strict';
describe('Inventory Controller', function() {
var scope, ctrl, user, $rootScope;
beforeEach(function() {
module(function($provide) {
$provide.value('User', {});
});
inject(function($rootScope, $controller, Shared){
user = specHelper.newUser();
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){
return true;
}
};
scope = $rootScope.$new();
// Load RootCtrl to ensure shared behaviors are loaded
$controller('RootCtrl', {$scope: scope, User: {user: user}, $window: mockWindow});
ctrl = $controller('InventoryCtrl', {$scope: scope, User: {user: user}, $window: mockWindow});
});
});
it('starts without any item selected', function(){
expect(scope.selectedEgg).to.eql(null);
expect(scope.selectedPotion).to.eql(null);
expect(scope.selectedFood).to.eql(undefined);
});
it('chooses an egg', function(){
scope.chooseEgg('Cactus');
expect(scope.selectedEgg.key).to.eql('Cactus');
});
it('chooses a potion', function(){
scope.choosePotion('Base');
expect(scope.selectedPotion.key).to.eql('Base');
});
it('hatches a pet', function(){
scope.chooseEgg('Cactus');
scope.choosePotion('Base');
expect(user.items.eggs).to.eql({Cactus: 0});
expect(user.items.hatchingPotions).to.eql({Base: 0});
expect(user.items.pets).to.eql({'Cactus-Base': 5});
expect(scope.selectedEgg).to.eql(null);
expect(scope.selectedPotion).to.eql(null);
});
it('sells an egg', function(){
scope.chooseEgg('Cactus');
scope.sellInventory();
expect(user.items.eggs).to.eql({Cactus: 0});
expect(user.stats.gp).to.eql(3);
});
it('sells a potion', function(){
scope.choosePotion('Base');
scope.sellInventory();
expect(user.items.hatchingPotions).to.eql({Base: 0});
expect(user.stats.gp).to.eql(2);
});
it('sells food', function(){
scope.chooseFood('Meat');
scope.sellInventory();
expect(user.items.food).to.eql({Meat: 0});
expect(user.stats.gp).to.eql(1);
});
it('chooses a pet', function(){
user.items.pets['Cactus-Base'] = 5;
scope.choosePet('Cactus', 'Base');
expect(user.items.currentPet).to.eql('Cactus-Base');
});
it('purchases an egg', inject(function(Content){
scope.purchase('eggs', Content.eggs['Wolf']);
expect(user.balance).to.eql(3.25);
expect(user.items.eggs).to.eql({Cactus: 1, Wolf: 1})
}));
});
+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;
});
});
});
});