(function (root, factory) { define([ "mock", "utils" ], function (mock, utils) { return factory(mock, utils); } ); } (this, function (mock, utils) { var spec_callback = function(mock, utils) { describe("The Control Box", $.proxy(function () { it("is not shown by default", $.proxy(function () { expect(this.rosterview.$el.is(':visible')).toEqual(false); }, converse)); var open_controlbox = $.proxy(function () { // This spec will only pass if the controlbox is not currently // open yet. expect($("div#controlbox").is(':visible')).toBe(false); spyOn(this.controlboxtoggle, 'onClick').andCallThrough(); spyOn(this.controlboxtoggle, 'showControlBox').andCallThrough(); // Redelegate so that the spies are now registered as the event handlers (specifically for 'onClick') this.controlboxtoggle.delegateEvents(); $('.toggle-online-users').click(); expect(this.controlboxtoggle.onClick).toHaveBeenCalled(); expect(this.controlboxtoggle.showControlBox).toHaveBeenCalled(); expect($("div#controlbox").is(':visible')).toBe(true); }, converse); it("can be opened by clicking a DOM element with class 'toggle-online-users'", open_controlbox); describe("The Status Widget", $.proxy(function () { it("shows the user's chat status, which is online by default", $.proxy(function () { var view = this.xmppstatusview; expect(view.$el.find('a.choose-xmpp-status').hasClass('online')).toBe(true); expect(view.$el.find('a.choose-xmpp-status').attr('data-value')).toBe('I am online'); }, converse)); it("can be used to set the current user's chat status", $.proxy(function () { var view = this.xmppstatusview; spyOn(view, 'toggleOptions').andCallThrough(); spyOn(view, 'setStatus').andCallThrough(); view.delegateEvents(); // We need to rebind all events otherwise our spy won't be called runs(function () { view.$el.find('a.choose-xmpp-status').click(); expect(view.toggleOptions).toHaveBeenCalled(); }); waits(250); runs(function () { spyOn(view, 'updateStatusUI').andCallThrough(); view.initialize(); // Rebind events for spy $(view.$el.find('.dropdown dd ul li a')[1]).click(); expect(view.setStatus).toHaveBeenCalled(); }); waits(250); runs($.proxy(function () { expect(view.updateStatusUI).toHaveBeenCalled(); expect(view.$el.find('a.choose-xmpp-status').hasClass('online')).toBe(false); expect(view.$el.find('a.choose-xmpp-status').hasClass('dnd')).toBe(true); expect(view.$el.find('a.choose-xmpp-status').attr('data-value')).toBe('I am busy'); }, converse)); }, converse)); it("can be used to set a custom status message", $.proxy(function () { var view = this.xmppstatusview; this.xmppstatus.save({'status': 'online'}); spyOn(view, 'setStatusMessage').andCallThrough(); spyOn(view, 'renderStatusChangeForm').andCallThrough(); view.delegateEvents(); // We need to rebind all events otherwise our spy won't be called view.$el.find('a.change-xmpp-status-message').click(); expect(view.renderStatusChangeForm).toHaveBeenCalled(); // The async testing here is used only to provide time for // visual feedback var msg = 'I am happy'; runs (function () { view.$el.find('form input.custom-xmpp-status').val(msg); }); waits(250); runs (function () { view.$el.find('form#set-custom-xmpp-status').submit(); expect(view.setStatusMessage).toHaveBeenCalled(); expect(view.$el.find('a.choose-xmpp-status').hasClass('online')).toBe(true); expect(view.$el.find('a.choose-xmpp-status').attr('data-value')).toBe(msg); }); }, converse)); }, converse)); }, converse)); describe("The Contacts Roster", $.proxy(function () { describe("Pending Contacts", $.proxy(function () { beforeEach(function () { if (!$("div#controlbox").is(':visible')) { $('.toggle-online-users').click(); } }); it("do not have a heading if there aren't any", $.proxy(function () { expect(this.rosterview.$el.find('dt#pending-xmpp-contacts').css('display')).toEqual('none'); }, converse)); it("can be added to the roster", $.proxy(function () { spyOn(this.rosterview, 'render').andCallThrough(); this.roster.create({ jid: mock.pend_names[0].replace(/ /g,'.').toLowerCase() + '@localhost', subscription: 'none', ask: 'subscribe', fullname: mock.pend_names[0], is_last: true }); expect(this.rosterview.$el.is(':visible')).toEqual(true); expect(this.rosterview.render).toHaveBeenCalled(); }, converse)); it("can be removed by the user", $.proxy(function () { var view = _.toArray(this.rosterview.rosteritemviews).pop(); spyOn(window, 'confirm').andReturn(true); spyOn(this.connection.roster, 'remove').andCallThrough(); spyOn(this.connection.roster, 'unauthorize'); spyOn(this.rosterview.model, 'remove').andCallThrough(); //spyOn(view, 'removeContact').andCallThrough(); runs($.proxy(function () { view.$el.find('.remove-xmpp-contact').click(); }, converse)); waits(500); runs($.proxy(function () { expect(window.confirm).toHaveBeenCalled(); //expect(view.removeContact).toHaveBeenCalled(); expect(this.connection.roster.remove).toHaveBeenCalled(); expect(this.connection.roster.unauthorize).toHaveBeenCalled(); expect(this.rosterview.model.remove).toHaveBeenCalled(); // The element must now be detached from the DOM. expect(view.$el.closest('html').length).toBeFalsy(); }, converse)); }, converse)); it("will lose their own heading once the last one has been removed", $.proxy(function () { expect(this.rosterview.$el.find('dt#pending-xmpp-contacts').is(':visible')).toBeFalsy(); }, converse)); it("can be added to the roster and they will be sorted alphabetically", $.proxy(function () { var i, t, is_last; spyOn(this.rosterview, 'render').andCallThrough(); for (i=0; i