From d2ee62da71c7f693dbd8beb5acdc4757c936882d Mon Sep 17 00:00:00 2001 From: JC Brand Date: Wed, 13 Apr 2016 15:11:04 +0000 Subject: [PATCH] Make sure that there is a valid connection when login API is called In the process I had to refactor some methods which required the mock connection of tests to be changed as well. --- spec/controlbox.js | 1 + spec/converse.js | 33 ++- spec/headline.js | 5 + spec/otr.js | 35 ++-- spec/register.js | 465 ++++++++++++++++++++++--------------------- src/converse-api.js | 1 + src/converse-core.js | 35 ++-- tests/main.js | 10 +- tests/mock.js | 13 +- 9 files changed, 308 insertions(+), 290 deletions(-) diff --git a/spec/controlbox.js b/spec/controlbox.js index 733268963..54300a2d5 100644 --- a/spec/controlbox.js +++ b/spec/controlbox.js @@ -136,6 +136,7 @@ describe("The live filter", $.proxy(function () { beforeEach(function () { test_utils.openControlBox(); + test_utils.openContactsPanel(); }); it("will only appear when roster contacts flow over the visible area", function () { diff --git a/spec/converse.js b/spec/converse.js index b15052ab2..47bf8804e 100644 --- a/spec/converse.js +++ b/spec/converse.js @@ -16,47 +16,40 @@ describe("Authentication", function () { it("needs either a bosh_service_url a websocket_url or both", function () { - converse.connection.connected = false; + var url = converse.bosh_service_url; + var connection = converse.connection; + delete converse.bosh_service_url; + delete converse.connection; expect(converse.initConnection.bind({})).toThrow( new Error("initConnection: you must supply a value for either the bosh_service_url or websocket_url or both.")); - converse.connection.connected = true; + converse.bosh_service_url = url; + converse.connection = connection; }); describe("with prebind", function () { it("needs a jid when also using keepalive", function () { var authentication = converse.authentication; - var connection = converse.connection; var jid = converse.jid; - converse.bosh_service_url = "localhost"; - converse.connection = undefined; - converse.jid = undefined; + delete converse.jid; converse.keepalive = true; converse.authentication = "prebind"; - expect(converse.initConnection.bind(converse)).toThrow( - new Error("initConnection: when using 'keepalive' with 'prebind, you must supply the JID of the current user.")); + expect(converse.logIn.bind(converse)).toThrow( + new Error("attemptPreboundSession: when using 'keepalive' with 'prebind, you must supply the JID of the current user.")); converse.authentication= authentication; - converse.bosh_service_url = undefined; - converse.connection = connection; converse.jid = jid; - converse.keepalive = undefined; + converse.keepalive = false; }); it("needs jid, rid and sid values when not using keepalive", function () { var authentication = converse.authentication; - var connection = converse.connection; var jid = converse.jid; - converse.bosh_service_url = "localhost"; - converse.connection = undefined; - converse.jid = undefined; - converse.keepalive = false; + delete converse.jid; converse.authentication = "prebind"; - expect(converse.initConnection.bind(converse)).toThrow( - new Error("initConnection: If you use prebind and not keepalive, then you MUST supply JID, RID and SID values")); + expect(converse.logIn.bind(converse)).toThrow( + new Error("attemptPreboundSession: If you use prebind and not keepalive, then you MUST supply JID, RID and SID values")); converse.authentication= authentication; converse.bosh_service_url = undefined; - converse.connection = connection; converse.jid = jid; - converse.keepalive = undefined; }); }); }); diff --git a/spec/headline.js b/spec/headline.js index 7029d6859..7e64fcaa5 100644 --- a/spec/headline.js +++ b/spec/headline.js @@ -13,6 +13,11 @@ describe("A headlines box", function () { + beforeEach(function () { + test_utils.openControlBox(); + test_utils.openContactsPanel(); + }); + it("will not open nor display non-headline messages", function () { /* XMPP spam message: * diff --git a/spec/otr.js b/spec/otr.js index b077bfd76..ada2c7a3e 100644 --- a/spec/otr.js +++ b/spec/otr.js @@ -11,34 +11,27 @@ } (this, function ($, mock, test_utils) { var b64_sha1 = converse_api.env.b64_sha1; - return describe("The OTR module", $.proxy(function(mock, test_utils) { + return describe("The OTR module", function() { - beforeEach($.proxy(function () { - window.localStorage.clear(); - window.sessionStorage.clear(); - }, converse)); - - it("can store a session passphrase in session storage", $.proxy(function () { - var pp; + it("can store a session passphrase in session storage", function () { // With no prebind, the user's XMPP password is used and nothing is // stored in session storage. - this.authentication = "manual"; - this.connection.pass = 's3cr3t!'; - expect(this.otr.getSessionPassphrase()).toBe(this.connection.pass); - expect(window.sessionStorage.length).toBe(0); - expect(window.localStorage.length).toBe(0); + var auth = converse.authentication; + var pass = converse.connection.pass; + converse.authentication = "manual"; + converse.connection.pass = 's3cr3t!'; + expect(converse.otr.getSessionPassphrase()).toBe(converse.connection.pass); // With prebind, a random passphrase is generated and stored in // session storage. - this.authentication = "prebind"; - pp = this.otr.getSessionPassphrase(); - expect(pp).not.toBe(this.connection.pass); - expect(window.sessionStorage.length).toBe(1); - expect(window.localStorage.length).toBe(0); + converse.authentication = "prebind"; + var pp = converse.otr.getSessionPassphrase(); + expect(pp).not.toBe(converse.connection.pass); expect(pp).toBe(window.sessionStorage[b64_sha1(converse.connection.jid)]); // Clean up - this.authentication = "manual"; - }, converse)); - }, converse, mock, test_utils)); + converse.authentication = auth; + converse.connection.pass = pass; + }); + }); })); diff --git a/spec/register.js b/spec/register.js index 7055771db..ad7923d10 100644 --- a/spec/register.js +++ b/spec/register.js @@ -1,268 +1,287 @@ /*global converse */ (function (root, factory) { - define([ - "jquery", - "mock", - "test_utils" - ], function ($, mock, test_utils) { - return factory($, mock, test_utils); - } - ); + define(["jquery", "mock", "test_utils"], factory); } (this, function ($, mock, test_utils) { var Strophe = converse_api.env.Strophe; var $iq = converse_api.env.$iq; + var original_connection = converse.connection; - describe("The Registration Panel", $.proxy(function (mock, test_utils) { + describe("The Registration Panel", function () { beforeEach(function () { test_utils.closeControlBox(); - var connection = mock.mock_connection; - connection.connected = false; converse._tearDown(); converse.initialized_plugins = []; - converse.initialize({ - i18n: window.locales.en, - bosh_service_url: 'localhost', - allow_registration: true, - auto_subscribe: false, - animate: false, - connection: connection, - no_trimming: true, - debug: true - }); - test_utils.openControlBox(); - }); - afterEach($.proxy(function () { - this.connection.connected = false; + afterEach(function () { test_utils.closeControlBox(); - }, converse)); + converse.connection = original_connection; + }); - it("is not available unless allow_registration=true", $.proxy(function () { - test_utils.closeControlBox(); - var connection = mock.mock_connection; - connection.connected = false; - converse._tearDown(); - converse.initialized_plugins = []; - converse.initialize({ - i18n: window.locales.en, - animate: false, - auto_subscribe: false, - bosh_service_url: 'localhost', - connection: connection, - no_trimming: true, - allow_registration: false, - debug: true - }); - test_utils.openControlBox(); - var cbview = this.chatboxviews.get('controlbox'); - expect(cbview.$('#controlbox-tabs li').length).toBe(1); - expect(cbview.$('#controlbox-tabs li').text().trim()).toBe("Sign in"); - connection = mock.mock_connection; - connection.connected = false; - converse._tearDown(); - converse.initialized_plugins = []; + it("is not available unless allow_registration=true", function () { converse.initialize({ i18n: window.locales.en, bosh_service_url: 'localhost', allow_registration: true, auto_subscribe: false, animate: false, - connection: connection, + connection: mock.mock_connection, no_trimming: true, - debug: true + debug: false + }, function (converse) { + test_utils.closeControlBox(); + var cbview = converse.chatboxviews.get('controlbox'); + expect(cbview.$('#controlbox-tabs li').length).toBe(1); + expect(cbview.$('#controlbox-tabs li').text().trim()).toBe("Sign in"); + cbview = converse.chatboxviews.get('controlbox'); + expect(cbview.$el.find('#controlbox-tabs li').length).toBe(2); + expect(cbview.$('#controlbox-tabs li').first().text().trim()).toBe("Sign in"); + expect(cbview.$('#controlbox-tabs li').last().text().trim()).toBe("Register"); }); - test_utils.openControlBox(); - cbview = this.chatboxviews.get('controlbox'); - expect(cbview.$el.find('#controlbox-tabs li').length).toBe(2); - expect(cbview.$('#controlbox-tabs li').first().text().trim()).toBe("Sign in"); - expect(cbview.$('#controlbox-tabs li').last().text().trim()).toBe("Register"); - }, converse)); + }); - it("can be opened by clicking on the registration tab", $.proxy(function () { - var cbview = this.chatboxviews.get('controlbox'); - var $tabs = cbview.$('#controlbox-tabs'); - var $panels = cbview.$('.controlbox-panes'); - var $login = $panels.children().first(); - var $registration = $panels.children().last(); - expect($tabs.find('li').first().text()).toBe('Sign in'); - expect($tabs.find('li').last().text()).toBe('Register'); + it("can be opened by clicking on the registration tab", function () { + converse.initialize({ + i18n: window.locales.en, + bosh_service_url: 'localhost', + allow_registration: true, + auto_subscribe: false, + animate: false, + connection: mock.mock_connection, + no_trimming: true, + debug: false + }, function (converse) { + test_utils.closeControlBox(); + var cbview = converse.chatboxviews.get('controlbox'); + var $tabs = cbview.$('#controlbox-tabs'); + var $panels = cbview.$('.controlbox-panes'); + var $login = $panels.children().first(); + var $registration = $panels.children().last(); + expect($tabs.find('li').first().text()).toBe('Sign in'); + expect($tabs.find('li').last().text()).toBe('Register'); - spyOn(cbview, 'switchTab').andCallThrough(); - cbview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called - $tabs.find('li').last().find('a').click(); // Click the Register tab - expect($login.is(':visible')).toBe(false); - expect($registration.is(':visible')).toBe(true); - expect(cbview.switchTab).toHaveBeenCalled(); - }, converse)); + spyOn(cbview, 'switchTab').andCallThrough(); + cbview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called + $tabs.find('li').last().find('a').click(); // Click the Register tab + expect($login.is(':visible')).toBe(false); + expect($registration.is(':visible')).toBe(true); + expect(cbview.switchTab).toHaveBeenCalled(); + }); + }); - it("allows the user to choose an XMPP provider's domain", $.proxy(function () { - var cbview = this.chatboxviews.get('controlbox'); - var registerview = cbview.registerpanel; - spyOn(registerview, 'onProviderChosen').andCallThrough(); - registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called - spyOn(this.connection, 'connect'); - var $tabs = cbview.$('#controlbox-tabs'); - $tabs.find('li').last().find('a').click(); // Click the Register tab - // Check the form layout - var $form = cbview.$('#converse-register'); - expect($form.find('input').length).toEqual(2); - expect($form.find('input').first().attr('name')).toEqual('domain'); - expect($form.find('input').last().attr('type')).toEqual('submit'); - // Check that the input[type=domain] input is required - $form.find('input[type=submit]').click(); - expect(registerview.onProviderChosen).toHaveBeenCalled(); - expect($form.find('input[name=domain]').hasClass('error')).toBeTruthy(); - // Check that the form is accepted if input[type=domain] has a value - $form.find('input[name=domain]').val('conversejs.org'); - $form.find('input[type=submit]').click(); - expect(registerview.onProviderChosen).toHaveBeenCalled(); - expect(this.connection.connect).toHaveBeenCalled(); - }, converse)); + it("allows the user to choose an XMPP provider's domain", function () { + converse.initialize({ + i18n: window.locales.en, + bosh_service_url: 'localhost', + allow_registration: true, + auto_subscribe: false, + animate: false, + connection: mock.mock_connection, + no_trimming: true, + debug: false + }, function (converse) { + test_utils.closeControlBox(); + var cbview = converse.chatboxviews.get('controlbox'); + var registerview = cbview.registerpanel; + spyOn(registerview, 'onProviderChosen').andCallThrough(); + registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called + spyOn(converse.connection, 'connect'); + var $tabs = cbview.$('#controlbox-tabs'); + $tabs.find('li').last().find('a').click(); // Click the Register tab + // Check the form layout + var $form = cbview.$('#converse-register'); + expect($form.find('input').length).toEqual(2); + expect($form.find('input').first().attr('name')).toEqual('domain'); + expect($form.find('input').last().attr('type')).toEqual('submit'); + // Check that the input[type=domain] input is required + $form.find('input[type=submit]').click(); + expect(registerview.onProviderChosen).toHaveBeenCalled(); + expect($form.find('input[name=domain]').hasClass('error')).toBeTruthy(); + // Check that the form is accepted if input[type=domain] has a value + $form.find('input[name=domain]').val('conversejs.org'); + $form.find('input[type=submit]').click(); + expect(registerview.onProviderChosen).toHaveBeenCalled(); + expect(converse.connection.connect).toHaveBeenCalled(); + }); + }); - it("will render a registration form as received from the XMPP provider", $.proxy(function () { - var cbview = this.chatboxviews.get('controlbox'); - cbview.$('#controlbox-tabs').find('li').last().find('a').click(); // Click the Register tab - var registerview = this.chatboxviews.get('controlbox').registerpanel; - spyOn(registerview, 'onProviderChosen').andCallThrough(); - spyOn(registerview, 'getRegistrationFields').andCallThrough(); - spyOn(registerview, 'onRegistrationFields').andCallThrough(); - spyOn(registerview, 'renderRegistrationForm').andCallThrough(); - registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called - spyOn(this.connection, 'connect').andCallThrough(); + it("will render a registration form as received from the XMPP provider", function () { + converse.initialize({ + i18n: window.locales.en, + bosh_service_url: 'localhost', + allow_registration: true, + auto_subscribe: false, + animate: false, + connection: mock.mock_connection, + no_trimming: true, + debug: false + }, function (converse) { + var cbview = converse.chatboxviews.get('controlbox'); + cbview.$('#controlbox-tabs').find('li').last().find('a').click(); // Click the Register tab + var registerview = converse.chatboxviews.get('controlbox').registerpanel; + spyOn(registerview, 'onProviderChosen').andCallThrough(); + spyOn(registerview, 'getRegistrationFields').andCallThrough(); + spyOn(registerview, 'onRegistrationFields').andCallThrough(); + spyOn(registerview, 'renderRegistrationForm').andCallThrough(); + registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called + spyOn(converse.connection, 'connect').andCallThrough(); - expect(registerview._registering).toBeFalsy(); - expect(this.connection.connected).toBeFalsy(); - registerview.$('input[name=domain]').val('conversejs.org'); - registerview.$('input[type=submit]').click(); - expect(registerview.onProviderChosen).toHaveBeenCalled(); - expect(registerview._registering).toBeTruthy(); - expect(this.connection.connect).toHaveBeenCalled(); + expect(registerview._registering).toBeFalsy(); + expect(converse.connection.connected).toBeFalsy(); + registerview.$('input[name=domain]').val('conversejs.org'); + registerview.$('input[type=submit]').click(); + expect(registerview.onProviderChosen).toHaveBeenCalled(); + expect(registerview._registering).toBeTruthy(); + expect(converse.connection.connect).toHaveBeenCalled(); - var stanza = new Strophe.Builder("stream:features", { - 'xmlns:stream': "http://etherx.jabber.org/streams", - 'xmlns': "jabber:client" - }) - .c('register', {xmlns: "http://jabber.org/features/iq-register"}).up() - .c('mechanisms', {xmlns: "urn:ietf:params:xml:ns:xmpp-sasl"}); - this.connection._connect_cb(test_utils.createRequest(stanza)); + var stanza = new Strophe.Builder("stream:features", { + 'xmlns:stream': "http://etherx.jabber.org/streams", + 'xmlns': "jabber:client" + }) + .c('register', {xmlns: "http://jabber.org/features/iq-register"}).up() + .c('mechanisms', {xmlns: "urn:ietf:params:xml:ns:xmpp-sasl"}); + converse.connection._connect_cb(test_utils.createRequest(stanza)); - expect(registerview.getRegistrationFields).toHaveBeenCalled(); - expect(this.connection.connected).toBeTruthy(); + expect(registerview.getRegistrationFields).toHaveBeenCalled(); + expect(converse.connection.connected).toBeTruthy(); - stanza = $iq({ - 'type': 'result', - 'id': 'reg1' - }).c('query', {'xmlns': 'jabber:iq:register'}) - .c('instructions') - .t('Please choose a username, password and provide your email address').up() - .c('username').up() - .c('password').up() - .c('email'); - this.connection._dataRecv(test_utils.createRequest(stanza)); - expect(registerview.onRegistrationFields).toHaveBeenCalled(); - expect(registerview.renderRegistrationForm).toHaveBeenCalled(); - expect(registerview.$('input').length).toBe(5); - expect(registerview.$('input[type=submit]').length).toBe(1); - expect(registerview.$('input[type=button]').length).toBe(1); - }, converse)); + stanza = $iq({ + 'type': 'result', + 'id': 'reg1' + }).c('query', {'xmlns': 'jabber:iq:register'}) + .c('instructions') + .t('Please choose a username, password and provide your email address').up() + .c('username').up() + .c('password').up() + .c('email'); + converse.connection._dataRecv(test_utils.createRequest(stanza)); + expect(registerview.onRegistrationFields).toHaveBeenCalled(); + expect(registerview.renderRegistrationForm).toHaveBeenCalled(); + expect(registerview.$('input').length).toBe(5); + expect(registerview.$('input[type=submit]').length).toBe(1); + expect(registerview.$('input[type=button]').length).toBe(1); + }); + }); - it("will set form_type to legacy and submit it as legacy", $.proxy(function () { - var cbview = this.chatboxviews.get('controlbox'); - cbview.$('#controlbox-tabs').find('li').last().find('a').click(); // Click the Register tab - var registerview = this.chatboxviews.get('controlbox').registerpanel; - spyOn(registerview, 'onProviderChosen').andCallThrough(); - spyOn(registerview, 'getRegistrationFields').andCallThrough(); - spyOn(registerview, 'onRegistrationFields').andCallThrough(); - spyOn(registerview, 'renderRegistrationForm').andCallThrough(); - registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called - spyOn(this.connection, 'connect').andCallThrough(); + it("will set form_type to legacy and submit it as legacy", function () { + converse.initialize({ + i18n: window.locales.en, + bosh_service_url: 'localhost', + allow_registration: true, + auto_subscribe: false, + animate: false, + connection: mock.mock_connection, + no_trimming: true, + debug: false + }, function (converse) { + test_utils.closeControlBox(); + var cbview = converse.chatboxviews.get('controlbox'); + cbview.$('#controlbox-tabs').find('li').last().find('a').click(); // Click the Register tab + var registerview = converse.chatboxviews.get('controlbox').registerpanel; + spyOn(registerview, 'onProviderChosen').andCallThrough(); + spyOn(registerview, 'getRegistrationFields').andCallThrough(); + spyOn(registerview, 'onRegistrationFields').andCallThrough(); + spyOn(registerview, 'renderRegistrationForm').andCallThrough(); + registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called + spyOn(converse.connection, 'connect').andCallThrough(); - registerview.$('input[name=domain]').val('conversejs.org'); - registerview.$('input[type=submit]').click(); + registerview.$('input[name=domain]').val('conversejs.org'); + registerview.$('input[type=submit]').click(); - var stanza = new Strophe.Builder("stream:features", { - 'xmlns:stream': "http://etherx.jabber.org/streams", - 'xmlns': "jabber:client" - }) - .c('register', {xmlns: "http://jabber.org/features/iq-register"}).up() - .c('mechanisms', {xmlns: "urn:ietf:params:xml:ns:xmpp-sasl"}); - this.connection._connect_cb(test_utils.createRequest(stanza)); - stanza = $iq({ - 'type': 'result', - 'id': 'reg1' - }).c('query', {'xmlns': 'jabber:iq:register'}) - .c('instructions') - .t('Please choose a username, password and provide your email address').up() - .c('username').up() - .c('password').up() - .c('email'); - this.connection._dataRecv(test_utils.createRequest(stanza)); - expect(registerview.form_type).toBe('legacy'); + var stanza = new Strophe.Builder("stream:features", { + 'xmlns:stream': "http://etherx.jabber.org/streams", + 'xmlns': "jabber:client" + }) + .c('register', {xmlns: "http://jabber.org/features/iq-register"}).up() + .c('mechanisms', {xmlns: "urn:ietf:params:xml:ns:xmpp-sasl"}); + converse.connection._connect_cb(test_utils.createRequest(stanza)); + stanza = $iq({ + 'type': 'result', + 'id': 'reg1' + }).c('query', {'xmlns': 'jabber:iq:register'}) + .c('instructions') + .t('Please choose a username, password and provide your email address').up() + .c('username').up() + .c('password').up() + .c('email'); + converse.connection._dataRecv(test_utils.createRequest(stanza)); + expect(registerview.form_type).toBe('legacy'); - registerview.$('input[name=username]').val('testusername'); - registerview.$('input[name=password]').val('testpassword'); - registerview.$('input[name=email]').val('test@email.local'); + registerview.$('input[name=username]').val('testusername'); + registerview.$('input[name=password]').val('testpassword'); + registerview.$('input[name=email]').val('test@email.local'); - spyOn(converse.connection, 'send'); + spyOn(converse.connection, 'send'); - registerview.$('input[type=submit]').click(); + registerview.$('input[type=submit]').click(); - expect(converse.connection.send).toHaveBeenCalled(); - var $stanza = $(converse.connection.send.argsForCall[0][0].tree()); - expect($stanza.children('query').children().length).toBe(3); - expect($stanza.children('query').children()[0].tagName).toBe('username'); - }, converse)); + expect(converse.connection.send).toHaveBeenCalled(); + var $stanza = $(converse.connection.send.argsForCall[0][0].tree()); + expect($stanza.children('query').children().length).toBe(3); + expect($stanza.children('query').children()[0].tagName).toBe('username'); + }); + }); - it("will set form_type to xform and submit it as xform", $.proxy(function () { - var cbview = this.chatboxviews.get('controlbox'); - cbview.$('#controlbox-tabs').find('li').last().find('a').click(); // Click the Register tab - var registerview = this.chatboxviews.get('controlbox').registerpanel; - spyOn(registerview, 'onProviderChosen').andCallThrough(); - spyOn(registerview, 'getRegistrationFields').andCallThrough(); - spyOn(registerview, 'onRegistrationFields').andCallThrough(); - spyOn(registerview, 'renderRegistrationForm').andCallThrough(); - registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called - spyOn(this.connection, 'connect').andCallThrough(); + it("will set form_type to xform and submit it as xform", function () { + converse.initialize({ + i18n: window.locales.en, + bosh_service_url: 'localhost', + allow_registration: true, + auto_subscribe: false, + animate: false, + connection: mock.mock_connection, + no_trimming: true, + debug: false + }, function (converse) { + test_utils.closeControlBox(); + var cbview = converse.chatboxviews.get('controlbox'); + cbview.$('#controlbox-tabs').find('li').last().find('a').click(); // Click the Register tab + var registerview = converse.chatboxviews.get('controlbox').registerpanel; + spyOn(registerview, 'onProviderChosen').andCallThrough(); + spyOn(registerview, 'getRegistrationFields').andCallThrough(); + spyOn(registerview, 'onRegistrationFields').andCallThrough(); + spyOn(registerview, 'renderRegistrationForm').andCallThrough(); + registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called + spyOn(converse.connection, 'connect').andCallThrough(); - registerview.$('input[name=domain]').val('conversejs.org'); - registerview.$('input[type=submit]').click(); + registerview.$('input[name=domain]').val('conversejs.org'); + registerview.$('input[type=submit]').click(); - var stanza = new Strophe.Builder("stream:features", { - 'xmlns:stream': "http://etherx.jabber.org/streams", - 'xmlns': "jabber:client" - }) - .c('register', {xmlns: "http://jabber.org/features/iq-register"}).up() - .c('mechanisms', {xmlns: "urn:ietf:params:xml:ns:xmpp-sasl"}); - this.connection._connect_cb(test_utils.createRequest(stanza)); - stanza = $iq({ - 'type': 'result', - 'id': 'reg1' - }).c('query', {'xmlns': 'jabber:iq:register'}) - .c('instructions') - .t('Using xform data').up() - .c('x', { 'xmlns': 'jabber:x:data', 'type': 'form' }) - .c('instructions').t('xform instructions').up() - .c('field', {'type': 'text-single', 'var': 'username'}).c('required').up().up() - .c('field', {'type': 'text-private', 'var': 'password'}).c('required').up().up() - .c('field', {'type': 'text-single', 'var': 'email'}).c('required').up().up(); - this.connection._dataRecv(test_utils.createRequest(stanza)); - expect(registerview.form_type).toBe('xform'); + var stanza = new Strophe.Builder("stream:features", { + 'xmlns:stream': "http://etherx.jabber.org/streams", + 'xmlns': "jabber:client" + }) + .c('register', {xmlns: "http://jabber.org/features/iq-register"}).up() + .c('mechanisms', {xmlns: "urn:ietf:params:xml:ns:xmpp-sasl"}); + converse.connection._connect_cb(test_utils.createRequest(stanza)); + stanza = $iq({ + 'type': 'result', + 'id': 'reg1' + }).c('query', {'xmlns': 'jabber:iq:register'}) + .c('instructions') + .t('Using xform data').up() + .c('x', { 'xmlns': 'jabber:x:data', 'type': 'form' }) + .c('instructions').t('xform instructions').up() + .c('field', {'type': 'text-single', 'var': 'username'}).c('required').up().up() + .c('field', {'type': 'text-private', 'var': 'password'}).c('required').up().up() + .c('field', {'type': 'text-single', 'var': 'email'}).c('required').up().up(); + converse.connection._dataRecv(test_utils.createRequest(stanza)); + expect(registerview.form_type).toBe('xform'); - registerview.$('input[name=username]').val('testusername'); - registerview.$('input[name=password]').val('testpassword'); - registerview.$('input[name=email]').val('test@email.local'); + registerview.$('input[name=username]').val('testusername'); + registerview.$('input[name=password]').val('testpassword'); + registerview.$('input[name=email]').val('test@email.local'); - spyOn(converse.connection, 'send'); + spyOn(converse.connection, 'send'); - registerview.$('input[type=submit]').click(); + registerview.$('input[type=submit]').click(); - expect(converse.connection.send).toHaveBeenCalled(); - var $stanza = $(converse.connection.send.argsForCall[0][0].tree()); - expect($stanza.children('query').children().length).toBe(1); - expect($stanza.children('query').children().children().length).toBe(3); - expect($stanza.children('query').children().children()[0].tagName).toBe('field'); - }, converse)); - - }, converse, mock, test_utils)); + expect(converse.connection.send).toHaveBeenCalled(); + var $stanza = $(converse.connection.send.argsForCall[0][0].tree()); + expect($stanza.children('query').children().length).toBe(1); + expect($stanza.children('query').children().children().length).toBe(3); + expect($stanza.children('query').children().children()[0].tagName).toBe('field'); + }); + }); + }); })); diff --git a/src/converse-api.js b/src/converse-api.js index e8027d5e4..e9b2058b8 100644 --- a/src/converse-api.js +++ b/src/converse-api.js @@ -35,6 +35,7 @@ }, 'user': { 'login': function (credentials) { + converse.initConnection(); converse.logIn(credentials); }, 'logout': function () { diff --git a/src/converse-core.js b/src/converse-core.js index 1334cd1ee..caa536496 100755 --- a/src/converse-core.js +++ b/src/converse-core.js @@ -1620,7 +1620,8 @@ return this.connection.attach(this.jid, this.sid, this.rid, this.onConnectStatusChanged); } else if (this.keepalive) { if (!this.jid) { - throw new Error("initConnection: when using 'keepalive' with 'prebind, you must supply the JID of the current user."); + throw new Error("attemptPreboundSession: when using 'keepalive' with 'prebind, "+ + "you must supply the JID of the current user."); } try { return this.connection.restore(this.jid, this.onConnectStatusChanged); @@ -1629,7 +1630,7 @@ this.clearSession(); // If there's a roster, we want to clear it (see #555) } } else { - throw new Error("initConnection: If you use prebind and not keepalive, "+ + throw new Error("attemptPreboundSession: If you use prebind and not keepalive, "+ "then you MUST supply JID, RID and SID values"); } // We haven't been able to attach yet. Let's see if there @@ -1700,6 +1701,8 @@ this.logIn = function (credentials) { if (credentials) { + // When credentials are passed in, they override prebinding + // or credentials fetching via HTTP this.autoLogin(credentials); } else { // We now try to resume or automatically set up a new session. @@ -1713,22 +1716,18 @@ }; this.initConnection = function () { - if (this.connection && this.connection.connected) { - this.setUpXMLLogging(); - this.onConnected(); + if (this.connection) { + return; + } + if (!this.bosh_service_url && ! this.websocket_url) { + throw new Error("initConnection: you must supply a value for either the bosh_service_url or websocket_url or both."); + } + if (('WebSocket' in window || 'MozWebSocket' in window) && this.websocket_url) { + this.connection = new Strophe.Connection(this.websocket_url); + } else if (this.bosh_service_url) { + this.connection = new Strophe.Connection(this.bosh_service_url, {'keepalive': this.keepalive}); } else { - if (!this.bosh_service_url && ! this.websocket_url) { - throw new Error("initConnection: you must supply a value for either the bosh_service_url or websocket_url or both."); - } - if (('WebSocket' in window || 'MozWebSocket' in window) && this.websocket_url) { - this.connection = new Strophe.Connection(this.websocket_url); - } else if (this.bosh_service_url) { - this.connection = new Strophe.Connection(this.bosh_service_url, {'keepalive': this.keepalive}); - } else { - throw new Error("initConnection: this browser does not support websockets and bosh_service_url wasn't specified."); - } - this.setUpXMLLogging(); - this.logIn(); + throw new Error("initConnection: this browser does not support websockets and bosh_service_url wasn't specified."); } }; @@ -1753,6 +1752,8 @@ this.chatboxviews = new this.ChatBoxViews({model: this.chatboxes}); this.initSession(); this.initConnection(); + this.setUpXMLLogging(); + this.logIn(); return this; }; diff --git a/tests/main.js b/tests/main.js index 2db608599..bfe44588e 100644 --- a/tests/main.js +++ b/tests/main.js @@ -47,9 +47,13 @@ require([ converse.initialize({ i18n: window.locales.en, auto_subscribe: false, - animate: false, + bosh_service_url: 'localhost', connection: mock.mock_connection, + animate: false, no_trimming: true, + auto_login: true, + jid: 'dummy@localhost', + password: 'secret', debug: false }, function (converse) { window.converse = converse; @@ -64,6 +68,7 @@ require([ require([ "console-runner", "spec/converse", + "spec/headline", "spec/disco", "spec/protocol", "spec/mam", @@ -76,9 +81,8 @@ require([ "spec/notification", "spec/profiling", "spec/ping", - "spec/headline", "spec/register", - "spec/xmppstatus" + "spec/xmppstatus", ], function () { // Make sure this callback is only called once. delete converse.callback; diff --git a/tests/mock.js b/tests/mock.js index 5dca45f31..61dcdd117 100644 --- a/tests/mock.js +++ b/tests/mock.js @@ -50,10 +50,6 @@ mock.mock_connection = function () { Strophe.Bosh.prototype._processRequest = function () {}; // Don't attempt to send out stanzas var c = new Strophe.Connection('jasmine tests'); - c.authenticated = true; - c.connected = true; - c.mock = true; - c.jid = 'dummy@localhost/resource'; c.vcard = { 'get': function (callback, jid) { var fullname; @@ -71,8 +67,13 @@ callback(vcard.tree()); } }; - c._changeConnectStatus(Strophe.Status.CONNECTED); - c.attach(c.jid); + c._proto._connect = function () { + c.authenticated = true; + c.connected = true; + c.mock = true; + c.jid = 'dummy@localhost/resource'; + c._changeConnectStatus(Strophe.Status.CONNECTED); + }; return c; }(); return mock;