diff --git a/test/spec/controllers/autocompleteCtrlSpec.js b/test/spec/controllers/autocompleteCtrlSpec.js new file mode 100644 index 0000000000..2acf1f585b --- /dev/null +++ b/test/spec/controllers/autocompleteCtrlSpec.js @@ -0,0 +1,120 @@ +'use strict'; + +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 = sandbox.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 = sandbox.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); + }); + }); +}); diff --git a/test/spec/controllers/chatCtrlSpec.js b/test/spec/controllers/chatCtrlSpec.js new file mode 100644 index 0000000000..81a19f8efc --- /dev/null +++ b/test/spec/controllers/chatCtrlSpec.js @@ -0,0 +1,72 @@ +'use strict'; + +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 = sandbox.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 = sandbox.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 + })); + }); + }); +}); + diff --git a/test/spec/controllers/copyMessageModalControllerSpec.js b/test/spec/controllers/copyMessageModalControllerSpec.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/spec/controllers/groupCtrlSpec.js b/test/spec/controllers/groupCtrlSpec.js index dbe085fd07..c214c8ed9f 100644 --- a/test/spec/controllers/groupCtrlSpec.js +++ b/test/spec/controllers/groupCtrlSpec.js @@ -71,375 +71,3 @@ describe('Groups Controller', function() { }); }); }); - -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 = sandbox.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 = sandbox.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 = sandbox.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 = sandbox.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: sandbox.spy() - }; - - scope = $rootScope.$new(); - scope.$close = sandbox.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 = sandbox.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; - }); - }); -}); - -describe("Party Controller", function() { - var scope, ctrl, user, User, groups, $rootScope, $controller; - - beforeEach(function() { - user = specHelper.newUser(), - user._id = "unique-user-id"; - User = { - user: user, - sync: sinon.spy - } - - module(function($provide) { - $provide.value('User', User); - }); - - inject(function(_$rootScope_, _$controller_, Groups){ - - $rootScope = _$rootScope_; - - scope = _$rootScope_.$new(); - - $controller = _$controller_; - - groups = Groups; - - // Load RootCtrl to ensure shared behaviors are loaded - $controller('RootCtrl', {$scope: scope, User: User}); - - ctrl = $controller('PartyCtrl', {$scope: scope, User: User}); - }); - }); - - describe('questAccept', function() { - it('calls Groups.questAccept', function() { - var party = {}; - var groupSpy = sinon.stub(groups, "questAccept", function(){return true;}); - scope.questAccept(party); - groupSpy.should.have.been.calledOnce; - }); - }); - - describe('questReject', function() { - it('calls Groups.questReject', function() { - var party = {}; - var groupSpy = sinon.stub(groups, "questReject", function(){return true;}); - scope.questReject(party); - groupSpy.should.have.been.calledOnce; - }); - }); - - describe('questCancel', function() { - var party, cancelSpy, windowSpy; - beforeEach(function() { - party = {}; - cancelSpy = sinon.stub(groups, "questCancel", function(){return true;}); - }); - - afterEach(function() { - windowSpy.restore(); - cancelSpy.restore(); - }); - - it('calls Groups.questCancel when alert box is confirmed', function() { - windowSpy = sinon.stub(window, "confirm", function(){return true}); - - scope.questCancel(party); - windowSpy.should.have.been.calledOnce; - windowSpy.should.have.been.calledWith(window.env.t('sureCancel')); - cancelSpy.should.have.been.calledOnce; - }); - - it('does not call Groups.questCancel when alert box is confirmed', function() { - windowSpy = sinon.stub(window, "confirm", function(){return false}); - - scope.questCancel(party); - windowSpy.should.have.been.calledOnce; - cancelSpy.should.not.have.been.calledOnce; - }); - }); - - describe('questAbort', function() { - var party, abortSpy, windowSpy; - beforeEach(function() { - party = {}; - abortSpy = sinon.stub(groups, "questAbort", function(){return true;}); - }); - - afterEach(function() { - windowSpy.restore(); - abortSpy.restore(); - }); - - it('calls Groups.questAbort when two alert boxes are confirmed', function() { - windowSpy = sinon.stub(window, "confirm", function(){return true}); - - scope.questAbort(party); - windowSpy.should.have.been.calledTwice; - windowSpy.should.have.been.calledWith(window.env.t('sureAbort')); - windowSpy.should.have.been.calledWith(window.env.t('doubleSureAbort')); - abortSpy.should.have.been.calledOnce; - }); - - it('does not call Groups.questAbort when first alert box is not confirmed', function() { - windowSpy = sinon.stub(window, "confirm", function(){return false}); - - scope.questAbort(party); - windowSpy.should.have.been.calledOnce; - windowSpy.should.have.been.calledWith(window.env.t('sureAbort')); - windowSpy.should.not.have.been.calledWith(window.env.t('doubleSureAbort')); - abortSpy.should.not.have.been.calledOnce; - }); - - it('does not call Groups.questAbort when first alert box is confirmed but second one is not', function() { - // Hack to confirm first window, but not second - var shouldReturn = false; - windowSpy = sinon.stub(window, "confirm", function(){ - shouldReturn = !shouldReturn; - return shouldReturn; - }); - - scope.questAbort(party); - windowSpy.should.have.been.calledTwice; - windowSpy.should.have.been.calledWith(window.env.t('sureAbort')); - windowSpy.should.have.been.calledWith(window.env.t('doubleSureAbort')); - abortSpy.should.not.have.been.calledOnce; - }); - }); -}); diff --git a/test/spec/controllers/partyCtrlSpec.js b/test/spec/controllers/partyCtrlSpec.js new file mode 100644 index 0000000000..4220c008f9 --- /dev/null +++ b/test/spec/controllers/partyCtrlSpec.js @@ -0,0 +1,130 @@ +'use strict'; + +describe("Party Controller", function() { + var scope, ctrl, user, User, groups, $rootScope, $controller; + + beforeEach(function() { + user = specHelper.newUser(), + user._id = "unique-user-id"; + User = { + user: user, + sync: sinon.spy + } + + module(function($provide) { + $provide.value('User', User); + }); + + inject(function(_$rootScope_, _$controller_, Groups){ + + $rootScope = _$rootScope_; + + scope = _$rootScope_.$new(); + + $controller = _$controller_; + + groups = Groups; + + // Load RootCtrl to ensure shared behaviors are loaded + $controller('RootCtrl', {$scope: scope, User: User}); + + ctrl = $controller('PartyCtrl', {$scope: scope, User: User}); + }); + }); + + describe('questAccept', function() { + it('calls Groups.questAccept', function() { + var party = {}; + var groupSpy = sinon.stub(groups, "questAccept", function(){return true;}); + scope.questAccept(party); + groupSpy.should.have.been.calledOnce; + }); + }); + + describe('questReject', function() { + it('calls Groups.questReject', function() { + var party = {}; + var groupSpy = sinon.stub(groups, "questReject", function(){return true;}); + scope.questReject(party); + groupSpy.should.have.been.calledOnce; + }); + }); + + describe('questCancel', function() { + var party, cancelSpy, windowSpy; + beforeEach(function() { + party = {}; + cancelSpy = sinon.stub(groups, "questCancel", function(){return true;}); + }); + + afterEach(function() { + windowSpy.restore(); + cancelSpy.restore(); + }); + + it('calls Groups.questCancel when alert box is confirmed', function() { + windowSpy = sinon.stub(window, "confirm", function(){return true}); + + scope.questCancel(party); + windowSpy.should.have.been.calledOnce; + windowSpy.should.have.been.calledWith(window.env.t('sureCancel')); + cancelSpy.should.have.been.calledOnce; + }); + + it('does not call Groups.questCancel when alert box is confirmed', function() { + windowSpy = sinon.stub(window, "confirm", function(){return false}); + + scope.questCancel(party); + windowSpy.should.have.been.calledOnce; + cancelSpy.should.not.have.been.calledOnce; + }); + }); + + describe('questAbort', function() { + var party, abortSpy, windowSpy; + beforeEach(function() { + party = {}; + abortSpy = sinon.stub(groups, "questAbort", function(){return true;}); + }); + + afterEach(function() { + windowSpy.restore(); + abortSpy.restore(); + }); + + it('calls Groups.questAbort when two alert boxes are confirmed', function() { + windowSpy = sinon.stub(window, "confirm", function(){return true}); + + scope.questAbort(party); + windowSpy.should.have.been.calledTwice; + windowSpy.should.have.been.calledWith(window.env.t('sureAbort')); + windowSpy.should.have.been.calledWith(window.env.t('doubleSureAbort')); + abortSpy.should.have.been.calledOnce; + }); + + it('does not call Groups.questAbort when first alert box is not confirmed', function() { + windowSpy = sinon.stub(window, "confirm", function(){return false}); + + scope.questAbort(party); + windowSpy.should.have.been.calledOnce; + windowSpy.should.have.been.calledWith(window.env.t('sureAbort')); + windowSpy.should.not.have.been.calledWith(window.env.t('doubleSureAbort')); + abortSpy.should.not.have.been.calledOnce; + }); + + it('does not call Groups.questAbort when first alert box is confirmed but second one is not', function() { + // Hack to confirm first window, but not second + var shouldReturn = false; + windowSpy = sinon.stub(window, "confirm", function(){ + shouldReturn = !shouldReturn; + return shouldReturn; + }); + + scope.questAbort(party); + windowSpy.should.have.been.calledTwice; + windowSpy.should.have.been.calledWith(window.env.t('sureAbort')); + windowSpy.should.have.been.calledWith(window.env.t('doubleSureAbort')); + abortSpy.should.not.have.been.calledOnce; + }); + }); +});