Upgrade to Jasmine 2.5.3

This commit is contained in:
JC Brand 2017-04-05 11:01:31 +02:00
parent bf9ba245b4
commit 0c43e4b87c
28 changed files with 2025 additions and 2061 deletions

View File

@ -255,7 +255,7 @@
"error", "error",
"never" "never"
], ],
"valid-jsdoc": "error", "valid-jsdoc": "off",
"vars-on-top": "off", "vars-on-top": "off",
"wrap-iife": [ "wrap-iife": [
"error", "error",

View File

@ -3,7 +3,6 @@ BUILDDIR = ./docs
BUNDLE ?= ./.bundle/bin/bundle BUNDLE ?= ./.bundle/bin/bundle
GRUNT ?= ./node_modules/.bin/grunt GRUNT ?= ./node_modules/.bin/grunt
HTTPSERVE ?= ./node_modules/.bin/http-server HTTPSERVE ?= ./node_modules/.bin/http-server
JSHINT ?= ./node_modules/.bin/jshint
ESLINT ?= ./node_modules/.bin/eslint ESLINT ?= ./node_modules/.bin/eslint
PAPER = PAPER =
PHANTOMJS ?= ./node_modules/.bin/phantomjs PHANTOMJS ?= ./node_modules/.bin/phantomjs
@ -16,13 +15,6 @@ SPHINXOPTS =
# Internal variables. # Internal variables.
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) ./docs/source ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) ./docs/source
SOURCES = $(wildcard *.js) $(wildcard spec/*.js) $(wildcard src/*.js)
JSHINTEXCEPTIONS = $(GENERATED) \
src/build-mobile.js \
src/build-no-jquery.js \
src/build-no-dependencies.js \
src/build.js \
CHECKSOURCES = $(filter-out $(JSHINTEXCEPTIONS),$(SOURCES))
.PHONY: all .PHONY: all
all: dev dist all: dev dist
@ -184,18 +176,15 @@ build:: dev css
######################################################################## ########################################################################
## Tests ## Tests
.PHONY: jshint
jshint: stamp-npm
$(JSHINT) --config jshintrc $(CHECKSOURCES)
.PHONY: eslint .PHONY: eslint
eslint: stamp-npm eslint: stamp-npm
$(ESLINT) src/ $(ESLINT) src/
$(ESLINT) spec/ $(ESLINT) spec/
.PHONY: check .PHONY: check
check: jshint eslint check: eslint
$(PHANTOMJS) node_modules/phantom-jasmine/lib/run_jasmine_test.coffee tests.html $(PHANTOMJS) tests/run-jasmine2.js tests.html
######################################################################## ########################################################################
## Documentation ## Documentation

View File

@ -2,7 +2,7 @@
## 3.0.2 (Unreleased) ## 3.0.2 (Unreleased)
- No changes yet. - Update Jasmine from 1.3.1 to 2.5.3 and Phantomjs from 1.9.7-1 to 2.1.14 [jcbrand]
## 3.0.1 (2017-04-04) ## 3.0.1 (2017-04-04)

View File

@ -40,6 +40,7 @@
"bootstrap": "^3.3.7", "bootstrap": "^3.3.7",
"bourbon": "^4.3.2", "bourbon": "^4.3.2",
"clean-css": "^3.4.19", "clean-css": "^3.4.19",
"es6-promise": "^4.1.0",
"eslint": "^3.16.1", "eslint": "^3.16.1",
"eslint-plugin-lodash": "^2.3.3", "eslint-plugin-lodash": "^2.3.3",
"font-awesome": "^4.7.0", "font-awesome": "^4.7.0",
@ -49,7 +50,7 @@
"grunt-json": "^0.2.0", "grunt-json": "^0.2.0",
"http-server": "^0.9.0", "http-server": "^0.9.0",
"install": "^0.8.5", "install": "^0.8.5",
"jasmine": "https://github.com/jcbrand/jasmine.git#439a7f805eeaec0cabe18a8ecf7e47da1a0afa33", "jasmine": "2.5.3",
"jed": "0.5.4", "jed": "0.5.4",
"jquery": "2.2.3", "jquery": "2.2.3",
"jquery-easing": "0.0.1", "jquery-easing": "0.0.1",
@ -60,8 +61,7 @@
"moment": "~2.13.0", "moment": "~2.13.0",
"npm": "^4.1.1", "npm": "^4.1.1",
"otr": "0.2.16", "otr": "0.2.16",
"phantom-jasmine": "0.1.8", "phantomjs-prebuilt": "~2.1.14",
"phantomjs": "~1.9.7-1",
"pluggable.js": "1.0.0", "pluggable.js": "1.0.0",
"po2json": "^0.4.4", "po2json": "^0.4.4",
"requirejs": "2.3.3", "requirejs": "2.3.3",
@ -73,7 +73,8 @@
"strophejs-plugin-register": "0.0.1", "strophejs-plugin-register": "0.0.1",
"strophejs-plugin-rsm": "0.0.1", "strophejs-plugin-rsm": "0.0.1",
"strophejs-plugin-vcard": "0.0.1", "strophejs-plugin-vcard": "0.0.1",
"text": "requirejs/text#2.0.15" "text": "requirejs/text#2.0.15",
"wait-until-promise": "^1.0.0"
}, },
"dependencies": {} "dependencies": {}
} }

View File

@ -1,10 +1,12 @@
/*global waitUntilPromise */
(function (root, factory) { (function (root, factory) {
define([ define([
"jquery", "jquery",
"converse-core", "converse-core",
"utils", "utils",
"mock", "mock",
"test_utils" "test-utils"
], factory); ], factory);
} (this, function ($, converse, utils, mock, test_utils) { } (this, function ($, converse, utils, mock, test_utils) {
"use strict"; "use strict";
@ -17,17 +19,17 @@
it("can be bookmarked", mock.initConverse(function (_converse) { it("can be bookmarked", mock.initConverse(function (_converse) {
var sent_stanza, IQ_id; var sent_stanza, IQ_id;
var sendIQ = _converse.connection.sendIQ; var sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
sent_stanza = iq; sent_stanza = iq;
IQ_id = sendIQ.bind(this)(iq, callback, errback); IQ_id = sendIQ.bind(this)(iq, callback, errback);
}); });
spyOn(_converse.connection, 'getUniqueId').andCallThrough(); spyOn(_converse.connection, 'getUniqueId').and.callThrough();
test_utils.openChatRoom(_converse, 'theplay', 'conference.shakespeare.lit', 'JC'); test_utils.openChatRoom(_converse, 'theplay', 'conference.shakespeare.lit', 'JC');
var jid = 'theplay@conference.shakespeare.lit'; var jid = 'theplay@conference.shakespeare.lit';
var view = _converse.chatboxviews.get(jid); var view = _converse.chatboxviews.get(jid);
spyOn(view, 'renderBookmarkForm').andCallThrough(); spyOn(view, 'renderBookmarkForm').and.callThrough();
spyOn(view, 'cancelConfiguration').andCallThrough(); spyOn(view, 'cancelConfiguration').and.callThrough();
var $bookmark = view.$el.find('.icon-pushpin'); var $bookmark = view.$el.find('.icon-pushpin');
$bookmark.click(); $bookmark.click();
@ -146,85 +148,73 @@
describe("when bookmarked", function () { describe("when bookmarked", function () {
it("displays that it's bookmarked through its bookmark icon", mock.initConverse(function (_converse) { it("displays that it's bookmarked through its bookmark icon", mock.initConverse(function (_converse) {
runs(function () { test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy');
test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy'); var view = _converse.chatboxviews.get('lounge@localhost');
}); var $bookmark_icon = view.$('.icon-pushpin');
waits(100); expect($bookmark_icon.hasClass('button-on')).toBeFalsy();
runs(function () { view.model.set('bookmarked', true);
var view = _converse.chatboxviews.get('lounge@localhost'); expect($bookmark_icon.hasClass('button-on')).toBeTruthy();
var $bookmark_icon = view.$('.icon-pushpin'); view.model.set('bookmarked', false);
expect($bookmark_icon.hasClass('button-on')).toBeFalsy(); expect($bookmark_icon.hasClass('button-on')).toBeFalsy();
view.model.set('bookmarked', true);
expect($bookmark_icon.hasClass('button-on')).toBeTruthy();
view.model.set('bookmarked', false);
expect($bookmark_icon.hasClass('button-on')).toBeFalsy();
});
})); }));
it("can be unbookmarked", mock.initConverse(function (_converse) { it("can be unbookmarked", mock.initConverse(function (_converse) {
var view, sent_stanza, IQ_id; var sent_stanza, IQ_id;
var sendIQ = _converse.connection.sendIQ; var sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) { test_utils.openChatRoom(_converse, 'theplay', 'conference.shakespeare.lit', 'JC');
var jid = 'theplay@conference.shakespeare.lit';
var view = _converse.chatboxviews.get(jid);
spyOn(view, 'toggleBookmark').and.callThrough();
spyOn(_converse.bookmarks, 'sendBookmarkStanza').and.callThrough();
view.delegateEvents();
_converse.bookmarks.create({
'jid': view.model.get('jid'),
'autojoin': false,
'name': 'The Play',
'nick': ' Othello'
});
expect(_converse.bookmarks.length).toBe(1);
expect(view.model.get('bookmarked')).toBeTruthy();
var $bookmark_icon = view.$('.icon-pushpin');
expect($bookmark_icon.hasClass('button-on')).toBeTruthy();
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
sent_stanza = iq; sent_stanza = iq;
IQ_id = sendIQ.bind(this)(iq, callback, errback); IQ_id = sendIQ.bind(this)(iq, callback, errback);
}); });
spyOn(_converse.connection, 'getUniqueId').andCallThrough(); spyOn(_converse.connection, 'getUniqueId').and.callThrough();
$bookmark_icon.click();
expect(view.toggleBookmark).toHaveBeenCalled();
expect($bookmark_icon.hasClass('button-on')).toBeFalsy();
expect(_converse.bookmarks.length).toBe(0);
runs(function () { // Check that an IQ stanza is sent out, containing no
test_utils.openChatRoom(_converse, 'theplay', 'conference.shakespeare.lit', 'JC'); // conferences to bookmark (since we removed the one and
}); // only bookmark).
waits(100); expect(sent_stanza.toLocaleString()).toBe(
runs(function () { "<iq type='set' from='dummy@localhost/resource' xmlns='jabber:client' id='"+IQ_id+"'>"+
var jid = 'theplay@conference.shakespeare.lit'; "<pubsub xmlns='http://jabber.org/protocol/pubsub'>"+
view = _converse.chatboxviews.get(jid); "<publish node='storage:bookmarks'>"+
spyOn(view, 'toggleBookmark').andCallThrough(); "<item id='current'>"+
spyOn(_converse.bookmarks, 'sendBookmarkStanza').andCallThrough(); "<storage xmlns='storage:bookmarks'/>"+
view.delegateEvents(); "</item>"+
_converse.bookmarks.create({ "</publish>"+
'jid': view.model.get('jid'), "<publish-options>"+
'autojoin': false, "<x xmlns='jabber:x:data' type='submit'>"+
'name': 'The Play', "<field var='FORM_TYPE' type='hidden'>"+
'nick': ' Othello' "<value>http://jabber.org/protocol/pubsub#publish-options</value>"+
}); "</field>"+
expect(_converse.bookmarks.length).toBe(1); "<field var='pubsub#persist_items'>"+
}); "<value>true</value>"+
waits(100); "</field>"+
runs(function () { "<field var='pubsub#access_model'>"+
expect(view.model.get('bookmarked')).toBeTruthy(); "<value>whitelist</value>"+
var $bookmark_icon = view.$('.icon-pushpin'); "</field>"+
expect($bookmark_icon.hasClass('button-on')).toBeTruthy(); "</x>"+
$bookmark_icon.click(); "</publish-options>"+
expect(view.toggleBookmark).toHaveBeenCalled(); "</pubsub>"+
expect($bookmark_icon.hasClass('button-on')).toBeFalsy(); "</iq>"
expect(_converse.bookmarks.length).toBe(0); );
// Check that an IQ stanza is sent out, containing no
// conferences to bookmark (since we removed the one and
// only bookmark).
expect(sent_stanza.toLocaleString()).toBe(
"<iq type='set' from='dummy@localhost/resource' xmlns='jabber:client' id='"+IQ_id+"'>"+
"<pubsub xmlns='http://jabber.org/protocol/pubsub'>"+
"<publish node='storage:bookmarks'>"+
"<item id='current'>"+
"<storage xmlns='storage:bookmarks'/>"+
"</item>"+
"</publish>"+
"<publish-options>"+
"<x xmlns='jabber:x:data' type='submit'>"+
"<field var='FORM_TYPE' type='hidden'>"+
"<value>http://jabber.org/protocol/pubsub#publish-options</value>"+
"</field>"+
"<field var='pubsub#persist_items'>"+
"<value>true</value>"+
"</field>"+
"<field var='pubsub#access_model'>"+
"<value>whitelist</value>"+
"</field>"+
"</x>"+
"</publish-options>"+
"</pubsub>"+
"</iq>"
);
});
})); }));
}); });
@ -255,7 +245,7 @@
describe("Bookmarks", function () { describe("Bookmarks", function () {
it("can be pushed from the XMPP server", mock.initConverse(function (_converse) { xit("can be pushed from the XMPP server", mock.initConverse(function (_converse) {
// TODO // TODO
/* The stored data is automatically pushed to all of the user's /* The stored data is automatically pushed to all of the user's
* connected resources. * connected resources.
@ -305,7 +295,7 @@
it("can be retrieved from the XMPP server", mock.initConverse(function (_converse) { it("can be retrieved from the XMPP server", mock.initConverse(function (_converse) {
var sent_stanza, IQ_id, var sent_stanza, IQ_id,
sendIQ = _converse.connection.sendIQ; sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
sent_stanza = iq; sent_stanza = iq;
IQ_id = sendIQ.bind(this)(iq, callback, errback); IQ_id = sendIQ.bind(this)(iq, callback, errback);
}); });
@ -376,7 +366,7 @@
it("shows a list of bookmarks", mock.initConverse(function (_converse) { it("shows a list of bookmarks", mock.initConverse(function (_converse) {
var IQ_id; var IQ_id;
var sendIQ = _converse.connection.sendIQ; var sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
IQ_id = sendIQ.bind(this)(iq, callback, errback); IQ_id = sendIQ.bind(this)(iq, callback, errback);
}); });
_converse.chatboxviews.get('controlbox').$('#chatrooms dl.bookmarks').html(''); _converse.chatboxviews.get('controlbox').$('#chatrooms dl.bookmarks').html('');
@ -406,27 +396,22 @@
})); }));
it("remembers the toggle state of the bookmarks list", mock.initConverse(function (_converse) { it("remembers the toggle state of the bookmarks list", mock.initConverse(function (_converse) {
runs(function () { _converse.bookmarks.create({
_converse.bookmarks.create({ 'jid': 'theplay@conference.shakespeare.lit',
'jid': 'theplay@conference.shakespeare.lit', 'autojoin': false,
'autojoin': false, 'name': 'The Play',
'name': 'The Play', 'nick': ''
'nick': ''
});
_converse.emit('chatBoxesFetched');
test_utils.openControlBox().openRoomsPanel(_converse);
});
waits(100);
runs(function () {
expect($('#chatrooms dl.bookmarks dd:visible').length).toBe(1);
expect(_converse.bookmarksview.list_model.get('toggle-state')).toBe(_converse.OPENED);
$('#chatrooms .bookmarks-toggle').click();
expect($('#chatrooms dl.bookmarks dd:visible').length).toBe(0);
expect(_converse.bookmarksview.list_model.get('toggle-state')).toBe(_converse.CLOSED);
$('#chatrooms .bookmarks-toggle').click();
expect($('#chatrooms dl.bookmarks dd:visible').length).toBe(1);
expect(_converse.bookmarksview.list_model.get('toggle-state')).toBe(_converse.OPENED);
}); });
_converse.emit('chatBoxesFetched');
test_utils.openControlBox().openRoomsPanel(_converse);
expect($('#chatrooms dl.bookmarks dd:visible').length).toBe(1);
expect(_converse.bookmarksview.list_model.get('toggle-state')).toBe(_converse.OPENED);
$('#chatrooms .bookmarks-toggle').click();
expect($('#chatrooms dl.bookmarks dd:visible').length).toBe(0);
expect(_converse.bookmarksview.list_model.get('toggle-state')).toBe(_converse.CLOSED);
$('#chatrooms .bookmarks-toggle').click();
expect($('#chatrooms dl.bookmarks dd:visible').length).toBe(1);
expect(_converse.bookmarksview.list_model.get('toggle-state')).toBe(_converse.OPENED);
})); }));
}); });
}); });

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
define([ define([
"converse-core", "converse-core",
"mock", "mock",
"test_utils"], factory); "test-utils"], factory);
} (this, function (converse, mock, test_utils) { } (this, function (converse, mock, test_utils) {
var b64_sha1 = converse.env.b64_sha1; var b64_sha1 = converse.env.b64_sha1;
var _ = converse.env._; var _ = converse.env._;
@ -52,9 +52,9 @@
describe("A chat state indication", function () { describe("A chat state indication", function () {
it("are sent out when the client becomes or stops being idle", mock.initConverse(function (_converse) { it("are sent out when the client becomes or stops being idle", mock.initConverse(function (_converse) {
spyOn(_converse, 'sendCSI').andCallThrough(); spyOn(_converse, 'sendCSI').and.callThrough();
var sent_stanza; var sent_stanza;
spyOn(_converse.connection, 'send').andCallFake(function (stanza) { spyOn(_converse.connection, 'send').and.callFake(function (stanza) {
sent_stanza = stanza; sent_stanza = stanza;
}); });
var i = 0; var i = 0;
@ -298,26 +298,23 @@
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
var jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost'; var jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
var chatboxview; var chatboxview;
waits('300'); // ChatBox.show() is debounced for 250ms // Test on chat that doesn't exist.
runs(function () { expect(_converse.api.chats.get('non-existing@jabber.org')).toBeFalsy();
// Test on chat that doesn't exist. var box = _converse.api.chats.open(jid);
expect(_converse.api.chats.get('non-existing@jabber.org')).toBeFalsy(); expect(box instanceof Object).toBeTruthy();
var box = _converse.api.chats.open(jid); expect(box.model.get('box_id')).toBe(b64_sha1(jid));
expect(box instanceof Object).toBeTruthy(); expect(
expect(box.model.get('box_id')).toBe(b64_sha1(jid)); _.keys(box),
expect( ['close', 'endOTR', 'focus', 'get', 'initiateOTR', 'is_chatroom', 'maximize', 'minimize', 'open', 'set']
_.keys(box), );
['close', 'endOTR', 'focus', 'get', 'initiateOTR', 'is_chatroom', 'maximize', 'minimize', 'open', 'set'] chatboxview = _converse.chatboxviews.get(jid);
); expect(chatboxview.$el.is(':visible')).toBeTruthy();
chatboxview = _converse.chatboxviews.get(jid); // Test for multiple JIDs
expect(chatboxview.$el.is(':visible')).toBeTruthy(); var jid2 = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
// Test for multiple JIDs var list = _converse.api.chats.open([jid, jid2]);
var jid2 = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost'; expect(_.isArray(list)).toBeTruthy();
var list = _converse.api.chats.open([jid, jid2]); expect(list[0].model.get('box_id')).toBe(b64_sha1(jid));
expect(_.isArray(list)).toBeTruthy(); expect(list[1].model.get('box_id')).toBe(b64_sha1(jid2));
expect(list[0].model.get('box_id')).toBe(b64_sha1(jid));
expect(list[1].model.get('box_id')).toBe(b64_sha1(jid2));
});
})); }));
}); });

View File

@ -3,7 +3,7 @@
"jquery", "jquery",
"converse-core", "converse-core",
"mock", "mock",
"test_utils"], factory); "test-utils"], factory);
} (this, function ($, converse, mock, test_utils) { } (this, function ($, converse, mock, test_utils) {
"use strict"; "use strict";
var Strophe = converse.env.Strophe; var Strophe = converse.env.Strophe;
@ -11,10 +11,10 @@
describe("Service Discovery", function () { describe("Service Discovery", function () {
describe("Whenever converse.js discovers a new server feature", function () { describe("Whenever converse.js discovers a new server feature", function () {
it("emits the serviceDiscovered event", mock.initConverse(function (_converse) { it("emits the serviceDiscovered event", mock.initConverse(function (_converse) {
spyOn(_converse, 'emit'); sinon.spy(_converse, 'emit');
_converse.features.create({'var': Strophe.NS.MAM}); _converse.features.create({'var': Strophe.NS.MAM});
expect(_converse.emit).toHaveBeenCalled(); expect(_converse.emit.called).toBe(true);
expect(_converse.emit.argsForCall[0][1].get('var')).toBe(Strophe.NS.MAM); expect(_converse.emit.args[0][1].get('var')).toBe(Strophe.NS.MAM);
})); }));
}); });
}); });

View File

@ -1,5 +1,5 @@
(function (root, factory) { (function (root, factory) {
define(["mock", "converse-core", "test_utils"], factory); define(["mock", "converse-core", "test-utils"], factory);
} (this, function (mock, converse, test_utils) { } (this, function (mock, converse, test_utils) {
return describe("The _converse Event Emitter", function() { return describe("The _converse Event Emitter", function() {
@ -11,9 +11,9 @@
_converse.emit('connected'); _converse.emit('connected');
expect(this.callback).toHaveBeenCalled(); expect(this.callback).toHaveBeenCalled();
_converse.emit('connected'); _converse.emit('connected');
expect(this.callback.callCount, 2); expect(this.callback.calls.count(), 2);
_converse.emit('connected'); _converse.emit('connected');
expect(this.callback.callCount, 3); expect(this.callback.calls.count(), 3);
})); }));
it("allows you to listen once for an emitted event", mock.initConverse(function (_converse) { it("allows you to listen once for an emitted event", mock.initConverse(function (_converse) {
@ -23,9 +23,9 @@
_converse.emit('connected'); _converse.emit('connected');
expect(this.callback).toHaveBeenCalled(); expect(this.callback).toHaveBeenCalled();
_converse.emit('connected'); _converse.emit('connected');
expect(this.callback.callCount, 1); expect(this.callback.calls.count(), 1);
_converse.emit('connected'); _converse.emit('connected');
expect(this.callback.callCount, 1); expect(this.callback.calls.count(), 1);
})); }));
it("allows you to stop listening or subscribing to an event", mock.initConverse(function (_converse) { it("allows you to stop listening or subscribing to an event", mock.initConverse(function (_converse) {
@ -46,15 +46,15 @@
_converse.off('connected', this.callback); _converse.off('connected', this.callback);
_converse.emit('connected'); _converse.emit('connected');
expect(this.callback.callCount, 1); expect(this.callback.calls.count(), 1);
expect(this.anotherCallback.callCount, 2); expect(this.anotherCallback.calls.count(), 2);
_converse.once('connected', this.neverCalled); _converse.once('connected', this.neverCalled);
_converse.off('connected', this.neverCalled); _converse.off('connected', this.neverCalled);
_converse.emit('connected'); _converse.emit('connected');
expect(this.callback.callCount, 1); expect(this.callback.calls.count(), 1);
expect(this.anotherCallback.callCount, 3); expect(this.anotherCallback.calls.count(), 3);
expect(this.neverCalled).not.toHaveBeenCalled(); expect(this.neverCalled).not.toHaveBeenCalled();
})); }));
}); });

View File

@ -4,7 +4,7 @@
"converse-core", "converse-core",
"utils", "utils",
"mock", "mock",
"test_utils" "test-utils"
], factory); ], factory);
} (this, function ($, converse, utils, mock, test_utils) { } (this, function ($, converse, utils, mock, test_utils) {
"use strict"; "use strict";
@ -25,23 +25,18 @@
* </message * </message
*/ */
sinon.spy(utils, 'isHeadlineMessage'); sinon.spy(utils, 'isHeadlineMessage');
runs(function () { var stanza = $msg({
var stanza = $msg({ 'xmlns': 'jabber:client',
'xmlns': 'jabber:client', 'to': 'dummy@localhost',
'to': 'dummy@localhost', 'type': 'chat',
'type': 'chat', 'from': 'gapowa20102106@rds-rostov.ru/Adium',
'from': 'gapowa20102106@rds-rostov.ru/Adium', })
}) .c('nick', {'xmlns': "http://jabber.org/protocol/nick"}).t("-wwdmz").up()
.c('nick', {'xmlns': "http://jabber.org/protocol/nick"}).t("-wwdmz").up() .c('body').t('SORRY FOR THIS ADVERT');
.c('body').t('SORRY FOR THIS ADVERT'); _converse.connection._dataRecv(test_utils.createRequest(stanza));
_converse.connection._dataRecv(test_utils.createRequest(stanza)); expect(utils.isHeadlineMessage.called).toBeTruthy();
}); expect(utils.isHeadlineMessage.returned(false)).toBeTruthy();
waits(250); utils.isHeadlineMessage.restore();
runs(function () {
expect(utils.isHeadlineMessage.called).toBeTruthy();
expect(utils.isHeadlineMessage.returned(false)).toBeTruthy();
utils.isHeadlineMessage.restore();
});
})); }));
it("will open and display headline messages", mock.initConverse(function (_converse) { it("will open and display headline messages", mock.initConverse(function (_converse) {
@ -59,53 +54,43 @@
* </message> * </message>
*/ */
sinon.spy(utils, 'isHeadlineMessage'); sinon.spy(utils, 'isHeadlineMessage');
runs(function () { var stanza = $msg({
var stanza = $msg({ 'type': 'headline',
'type': 'headline', 'from': 'notify.example.com',
'from': 'notify.example.com', 'to': 'dummy@localhost',
'to': 'dummy@localhost', 'xml:lang': 'en'
'xml:lang': 'en' })
}) .c('subject').t('SIEVE').up()
.c('subject').t('SIEVE').up() .c('body').t('&lt;juliet@example.com&gt; You got mail.').up()
.c('body').t('&lt;juliet@example.com&gt; You got mail.').up() .c('x', {'xmlns': 'jabber:x:oob'})
.c('x', {'xmlns': 'jabber:x:oob'}) .c('url').t('imap://romeo@example.com/INBOX;UIDVALIDITY=385759043/;UID=18');
.c('url').t('imap://romeo@example.com/INBOX;UIDVALIDITY=385759043/;UID=18'); _converse.connection._dataRecv(test_utils.createRequest(stanza));
_converse.connection._dataRecv(test_utils.createRequest(stanza)); expect(
}); _.includes(
waits(250); _converse.chatboxviews.keys(),
runs(function () { 'notify.example.com')
expect( ).toBeTruthy();
_.includes( expect(utils.isHeadlineMessage.called).toBeTruthy();
_converse.chatboxviews.keys(), expect(utils.isHeadlineMessage.returned(true)).toBeTruthy();
'notify.example.com') utils.isHeadlineMessage.restore(); // unwraps
).toBeTruthy();
expect(utils.isHeadlineMessage.called).toBeTruthy();
expect(utils.isHeadlineMessage.returned(true)).toBeTruthy();
utils.isHeadlineMessage.restore(); // unwraps
});
})); }));
it("will not show a headline messages from a full JID if allow_non_roster_messaging is false", mock.initConverse(function (_converse) { it("will not show a headline messages from a full JID if allow_non_roster_messaging is false", mock.initConverse(function (_converse) {
_converse.allow_non_roster_messaging = false; _converse.allow_non_roster_messaging = false;
sinon.spy(utils, 'isHeadlineMessage'); sinon.spy(utils, 'isHeadlineMessage');
runs(function () { var stanza = $msg({
var stanza = $msg({ 'type': 'headline',
'type': 'headline', 'from': 'andre5114@jabber.snc.ru/Spark',
'from': 'andre5114@jabber.snc.ru/Spark', 'to': 'dummy@localhost',
'to': 'dummy@localhost', 'xml:lang': 'en'
'xml:lang': 'en' })
}) .c('nick').t('gpocy').up()
.c('nick').t('gpocy').up() .c('body').t('Здравствуйте друзья');
.c('body').t('Здравствуйте друзья'); _converse.connection._dataRecv(test_utils.createRequest(stanza));
_converse.connection._dataRecv(test_utils.createRequest(stanza)); expect(_.without('controlbox', _converse.chatboxviews.keys()).length).toBe(0);
}); expect(utils.isHeadlineMessage.called).toBeTruthy();
waits(250); expect(utils.isHeadlineMessage.returned(true)).toBeTruthy();
runs(function () { utils.isHeadlineMessage.restore(); // unwraps
expect(_.without('controlbox', _converse.chatboxviews.keys()).length).toBe(0);
expect(utils.isHeadlineMessage.called).toBeTruthy();
expect(utils.isHeadlineMessage.returned(true)).toBeTruthy();
utils.isHeadlineMessage.restore(); // unwraps
});
})); }));
}); });
})); }));

View File

@ -1,5 +1,5 @@
(function (root, factory) { (function (root, factory) {
define(["mock", "converse-core", "test_utils"], factory); define(["mock", "converse-core", "test-utils"], factory);
} (this, function (mock, converse, test_utils) { } (this, function (mock, converse, test_utils) {
"use strict"; "use strict";
var _ = converse.env._; var _ = converse.env._;
@ -18,7 +18,7 @@
it("can be used to query for all archived messages", mock.initConverse(function (_converse) { it("can be used to query for all archived messages", mock.initConverse(function (_converse) {
var sent_stanza, IQ_id; var sent_stanza, IQ_id;
var sendIQ = _converse.connection.sendIQ; var sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
sent_stanza = iq; sent_stanza = iq;
IQ_id = sendIQ.bind(this)(iq, callback, errback); IQ_id = sendIQ.bind(this)(iq, callback, errback);
}); });
@ -34,7 +34,7 @@
it("can be used to query for all messages to/from a particular JID", mock.initConverse(function (_converse) { it("can be used to query for all messages to/from a particular JID", mock.initConverse(function (_converse) {
var sent_stanza, IQ_id; var sent_stanza, IQ_id;
var sendIQ = _converse.connection.sendIQ; var sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
sent_stanza = iq; sent_stanza = iq;
IQ_id = sendIQ.bind(this)(iq, callback, errback); IQ_id = sendIQ.bind(this)(iq, callback, errback);
}); });
@ -62,7 +62,7 @@
it("can be used to query for all messages in a certain timespan", mock.initConverse(function (_converse) { it("can be used to query for all messages in a certain timespan", mock.initConverse(function (_converse) {
var sent_stanza, IQ_id; var sent_stanza, IQ_id;
var sendIQ = _converse.connection.sendIQ; var sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
sent_stanza = iq; sent_stanza = iq;
IQ_id = sendIQ.bind(this)(iq, callback, errback); IQ_id = sendIQ.bind(this)(iq, callback, errback);
}); });
@ -108,7 +108,7 @@
it("can be used to query for all messages after a certain time", mock.initConverse(function (_converse) { it("can be used to query for all messages after a certain time", mock.initConverse(function (_converse) {
var sent_stanza, IQ_id; var sent_stanza, IQ_id;
var sendIQ = _converse.connection.sendIQ; var sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
sent_stanza = iq; sent_stanza = iq;
IQ_id = sendIQ.bind(this)(iq, callback, errback); IQ_id = sendIQ.bind(this)(iq, callback, errback);
}); });
@ -137,7 +137,7 @@
it("can be used to query for a limited set of results", mock.initConverse(function (_converse) { it("can be used to query for a limited set of results", mock.initConverse(function (_converse) {
var sent_stanza, IQ_id; var sent_stanza, IQ_id;
var sendIQ = _converse.connection.sendIQ; var sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
sent_stanza = iq; sent_stanza = iq;
IQ_id = sendIQ.bind(this)(iq, callback, errback); IQ_id = sendIQ.bind(this)(iq, callback, errback);
}); });
@ -169,7 +169,7 @@
it("can be used to page through results", mock.initConverse(function (_converse) { it("can be used to page through results", mock.initConverse(function (_converse) {
var sent_stanza, IQ_id; var sent_stanza, IQ_id;
var sendIQ = _converse.connection.sendIQ; var sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
sent_stanza = iq; sent_stanza = iq;
IQ_id = sendIQ.bind(this)(iq, callback, errback); IQ_id = sendIQ.bind(this)(iq, callback, errback);
}); });
@ -206,7 +206,7 @@
it("accepts \"before\" with an empty string as value to reverse the order", mock.initConverse(function (_converse) { it("accepts \"before\" with an empty string as value to reverse the order", mock.initConverse(function (_converse) {
var sent_stanza, IQ_id; var sent_stanza, IQ_id;
var sendIQ = _converse.connection.sendIQ; var sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
sent_stanza = iq; sent_stanza = iq;
IQ_id = sendIQ.bind(this)(iq, callback, errback); IQ_id = sendIQ.bind(this)(iq, callback, errback);
}); });
@ -242,7 +242,7 @@
} }
var sent_stanza, IQ_id; var sent_stanza, IQ_id;
var sendIQ = _converse.connection.sendIQ; var sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
sent_stanza = iq; sent_stanza = iq;
IQ_id = sendIQ.bind(this)(iq, callback, errback); IQ_id = sendIQ.bind(this)(iq, callback, errback);
}); });
@ -280,7 +280,7 @@
} }
var sent_stanza, IQ_id; var sent_stanza, IQ_id;
var sendIQ = _converse.connection.sendIQ; var sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
sent_stanza = iq; sent_stanza = iq;
IQ_id = sendIQ.bind(this)(iq, callback, errback); IQ_id = sendIQ.bind(this)(iq, callback, errback);
}); });
@ -352,7 +352,7 @@
_converse.connection._dataRecv(test_utils.createRequest(stanza)); _converse.connection._dataRecv(test_utils.createRequest(stanza));
expect(callback).toHaveBeenCalled(); expect(callback).toHaveBeenCalled();
var args = callback.argsForCall[0]; var args = callback.calls.argsFor(0);
expect(args[0].length).toBe(2); expect(args[0].length).toBe(2);
expect(args[0][0].outerHTML).toBe(msg1.nodeTree.outerHTML); expect(args[0][0].outerHTML).toBe(msg1.nodeTree.outerHTML);
expect(args[0][1].outerHTML).toBe(msg2.nodeTree.outerHTML); expect(args[0][1].outerHTML).toBe(msg2.nodeTree.outerHTML);
@ -370,17 +370,17 @@
it("is set once server support for MAM has been confirmed", mock.initConverse(function (_converse) { it("is set once server support for MAM has been confirmed", mock.initConverse(function (_converse) {
var sent_stanza, IQ_id; var sent_stanza, IQ_id;
var sendIQ = _converse.connection.sendIQ; var sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
sent_stanza = iq; sent_stanza = iq;
IQ_id = sendIQ.bind(this)(iq, callback, errback); IQ_id = sendIQ.bind(this)(iq, callback, errback);
}); });
spyOn(_converse, 'onMAMPreferences').andCallThrough(); spyOn(_converse, 'onMAMPreferences').and.callThrough();
_converse.message_archiving = 'never'; _converse.message_archiving = 'never';
var feature = new _converse.Feature({ var feature = new _converse.Feature({
'var': Strophe.NS.MAM 'var': Strophe.NS.MAM
}); });
spyOn(feature, 'save').andCallFake(feature.set); // Save will complain about a url not being set spyOn(feature, 'save').and.callFake(feature.set); // Save will complain about a url not being set
_converse.features.onFeatureAdded(feature); _converse.features.onFeatureAdded(feature);
expect(_converse.connection.sendIQ).toHaveBeenCalled(); expect(_converse.connection.sendIQ).toHaveBeenCalled();
@ -407,7 +407,7 @@
expect(_converse.onMAMPreferences).toHaveBeenCalled(); expect(_converse.onMAMPreferences).toHaveBeenCalled();
expect(_converse.connection.sendIQ.callCount).toBe(2); expect(_converse.connection.sendIQ.calls.count()).toBe(2);
expect(sent_stanza.toString()).toBe( expect(sent_stanza.toString()).toBe(
"<iq type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+ "<iq type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
"<prefs xmlns='urn:xmpp:mam:0' default='never'>"+ "<prefs xmlns='urn:xmpp:mam:0' default='never'>"+

View File

@ -1,5 +1,5 @@
(function (root, factory) { (function (root, factory) {
define(["mock", "converse-core", "test_utils"], factory); define(["mock", "converse-core", "test-utils"], factory);
} (this, function (mock, converse, test_utils) { } (this, function (mock, converse, test_utils) {
var _ = converse.env._; var _ = converse.env._;
var $msg = converse.env.$msg; var $msg = converse.env.$msg;

View File

@ -1,5 +1,5 @@
(function (root, factory) { (function (root, factory) {
define(["mock", "converse-core", "test_utils", "utils"], factory); define(["mock", "converse-core", "test-utils", "utils"], factory);
} (this, function (mock, converse, test_utils, utils) { } (this, function (mock, converse, test_utils, utils) {
"use strict"; "use strict";
var _ = converse.env._; var _ = converse.env._;
@ -16,7 +16,7 @@
// TODO: not yet testing show_desktop_notifications setting // TODO: not yet testing show_desktop_notifications setting
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
spyOn(_converse, 'showMessageNotification'); spyOn(_converse, 'showMessageNotification');
spyOn(_converse, 'areDesktopNotificationsEnabled').andReturn(true); spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
var message = 'This message will show a desktop notification'; var message = 'This message will show a desktop notification';
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost', var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost',
@ -46,8 +46,8 @@
}; };
}; };
} }
spyOn(_converse, 'showMessageNotification').andCallThrough(); spyOn(_converse, 'showMessageNotification').and.callThrough();
spyOn(_converse, 'areDesktopNotificationsEnabled').andReturn(true); spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
var message = 'dummy: This message will show a desktop notification'; var message = 'dummy: This message will show a desktop notification';
var nick = mock.chatroom_names[0], var nick = mock.chatroom_names[0],
@ -66,56 +66,46 @@
})); }));
it("is shown for headline messages", mock.initConverse(function (_converse) { it("is shown for headline messages", mock.initConverse(function (_converse) {
spyOn(_converse, 'showMessageNotification').andCallThrough(); spyOn(_converse, 'showMessageNotification').and.callThrough();
spyOn(_converse, 'areDesktopNotificationsEnabled').andReturn(true); spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
runs(function () { var stanza = $msg({
var stanza = $msg({ 'type': 'headline',
'type': 'headline', 'from': 'notify.example.com',
'from': 'notify.example.com', 'to': 'dummy@localhost',
'to': 'dummy@localhost', 'xml:lang': 'en'
'xml:lang': 'en' })
}) .c('subject').t('SIEVE').up()
.c('subject').t('SIEVE').up() .c('body').t('&lt;juliet@example.com&gt; You got mail.').up()
.c('body').t('&lt;juliet@example.com&gt; You got mail.').up() .c('x', {'xmlns': 'jabber:x:oob'})
.c('x', {'xmlns': 'jabber:x:oob'}) .c('url').t('imap://romeo@example.com/INBOX;UIDVALIDITY=385759043/;UID=18');
.c('url').t('imap://romeo@example.com/INBOX;UIDVALIDITY=385759043/;UID=18'); _converse.connection._dataRecv(test_utils.createRequest(stanza));
_converse.connection._dataRecv(test_utils.createRequest(stanza)); expect(
}); _.includes(_converse.chatboxviews.keys(),
waits(250); 'notify.example.com')
runs(function () { ).toBeTruthy();
expect( expect(_converse.showMessageNotification).toHaveBeenCalled();
_.includes(_converse.chatboxviews.keys(),
'notify.example.com')
).toBeTruthy();
expect(_converse.showMessageNotification).toHaveBeenCalled();
});
})); }));
it("is not shown for full JID headline messages if allow_non_roster_messaging is false", mock.initConverse(function (_converse) { it("is not shown for full JID headline messages if allow_non_roster_messaging is false", mock.initConverse(function (_converse) {
_converse.allow_non_roster_messaging = false; _converse.allow_non_roster_messaging = false;
spyOn(_converse, 'showMessageNotification').andCallThrough(); spyOn(_converse, 'showMessageNotification').and.callThrough();
spyOn(_converse, 'areDesktopNotificationsEnabled').andReturn(true); spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
runs(function () { var stanza = $msg({
var stanza = $msg({ 'type': 'headline',
'type': 'headline', 'from': 'someone@notify.example.com',
'from': 'someone@notify.example.com', 'to': 'dummy@localhost',
'to': 'dummy@localhost', 'xml:lang': 'en'
'xml:lang': 'en' })
}) .c('subject').t('SIEVE').up()
.c('subject').t('SIEVE').up() .c('body').t('&lt;juliet@example.com&gt; You got mail.').up()
.c('body').t('&lt;juliet@example.com&gt; You got mail.').up() .c('x', {'xmlns': 'jabber:x:oob'})
.c('x', {'xmlns': 'jabber:x:oob'}) .c('url').t('imap://romeo@example.com/INBOX;UIDVALIDITY=385759043/;UID=18');
.c('url').t('imap://romeo@example.com/INBOX;UIDVALIDITY=385759043/;UID=18'); _converse.connection._dataRecv(test_utils.createRequest(stanza));
_converse.connection._dataRecv(test_utils.createRequest(stanza)); expect(
}); _.includes(_converse.chatboxviews.keys(),
waits(250); 'someone@notify.example.com')
runs(function () { ).toBeFalsy();
expect( expect(_converse.showMessageNotification).not.toHaveBeenCalled();
_.includes(_converse.chatboxviews.keys(),
'someone@notify.example.com')
).toBeFalsy();
expect(_converse.showMessageNotification).not.toHaveBeenCalled();
});
})); }));
it("is shown when a user changes their chat state (if show_chatstate_notifications is true)", mock.initConverse(function (_converse) { it("is shown when a user changes their chat state (if show_chatstate_notifications is true)", mock.initConverse(function (_converse) {
@ -123,7 +113,7 @@
_converse.show_chatstate_notifications = true; _converse.show_chatstate_notifications = true;
test_utils.createContacts(_converse, 'current'); test_utils.createContacts(_converse, 'current');
spyOn(_converse, 'areDesktopNotificationsEnabled').andReturn(true); spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
spyOn(_converse, 'showChatStateNotification'); spyOn(_converse, 'showChatStateNotification');
var jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost'; var jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
_converse.roster.get(jid).set('chat_status', 'busy'); // This will emit 'contactStatusChanged' _converse.roster.get(jid).set('chat_status', 'busy'); // This will emit 'contactStatusChanged'
@ -135,7 +125,7 @@
describe("When a new contact request is received", function () { describe("When a new contact request is received", function () {
it("an HTML5 Notification is received", mock.initConverse(function (_converse) { it("an HTML5 Notification is received", mock.initConverse(function (_converse) {
spyOn(_converse, 'areDesktopNotificationsEnabled').andReturn(true); spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
spyOn(_converse, 'showContactRequestNotification'); spyOn(_converse, 'showContactRequestNotification');
_converse.emit('contactRequest', {'fullname': 'Peter Parker', 'jid': 'peter@parker.com'}); _converse.emit('contactRequest', {'fullname': 'Peter Parker', 'jid': 'peter@parker.com'});
expect(_converse.areDesktopNotificationsEnabled).toHaveBeenCalled(); expect(_converse.areDesktopNotificationsEnabled).toHaveBeenCalled();

View File

@ -1,5 +1,5 @@
(function (root, factory) { (function (root, factory) {
define(["mock", "converse-core", "test_utils"], factory); define(["mock", "converse-core", "test-utils"], factory);
} (this, function (mock, converse, test_utils) { } (this, function (mock, converse, test_utils) {
var $ = converse.env.jQuery; var $ = converse.env.jQuery;
var Strophe = converse.env.Strophe; var Strophe = converse.env.Strophe;
@ -41,7 +41,7 @@
spyOn(_converse.connection, 'send'); spyOn(_converse.connection, 'send');
chatbox.set('otr_status', 1); // Set OTR status to UNVERIFIED, to mock an encrypted session chatbox.set('otr_status', 1); // Set OTR status to UNVERIFIED, to mock an encrypted session
chatbox.trigger('sendMessage', new _converse.Message({ message: msgtext })); chatbox.trigger('sendMessage', new _converse.Message({ message: msgtext }));
var $sent = $(_converse.connection.send.argsForCall[0][0].tree()); var $sent = $(_converse.connection.send.calls.argsFor(0)[0].tree());
expect($sent.find('body').siblings('private').length).toBe(1); expect($sent.find('body').siblings('private').length).toBe(1);
expect($sent.find('private').length).toBe(1); expect($sent.find('private').length).toBe(1);
expect($sent.find('private').attr('xmlns')).toBe('urn:xmpp:carbons:2'); expect($sent.find('private').attr('xmlns')).toBe('urn:xmpp:carbons:2');

View File

@ -1,5 +1,5 @@
(function (root, factory) { (function (root, factory) {
define(["mock", "converse-core", "test_utils", "converse-ping"], factory); define(["mock", "converse-core", "test-utils", "converse-ping"], factory);
} (this, function (mock, test_utils) { } (this, function (mock, test_utils) {
"use strict"; "use strict";
@ -7,16 +7,16 @@
describe("Ping and pong handlers", function () { describe("Ping and pong handlers", function () {
it("are registered when _converse.js is connected", mock.initConverse(function (_converse) { it("are registered when _converse.js is connected", mock.initConverse(function (_converse) {
spyOn(_converse, 'registerPingHandler').andCallThrough(); spyOn(_converse, 'registerPingHandler').and.callThrough();
spyOn(_converse, 'registerPongHandler').andCallThrough(); spyOn(_converse, 'registerPongHandler').and.callThrough();
_converse.emit('connected'); _converse.emit('connected');
expect(_converse.registerPingHandler).toHaveBeenCalled(); expect(_converse.registerPingHandler).toHaveBeenCalled();
expect(_converse.registerPongHandler).toHaveBeenCalled(); expect(_converse.registerPongHandler).toHaveBeenCalled();
})); }));
it("are registered when _converse.js reconnected", mock.initConverse(function (_converse) { it("are registered when _converse.js reconnected", mock.initConverse(function (_converse) {
spyOn(_converse, 'registerPingHandler').andCallThrough(); spyOn(_converse, 'registerPingHandler').and.callThrough();
spyOn(_converse, 'registerPongHandler').andCallThrough(); spyOn(_converse, 'registerPongHandler').and.callThrough();
_converse.emit('reconnected'); _converse.emit('reconnected');
expect(_converse.registerPingHandler).toHaveBeenCalled(); expect(_converse.registerPingHandler).toHaveBeenCalled();
expect(_converse.registerPongHandler).toHaveBeenCalled(); expect(_converse.registerPongHandler).toHaveBeenCalled();
@ -28,7 +28,7 @@
it("is sent out when _converse.js pings a server", mock.initConverse(function (_converse) { it("is sent out when _converse.js pings a server", mock.initConverse(function (_converse) {
var sent_stanza, IQ_id; var sent_stanza, IQ_id;
var sendIQ = _converse.connection.sendIQ; var sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
sent_stanza = iq; sent_stanza = iq;
IQ_id = sendIQ.bind(this)(iq, callback, errback); IQ_id = sendIQ.bind(this)(iq, callback, errback);
}); });

View File

@ -5,7 +5,7 @@
"jquery", "jquery",
"converse-core", "converse-core",
"mock", "mock",
"test_utils", "test-utils",
"lodash"], factory); "lodash"], factory);
} (this, function ($, converse, mock, test_utils, _) { } (this, function ($, converse, mock, test_utils, _) {
"use strict"; "use strict";

View File

@ -3,7 +3,7 @@
"jquery", "jquery",
"converse-core", "converse-core",
"mock", "mock",
"test_utils"], factory); "test-utils"], factory);
} (this, function ($, converse, mock, test_utils) { } (this, function ($, converse, mock, test_utils) {
"use strict"; "use strict";
var Strophe = converse.env.Strophe; var Strophe = converse.env.Strophe;
@ -46,175 +46,171 @@
* that session. A client MUST acknowledge each roster push with an IQ * that session. A client MUST acknowledge each roster push with an IQ
* stanza of type "result". * stanza of type "result".
*/ */
it("Subscribe to contact, contact accepts and subscribes back", mock.initConverse(function (_converse) { it("Subscribe to contact, contact accepts and subscribes back", mock.initConverseWithAsync(function (done, _converse) {
/* The process by which a user subscribes to a contact, including /* The process by which a user subscribes to a contact, including
* the interaction between roster items and subscription states. * the interaction between roster items and subscription states.
*/ */
_converse.roster_groups = false; _converse.roster_groups = false;
var contact, stanza, sent_stanza, IQ_id; var contact, stanza, sent_stanza, IQ_id;
runs(function () { test_utils.openControlBox(_converse);
test_utils.openControlBox(_converse); var panel = _converse.chatboxviews.get('controlbox').contactspanel;
spyOn(panel, "addContactFromForm").and.callThrough();
spyOn(_converse.roster, "addAndSubscribe").and.callThrough();
spyOn(_converse.roster, "addContact").and.callThrough();
spyOn(_converse.roster, "sendContactAddIQ").and.callThrough();
spyOn(_converse, "getVCard").and.callThrough();
var sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
sent_stanza = iq;
IQ_id = sendIQ.bind(this)(iq, callback, errback);
}); });
waits(100); panel.delegateEvents(); // Rebind all events so that our spy gets called
runs(function () {
var panel = _converse.chatboxviews.get('controlbox').contactspanel;
spyOn(panel, "addContactFromForm").andCallThrough();
spyOn(_converse.roster, "addAndSubscribe").andCallThrough();
spyOn(_converse.roster, "addContact").andCallThrough();
spyOn(_converse.roster, "sendContactAddIQ").andCallThrough();
spyOn(_converse, "getVCard").andCallThrough();
var sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
sent_stanza = iq;
IQ_id = sendIQ.bind(this)(iq, callback, errback);
});
panel.delegateEvents(); // Rebind all events so that our spy gets called
/* Add a new contact through the UI */ /* Add a new contact through the UI */
var $form = panel.$('form.add-xmpp-contact'); var $form = panel.$('form.add-xmpp-contact');
expect($form.is(":visible")).toBeFalsy(); expect($form.is(":visible")).toBeFalsy();
// Click the "Add a contact" link. // Click the "Add a contact" link.
panel.$('.toggle-xmpp-contact-form').click(); panel.$('.toggle-xmpp-contact-form').click();
// Check that the $form appears // Check that the $form appears
expect($form.is(":visible")).toBeTruthy(); expect($form.is(":visible")).toBeTruthy();
// Fill in the form and submit // Fill in the form and submit
$form.find('input').val('contact@example.org'); $form.find('input').val('contact@example.org');
$form.submit(); $form.submit();
/* In preparation for being able to render the contact in the /* In preparation for being able to render the contact in the
* user's client interface and for the server to keep track of the * user's client interface and for the server to keep track of the
* subscription, the user's client SHOULD perform a "roster set" * subscription, the user's client SHOULD perform a "roster set"
* for the new roster item. * for the new roster item.
*/ */
expect(panel.addContactFromForm).toHaveBeenCalled(); expect(panel.addContactFromForm).toHaveBeenCalled();
expect(_converse.roster.addAndSubscribe).toHaveBeenCalled(); expect(_converse.roster.addAndSubscribe).toHaveBeenCalled();
expect(_converse.roster.addContact).toHaveBeenCalled(); expect(_converse.roster.addContact).toHaveBeenCalled();
// The form should not be visible anymore. // The form should not be visible anymore.
expect($form.is(":visible")).toBeFalsy(); expect($form.is(":visible")).toBeFalsy();
/* _converse request consists of sending an IQ /* _converse request consists of sending an IQ
* stanza of type='set' containing a <query/> element qualified by * stanza of type='set' containing a <query/> element qualified by
* the 'jabber:iq:roster' namespace, which in turn contains an * the 'jabber:iq:roster' namespace, which in turn contains an
* <item/> element that defines the new roster item; the <item/> * <item/> element that defines the new roster item; the <item/>
* element MUST possess a 'jid' attribute, MAY possess a 'name' * element MUST possess a 'jid' attribute, MAY possess a 'name'
* attribute, MUST NOT possess a 'subscription' attribute, and MAY * attribute, MUST NOT possess a 'subscription' attribute, and MAY
* contain one or more <group/> child elements: * contain one or more <group/> child elements:
* *
* <iq type='set' id='set1'> * <iq type='set' id='set1'>
* <query xmlns='jabber:iq:roster'> * <query xmlns='jabber:iq:roster'>
* <item * <item
* jid='contact@example.org' * jid='contact@example.org'
* name='MyContact'> * name='MyContact'>
* <group>MyBuddies</group> * <group>MyBuddies</group>
* </item> * </item>
* </query> * </query>
* </iq> * </iq>
*/ */
expect(_converse.roster.sendContactAddIQ).toHaveBeenCalled(); expect(_converse.roster.sendContactAddIQ).toHaveBeenCalled();
expect(sent_stanza.toLocaleString()).toBe( expect(sent_stanza.toLocaleString()).toBe(
"<iq type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+ "<iq type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
"<query xmlns='jabber:iq:roster'>"+ "<query xmlns='jabber:iq:roster'>"+
"<item jid='contact@example.org' name='contact@example.org'/>"+ "<item jid='contact@example.org' name='contact@example.org'/>"+
"</query>"+ "</query>"+
"</iq>" "</iq>"
); );
/* As a result, the user's server (1) MUST initiate a roster push /* As a result, the user's server (1) MUST initiate a roster push
* for the new roster item to all available resources associated * for the new roster item to all available resources associated
* with _converse user that have requested the roster, setting the * with _converse user that have requested the roster, setting the
* 'subscription' attribute to a value of "none"; and (2) MUST * 'subscription' attribute to a value of "none"; and (2) MUST
* reply to the sending resource with an IQ result indicating the * reply to the sending resource with an IQ result indicating the
* success of the roster set: * success of the roster set:
* *
* <iq type='set'> * <iq type='set'>
* <query xmlns='jabber:iq:roster'> * <query xmlns='jabber:iq:roster'>
* <item * <item
* jid='contact@example.org' * jid='contact@example.org'
* subscription='none' * subscription='none'
* name='MyContact'> * name='MyContact'>
* <group>MyBuddies</group> * <group>MyBuddies</group>
* </item> * </item>
* </query> * </query>
* </iq> * </iq>
*/ */
var create = _converse.roster.create; var create = _converse.roster.create;
spyOn(_converse.connection, 'send').andCallFake(function (stanza) { spyOn(_converse.connection, 'send').and.callFake(function (stanza) {
sent_stanza = stanza; sent_stanza = stanza;
});
spyOn(_converse.roster, 'create').andCallFake(function () {
contact = create.apply(_converse.roster, arguments);
spyOn(contact, 'subscribe').andCallThrough();
return contact;
});
stanza = $iq({'type': 'set'}).c('query', {'xmlns': 'jabber:iq:roster'})
.c('item', {
'jid': 'contact@example.org',
'subscription': 'none',
'name': 'contact@example.org'});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
/*
* <iq type='result' id='set1'/>
*/
stanza = $iq({'type': 'result', 'id':IQ_id});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
// A contact should now have been created
expect(_converse.roster.get('contact@example.org') instanceof _converse.RosterContact).toBeTruthy();
expect(contact.get('jid')).toBe('contact@example.org');
expect(_converse.getVCard).toHaveBeenCalled();
/* To subscribe to the contact's presence information,
* the user's client MUST send a presence stanza of
* type='subscribe' to the contact:
*
* <presence to='contact@example.org' type='subscribe'/>
*/
expect(contact.subscribe).toHaveBeenCalled();
expect(sent_stanza.toLocaleString()).toBe( // Strophe adds the xmlns attr (although not in spec)
"<presence to='contact@example.org' type='subscribe' xmlns='jabber:client'>"+
"<nick xmlns='http://jabber.org/protocol/nick'>Max Mustermann</nick>"+
"</presence>"
);
/* As a result, the user's server MUST initiate a second roster
* push to all of the user's available resources that have
* requested the roster, setting the contact to the pending
* sub-state of the 'none' subscription state; _converse pending
* sub-state is denoted by the inclusion of the ask='subscribe'
* attribute in the roster item:
*
* <iq type='set'>
* <query xmlns='jabber:iq:roster'>
* <item
* jid='contact@example.org'
* subscription='none'
* ask='subscribe'
* name='MyContact'>
* <group>MyBuddies</group>
* </item>
* </query>
* </iq>
*/
spyOn(_converse.roster, "updateContact").andCallThrough();
stanza = $iq({'type': 'set', 'from': 'dummy@localhost'})
.c('query', {'xmlns': 'jabber:iq:roster'})
.c('item', {
'jid': 'contact@example.org',
'subscription': 'none',
'ask': 'subscribe',
'name': 'contact@example.org'});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
expect(_converse.roster.updateContact).toHaveBeenCalled();
}); });
waits(50); spyOn(_converse.roster, 'create').and.callFake(function () {
runs(function () { contact = create.apply(_converse.roster, arguments);
// Check that the user is now properly shown as a pending spyOn(contact, 'subscribe').and.callThrough();
// contact in the roster. return contact;
});
stanza = $iq({'type': 'set'}).c('query', {'xmlns': 'jabber:iq:roster'})
.c('item', {
'jid': 'contact@example.org',
'subscription': 'none',
'name': 'contact@example.org'});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
/*
* <iq type='result' id='set1'/>
*/
stanza = $iq({'type': 'result', 'id':IQ_id});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
// A contact should now have been created
expect(_converse.roster.get('contact@example.org') instanceof _converse.RosterContact).toBeTruthy();
expect(contact.get('jid')).toBe('contact@example.org');
expect(_converse.getVCard).toHaveBeenCalled();
/* To subscribe to the contact's presence information,
* the user's client MUST send a presence stanza of
* type='subscribe' to the contact:
*
* <presence to='contact@example.org' type='subscribe'/>
*/
expect(contact.subscribe).toHaveBeenCalled();
expect(sent_stanza.toLocaleString()).toBe( // Strophe adds the xmlns attr (although not in spec)
"<presence to='contact@example.org' type='subscribe' xmlns='jabber:client'>"+
"<nick xmlns='http://jabber.org/protocol/nick'>Max Mustermann</nick>"+
"</presence>"
);
/* As a result, the user's server MUST initiate a second roster
* push to all of the user's available resources that have
* requested the roster, setting the contact to the pending
* sub-state of the 'none' subscription state; _converse pending
* sub-state is denoted by the inclusion of the ask='subscribe'
* attribute in the roster item:
*
* <iq type='set'>
* <query xmlns='jabber:iq:roster'>
* <item
* jid='contact@example.org'
* subscription='none'
* ask='subscribe'
* name='MyContact'>
* <group>MyBuddies</group>
* </item>
* </query>
* </iq>
*/
spyOn(_converse.roster, "updateContact").and.callThrough();
stanza = $iq({'type': 'set', 'from': 'dummy@localhost'})
.c('query', {'xmlns': 'jabber:iq:roster'})
.c('item', {
'jid': 'contact@example.org',
'subscription': 'none',
'ask': 'subscribe',
'name': 'contact@example.org'});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
expect(_converse.roster.updateContact).toHaveBeenCalled();
// Check that the user is now properly shown as a pending
// contact in the roster.
test_utils.waitUntil(function () {
return $('a:contains("Pending contacts")').length;
}).then(function () {
var $header = $('a:contains("Pending contacts")'); var $header = $('a:contains("Pending contacts")');
expect($header.length).toBe(1); expect($header.length).toBe(1);
expect($header.is(":visible")).toBeTruthy(); expect($header.is(":visible")).toBeTruthy();
var $contacts = $header.parent().nextUntil('dt', 'dd'); var $contacts = $header.parent().nextUntil('dt', 'dd');
expect($contacts.length).toBe(1); expect($contacts.length).toBe(1);
spyOn(contact, "ackSubscribe").andCallThrough(); spyOn(contact, "ackSubscribe").and.callThrough();
/* Here we assume the "happy path" that the contact /* Here we assume the "happy path" that the contact
* approves the subscription request * approves the subscription request
* *
@ -301,8 +297,8 @@
* *
* <presence from='contact@example.org' to='user@example.com' type='subscribe'/> * <presence from='contact@example.org' to='user@example.com' type='subscribe'/>
*/ */
spyOn(contact, 'authorize').andCallThrough(); spyOn(contact, 'authorize').and.callThrough();
spyOn(_converse.roster, 'handleIncomingSubscription').andCallThrough(); spyOn(_converse.roster, 'handleIncomingSubscription').and.callThrough();
stanza = $pres({ stanza = $pres({
'to': _converse.bare_jid, 'to': _converse.bare_jid,
'from': 'contact@example.org/resource', 'from': 'contact@example.org/resource',
@ -348,6 +344,7 @@
// The class on the contact will now have switched. // The class on the contact will now have switched.
expect($contacts.hasClass('to')).toBeFalsy(); expect($contacts.hasClass('to')).toBeFalsy();
expect($contacts.hasClass('both')).toBeTruthy(); expect($contacts.hasClass('both')).toBeTruthy();
done();
}); });
})); }));
@ -356,110 +353,101 @@
* the interaction between roster items and subscription states. * the interaction between roster items and subscription states.
*/ */
var contact, stanza, sent_stanza, sent_IQ; var contact, stanza, sent_stanza, sent_IQ;
runs(function () { test_utils.openControlBox(_converse);
test_utils.openControlBox(_converse); // Add a new roster contact via roster push
}); stanza = $iq({'type': 'set'}).c('query', {'xmlns': 'jabber:iq:roster'})
waits(100); .c('item', {
runs(function () { 'jid': 'contact@example.org',
// Add a new roster contact via roster push 'subscription': 'none',
stanza = $iq({'type': 'set'}).c('query', {'xmlns': 'jabber:iq:roster'}) 'ask': 'subscribe',
.c('item', { 'name': 'contact@example.org'});
'jid': 'contact@example.org', _converse.connection._dataRecv(test_utils.createRequest(stanza));
'subscription': 'none', // A pending contact should now exist.
'ask': 'subscribe', contact = _converse.roster.get('contact@example.org');
'name': 'contact@example.org'}); expect(_converse.roster.get('contact@example.org') instanceof _converse.RosterContact).toBeTruthy();
_converse.connection._dataRecv(test_utils.createRequest(stanza)); spyOn(contact, "ackUnsubscribe").and.callThrough();
});
waits(50);
runs(function () {
// A pending contact should now exist.
contact = _converse.roster.get('contact@example.org');
expect(_converse.roster.get('contact@example.org') instanceof _converse.RosterContact).toBeTruthy();
spyOn(contact, "ackUnsubscribe").andCallThrough();
spyOn(_converse.connection, 'send').andCallFake(function (stanza) { spyOn(_converse.connection, 'send').and.callFake(function (stanza) {
sent_stanza = stanza; sent_stanza = stanza;
});
spyOn(_converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
sent_IQ = iq;
});
/* We now assume the contact declines the subscription
* requests.
*
/* Upon receiving the presence stanza of type "unsubscribed"
* addressed to the user, the user's server (1) MUST deliver
* that presence stanza to the user and (2) MUST initiate a
* roster push to all of the user's available resources that
* have requested the roster, containing an updated roster
* item for the contact with the 'subscription' attribute
* set to a value of "none" and with no 'ask' attribute:
*
* <presence
* from='contact@example.org'
* to='user@example.com'
* type='unsubscribed'/>
*
* <iq type='set'>
* <query xmlns='jabber:iq:roster'>
* <item
* jid='contact@example.org'
* subscription='none'
* name='MyContact'>
* <group>MyBuddies</group>
* </item>
* </query>
* </iq>
*/
// FIXME: also add the <iq>
stanza = $pres({
'to': _converse.bare_jid,
'from': 'contact@example.org',
'type': 'unsubscribed'
});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
/* Upon receiving the presence stanza of type "unsubscribed",
* the user SHOULD acknowledge receipt of that subscription
* state notification through either "affirming" it by
* sending a presence stanza of type "unsubscribe
*/
expect(contact.ackUnsubscribe).toHaveBeenCalled();
expect(sent_stanza.toLocaleString()).toBe(
"<presence type='unsubscribe' to='contact@example.org' xmlns='jabber:client'/>"
);
/* _converse.js will then also automatically remove the
* contact from the user's roster.
*/
expect(sent_IQ.toLocaleString()).toBe(
"<iq type='set' xmlns='jabber:client'>"+
"<query xmlns='jabber:iq:roster'>"+
"<item jid='contact@example.org' subscription='remove'/>"+
"</query>"+
"</iq>"
);
}); });
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
sent_IQ = iq;
});
/* We now assume the contact declines the subscription
* requests.
*
/* Upon receiving the presence stanza of type "unsubscribed"
* addressed to the user, the user's server (1) MUST deliver
* that presence stanza to the user and (2) MUST initiate a
* roster push to all of the user's available resources that
* have requested the roster, containing an updated roster
* item for the contact with the 'subscription' attribute
* set to a value of "none" and with no 'ask' attribute:
*
* <presence
* from='contact@example.org'
* to='user@example.com'
* type='unsubscribed'/>
*
* <iq type='set'>
* <query xmlns='jabber:iq:roster'>
* <item
* jid='contact@example.org'
* subscription='none'
* name='MyContact'>
* <group>MyBuddies</group>
* </item>
* </query>
* </iq>
*/
// FIXME: also add the <iq>
stanza = $pres({
'to': _converse.bare_jid,
'from': 'contact@example.org',
'type': 'unsubscribed'
});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
/* Upon receiving the presence stanza of type "unsubscribed",
* the user SHOULD acknowledge receipt of that subscription
* state notification through either "affirming" it by
* sending a presence stanza of type "unsubscribe
*/
expect(contact.ackUnsubscribe).toHaveBeenCalled();
expect(sent_stanza.toLocaleString()).toBe(
"<presence type='unsubscribe' to='contact@example.org' xmlns='jabber:client'/>"
);
/* _converse.js will then also automatically remove the
* contact from the user's roster.
*/
expect(sent_IQ.toLocaleString()).toBe(
"<iq type='set' xmlns='jabber:client'>"+
"<query xmlns='jabber:iq:roster'>"+
"<item jid='contact@example.org' subscription='remove'/>"+
"</query>"+
"</iq>"
);
})); }));
it("Unsubscribe to a contact when subscription is mutual", mock.initConverse(function (_converse) { it("Unsubscribe to a contact when subscription is mutual", mock.initConverseWithAsync(function (done, _converse) {
var sent_IQ, IQ_id, jid = 'annegreet.gomez@localhost'; var sent_IQ, IQ_id, jid = 'annegreet.gomez@localhost';
_converse.roster_groups = false; _converse.roster_groups = false;
runs(function () { test_utils.openControlBox(_converse);
test_utils.openControlBox(_converse); test_utils.createContacts(_converse, 'current');
test_utils.createContacts(_converse, 'current'); spyOn(window, 'confirm').and.returnValue(true);
// We now have a contact we want to remove
expect(_converse.roster.get(jid) instanceof _converse.RosterContact).toBeTruthy();
var sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
sent_IQ = iq;
IQ_id = sendIQ.bind(this)(iq, callback, errback);
}); });
waits(50);
runs(function () {
spyOn(window, 'confirm').andReturn(true);
// We now have a contact we want to remove
expect(_converse.roster.get(jid) instanceof _converse.RosterContact).toBeTruthy();
var sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
sent_IQ = iq;
IQ_id = sendIQ.bind(this)(iq, callback, errback);
});
test_utils.waitUntil(function () {
return $('a:contains("My contacts")').length;
}).then(function () {
var $header = $('a:contains("My contacts")'); var $header = $('a:contains("My contacts")');
// remove the first user // remove the first user
$($header.parent().nextUntil('dt', 'dd').find('.remove-xmpp-contact').get(0)).click(); $($header.parent().nextUntil('dt', 'dd').find('.remove-xmpp-contact').get(0)).click();
@ -497,31 +485,31 @@
_converse.connection._dataRecv(test_utils.createRequest(stanza)); _converse.connection._dataRecv(test_utils.createRequest(stanza));
// Our contact has now been removed // Our contact has now been removed
expect(typeof _converse.roster.get(jid) === "undefined").toBeTruthy(); expect(typeof _converse.roster.get(jid) === "undefined").toBeTruthy();
done();
}); });
})); }));
it("Receiving a subscription request", mock.initConverse(function (_converse) { it("Receiving a subscription request", mock.initConverse(function (_converse) {
runs(function () { test_utils.openControlBox(_converse);
test_utils.openControlBox(_converse); test_utils.createContacts(_converse, 'current'); // Create some contacts so that we can test positioning
test_utils.createContacts(_converse, 'current'); // Create some contacts so that we can test positioning spyOn(_converse, "emit");
}); /* <presence
waits(50); * from='user@example.com'
runs(function () { * to='contact@example.org'
spyOn(_converse, "emit"); * type='subscribe'/>
/* <presence */
* from='user@example.com' var stanza = $pres({
* to='contact@example.org' 'to': _converse.bare_jid,
* type='subscribe'/> 'from': 'contact@example.org',
*/ 'type': 'subscribe'
var stanza = $pres({ }).c('nick', {
'to': _converse.bare_jid, 'xmlns': Strophe.NS.NICK,
'from': 'contact@example.org', }).t('Clint Contact');
'type': 'subscribe' _converse.connection._dataRecv(test_utils.createRequest(stanza));
}).c('nick', { expect(_converse.emit).toHaveBeenCalledWith('contactRequest', jasmine.any(Object));
'xmlns': Strophe.NS.NICK, test_utils.waitUntil(function () {
}).t('Clint Contact'); return $('a:contains("Contact requests")').length;
_converse.connection._dataRecv(test_utils.createRequest(stanza)); }).then(function () {
expect(_converse.emit).toHaveBeenCalledWith('contactRequest', jasmine.any(Object));
var $header = $('a:contains("Contact requests")'); var $header = $('a:contains("Contact requests")');
expect($header.length).toBe(1); expect($header.length).toBe(1);
expect($header.is(":visible")).toBeTruthy(); expect($header.is(":visible")).toBeTruthy();

View File

@ -1,5 +1,5 @@
(function (root, factory) { (function (root, factory) {
define(["mock", "converse-core", "test_utils"], factory); define(["mock", "converse-core", "test-utils"], factory);
} (this, function (mock, converse, test_utils) { } (this, function (mock, converse, test_utils) {
var $ = converse.env.jQuery; var $ = converse.env.jQuery;
var Strophe = converse.env.Strophe; var Strophe = converse.env.Strophe;
@ -8,44 +8,40 @@
describe("The Registration Panel", function () { describe("The Registration Panel", function () {
it("is not available unless allow_registration=true", mock.initConverse(function (_converse) { it("is not available unless allow_registration=true", mock.initConverse(function (_converse) {
runs(test_utils.openControlBox); test_utils.openControlBox();
waits(50); var cbview = _converse.chatboxviews.get('controlbox');
runs(function () { expect(cbview.$('#controlbox-tabs li').length).toBe(1);
var cbview = _converse.chatboxviews.get('controlbox'); expect(cbview.$('#controlbox-tabs li').text().trim()).toBe("Sign in");
expect(cbview.$('#controlbox-tabs li').length).toBe(1);
expect(cbview.$('#controlbox-tabs li').text().trim()).toBe("Sign in"); }, { auto_login: false,
}); allow_registration: false,
}, { auto_login: false, }));
allow_registration: false,
}));
it("can be opened by clicking on the registration tab", mock.initConverse(function (_converse) { it("can be opened by clicking on the registration tab", mock.initConverse(function (_converse) {
var cbview = _converse.chatboxviews.get('controlbox'); var cbview = _converse.chatboxviews.get('controlbox');
runs(test_utils.openControlBox); test_utils.openControlBox();
waits(50); var $tabs = cbview.$('#controlbox-tabs');
runs(function () { var $panels = cbview.$('.controlbox-panes');
var $tabs = cbview.$('#controlbox-tabs'); var $login = $panels.children().first();
var $panels = cbview.$('.controlbox-panes'); var $registration = $panels.children().last();
var $login = $panels.children().first(); expect($tabs.find('li').first().text()).toBe('Sign in');
var $registration = $panels.children().last(); expect($tabs.find('li').last().text()).toBe('Register');
expect($tabs.find('li').first().text()).toBe('Sign in');
expect($tabs.find('li').last().text()).toBe('Register');
spyOn(cbview, 'switchTab').andCallThrough(); spyOn(cbview, 'switchTab').and.callThrough();
cbview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called 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 $tabs.find('li').last().find('a').click(); // Click the Register tab
expect($login.is(':visible')).toBe(false); expect($login.is(':visible')).toBe(false);
expect($registration.is(':visible')).toBe(true); expect($registration.is(':visible')).toBe(true);
expect(cbview.switchTab).toHaveBeenCalled(); expect(cbview.switchTab).toHaveBeenCalled();
});
}, { auto_login: false, }, { auto_login: false,
allow_registration: true, allow_registration: true,
})); }));
it("allows the user to choose an XMPP provider's domain", mock.initConverse(function (_converse) { it("allows the user to choose an XMPP provider's domain", mock.initConverse(function (_converse) {
var cbview = _converse.chatboxviews.get('controlbox'); var cbview = _converse.chatboxviews.get('controlbox');
var registerview = cbview.registerpanel; var registerview = cbview.registerpanel;
spyOn(registerview, 'onProviderChosen').andCallThrough(); spyOn(registerview, 'onProviderChosen').and.callThrough();
registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
spyOn(_converse.connection, 'connect'); spyOn(_converse.connection, 'connect');
var $tabs = cbview.$('#controlbox-tabs'); var $tabs = cbview.$('#controlbox-tabs');
@ -72,12 +68,12 @@
var cbview = _converse.chatboxviews.get('controlbox'); var cbview = _converse.chatboxviews.get('controlbox');
cbview.$('#controlbox-tabs').find('li').last().find('a').click(); // Click the Register tab cbview.$('#controlbox-tabs').find('li').last().find('a').click(); // Click the Register tab
var registerview = _converse.chatboxviews.get('controlbox').registerpanel; var registerview = _converse.chatboxviews.get('controlbox').registerpanel;
spyOn(registerview, 'onProviderChosen').andCallThrough(); spyOn(registerview, 'onProviderChosen').and.callThrough();
spyOn(registerview, 'getRegistrationFields').andCallThrough(); spyOn(registerview, 'getRegistrationFields').and.callThrough();
spyOn(registerview, 'onRegistrationFields').andCallThrough(); spyOn(registerview, 'onRegistrationFields').and.callThrough();
spyOn(registerview, 'renderRegistrationForm').andCallThrough(); spyOn(registerview, 'renderRegistrationForm').and.callThrough();
registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
spyOn(_converse.connection, 'connect').andCallThrough(); spyOn(_converse.connection, 'connect').and.callThrough();
expect(registerview._registering).toBeFalsy(); expect(registerview._registering).toBeFalsy();
expect(_converse.connection.connected).toBeFalsy(); expect(_converse.connection.connected).toBeFalsy();
@ -120,12 +116,12 @@
var cbview = _converse.chatboxviews.get('controlbox'); var cbview = _converse.chatboxviews.get('controlbox');
cbview.$('#controlbox-tabs').find('li').last().find('a').click(); // Click the Register tab cbview.$('#controlbox-tabs').find('li').last().find('a').click(); // Click the Register tab
var registerview = _converse.chatboxviews.get('controlbox').registerpanel; var registerview = _converse.chatboxviews.get('controlbox').registerpanel;
spyOn(registerview, 'onProviderChosen').andCallThrough(); spyOn(registerview, 'onProviderChosen').and.callThrough();
spyOn(registerview, 'getRegistrationFields').andCallThrough(); spyOn(registerview, 'getRegistrationFields').and.callThrough();
spyOn(registerview, 'onRegistrationFields').andCallThrough(); spyOn(registerview, 'onRegistrationFields').and.callThrough();
spyOn(registerview, 'renderRegistrationForm').andCallThrough(); spyOn(registerview, 'renderRegistrationForm').and.callThrough();
registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
spyOn(_converse.connection, 'connect').andCallThrough(); spyOn(_converse.connection, 'connect').and.callThrough();
registerview.$('input[name=domain]').val('conversejs.org'); registerview.$('input[name=domain]').val('conversejs.org');
registerview.$('input[type=submit]').click(); registerview.$('input[type=submit]').click();
@ -158,7 +154,7 @@
registerview.$('input[type=submit]').click(); registerview.$('input[type=submit]').click();
expect(_converse.connection.send).toHaveBeenCalled(); expect(_converse.connection.send).toHaveBeenCalled();
var $stanza = $(_converse.connection.send.argsForCall[0][0].tree()); var $stanza = $(_converse.connection.send.calls.argsFor(0)[0].tree());
expect($stanza.children('query').children().length).toBe(3); expect($stanza.children('query').children().length).toBe(3);
expect($stanza.children('query').children()[0].tagName).toBe('username'); expect($stanza.children('query').children()[0].tagName).toBe('username');
}, { auto_login: false, }, { auto_login: false,
@ -169,12 +165,12 @@
var cbview = _converse.chatboxviews.get('controlbox'); var cbview = _converse.chatboxviews.get('controlbox');
cbview.$('#controlbox-tabs').find('li').last().find('a').click(); // Click the Register tab cbview.$('#controlbox-tabs').find('li').last().find('a').click(); // Click the Register tab
var registerview = _converse.chatboxviews.get('controlbox').registerpanel; var registerview = _converse.chatboxviews.get('controlbox').registerpanel;
spyOn(registerview, 'onProviderChosen').andCallThrough(); spyOn(registerview, 'onProviderChosen').and.callThrough();
spyOn(registerview, 'getRegistrationFields').andCallThrough(); spyOn(registerview, 'getRegistrationFields').and.callThrough();
spyOn(registerview, 'onRegistrationFields').andCallThrough(); spyOn(registerview, 'onRegistrationFields').and.callThrough();
spyOn(registerview, 'renderRegistrationForm').andCallThrough(); spyOn(registerview, 'renderRegistrationForm').and.callThrough();
registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called registerview.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
spyOn(_converse.connection, 'connect').andCallThrough(); spyOn(_converse.connection, 'connect').and.callThrough();
registerview.$('input[name=domain]').val('conversejs.org'); registerview.$('input[name=domain]').val('conversejs.org');
registerview.$('input[type=submit]').click(); registerview.$('input[type=submit]').click();
@ -209,7 +205,7 @@
registerview.$('input[type=submit]').click(); registerview.$('input[type=submit]').click();
expect(_converse.connection.send).toHaveBeenCalled(); expect(_converse.connection.send).toHaveBeenCalled();
var $stanza = $(_converse.connection.send.argsForCall[0][0].tree()); var $stanza = $(_converse.connection.send.calls.argsFor(0)[0].tree());
expect($stanza.children('query').children().length).toBe(1); expect($stanza.children('query').children().length).toBe(1);
expect($stanza.children('query').children().children().length).toBe(3); expect($stanza.children('query').children().children().length).toBe(3);
expect($stanza.children('query').children().children()[0].tagName).toBe('field'); expect($stanza.children('query').children().children()[0].tagName).toBe('field');

View File

@ -1,6 +1,6 @@
(function (root, factory) { (function (root, factory) {
define(["converse-core"], factory); define(["jasmine-html", "converse-core"], factory);
} (this, function (converse) { } (this, function (jasmine, converse) {
var utils = converse.env.utils, var utils = converse.env.utils,
_ = converse.env._; _ = converse.env._;

View File

@ -1,5 +1,5 @@
(function (root, factory) { (function (root, factory) {
define(["mock", "converse-core", "test_utils"], factory); define(["mock", "converse-core", "test-utils"], factory);
} (this, function (mock, converse, test_utils) { } (this, function (mock, converse, test_utils) {
var $ = converse.env.jQuery; var $ = converse.env.jQuery;
@ -7,11 +7,11 @@
it("won't send <show>online</show> when setting a custom status message", mock.initConverse(function (_converse) { it("won't send <show>online</show> when setting a custom status message", mock.initConverse(function (_converse) {
_converse.xmppstatus.save({'status': 'online'}); _converse.xmppstatus.save({'status': 'online'});
spyOn(_converse.xmppstatus, 'setStatusMessage').andCallThrough(); spyOn(_converse.xmppstatus, 'setStatusMessage').and.callThrough();
spyOn(_converse.connection, 'send'); spyOn(_converse.connection, 'send');
_converse.xmppstatus.setStatusMessage("I'm also happy!"); _converse.xmppstatus.setStatusMessage("I'm also happy!");
expect(_converse.connection.send).toHaveBeenCalled(); expect(_converse.connection.send).toHaveBeenCalled();
var $stanza = $(_converse.connection.send.argsForCall[0][0].tree()); var $stanza = $(_converse.connection.send.calls.argsFor(0)[0].tree());
expect($stanza.children().length).toBe(2); expect($stanza.children().length).toBe(2);
expect($stanza.children('status').length).toBe(1); expect($stanza.children('status').length).toBe(1);
expect($stanza.children('status').text()).toBe("I'm also happy!"); expect($stanza.children('status').text()).toBe("I'm also happy!");

View File

@ -21,6 +21,7 @@ require.config({
"backbone.browserStorage": "node_modules/backbone.browserStorage/backbone.browserStorage", "backbone.browserStorage": "node_modules/backbone.browserStorage/backbone.browserStorage",
"backbone.overview": "node_modules/backbone.overview/backbone.overview", "backbone.overview": "node_modules/backbone.overview/backbone.overview",
"eventemitter": "node_modules/otr/build/dep/eventemitter", "eventemitter": "node_modules/otr/build/dep/eventemitter",
"es6-promise": "node_modules/es6-promise/dist/es6-promise",
"jquery": "node_modules/jquery/dist/jquery", "jquery": "node_modules/jquery/dist/jquery",
"jquery-private": "src/jquery-private", "jquery-private": "src/jquery-private",
"jquery.browser": "node_modules/jquery.browser/dist/jquery.browser", "jquery.browser": "node_modules/jquery.browser/dist/jquery.browser",

View File

@ -4,12 +4,16 @@
<head> <head>
<title>Converse.js Tests</title> <title>Converse.js Tests</title>
<meta name="description" content="Converse.js: A chat client for your website" /> <meta name="description" content="Converse.js: A chat client for your website" />
<link rel="shortcut icon" type="image/png" href="components/jasmine/images/jasmine_favicon.png"> <link rel="shortcut icon" type="image/png" href="node_modules/jasmine-core/images/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" media="screen" href="node_modules/jasmine-core/lib/jasmine-core/jasmine.css">
<link rel="stylesheet" type="text/css" media="screen" href="css/jasmine.css"> <link rel="stylesheet" type="text/css" media="screen" href="css/jasmine.css">
<link type="text/css" rel="stylesheet" media="screen" href="css/theme.css" /> <link type="text/css" rel="stylesheet" media="screen" href="css/theme.css" />
<link type="text/css" rel="stylesheet" media="screen" href="css/converse.css" /> <link type="text/css" rel="stylesheet" media="screen" href="css/converse.css" />
<script src="src/config.js"></script> <script src="src/config.js"></script>
<script data-main="tests/main" src="node_modules/requirejs/require.js"></script> <script data-main="tests/runner" src="node_modules/requirejs/require.js"></script>
<style> <style>
.tests-brand-heading { .tests-brand-heading {
margin-top: 1em; margin-top: 1em;
@ -21,7 +25,8 @@
<body> <body>
<div id="header_wrap" class="outer"> <div id="header_wrap" class="outer">
<header class="inner"> <header class="inner">
<h1 class="brand-heading tests-brand-heading"><i class="icon-conversejs"></i> Converse.js</h1> <h1 class="brand-heading tests-brand-heading">
<i class="icon-conversejs"></i> Converse.js</h1>
<h2 id="project_tagline">Tests</h2> <h2 id="project_tagline">Tests</h2>
</header> </header>
</div> </div>

View File

@ -44,7 +44,7 @@
'preventDefault': function () {} 'preventDefault': function () {}
}; };
mock.mock_connection = function () { mock.mock_connection = function () { // eslint-disable-line wrap-iife
return function () { return function () {
Strophe.Bosh.prototype._processRequest = function () {}; // Don't attempt to send out stanzas Strophe.Bosh.prototype._processRequest = function () {}; // Don't attempt to send out stanzas
var c = new Strophe.Connection('jasmine tests'); var c = new Strophe.Connection('jasmine tests');
@ -76,25 +76,33 @@
}; };
}(); }();
function initConverse (settings) {
window.localStorage.clear();
window.sessionStorage.clear();
var converse = converse_api.initialize(_.extend({
i18n: window.locales.en,
auto_subscribe: false,
bosh_service_url: 'localhost',
connection: mock.mock_connection(),
animate: false,
no_trimming: true,
auto_login: true,
jid: 'dummy@localhost',
password: 'secret',
debug: false
}, settings || {}));
converse.ChatBoxViews.prototype.trimChat = function () {};
return converse;
}
mock.initConverseWithAsync = function (func, settings) {
return function (done) {
return func(done, initConverse(settings));
};
};
mock.initConverse = function (func, settings) { mock.initConverse = function (func, settings) {
return function () { return function () {
window.localStorage.clear(); initConverse(settings);
window.sessionStorage.clear(); return func(initConverse(settings));
var converse = converse_api.initialize(_.extend({
i18n: window.locales.en,
auto_subscribe: false,
bosh_service_url: 'localhost',
connection: mock.mock_connection(),
animate: false,
no_trimming: true,
auto_login: true,
jid: 'dummy@localhost',
password: 'secret',
debug: false
}, settings || {}));
converse.ChatBoxViews.prototype.trimChat = function () {};
return func(converse);
}; };
}; };
return mock; return mock;

97
tests/run-jasmine2.js Normal file
View File

@ -0,0 +1,97 @@
/*global document, require, setInterval, clearInterval, eval, phantom, console */
var system = require('system');
function waitFor(testFx, onReady, timeOutMillis) {
/**
* Wait until the test condition is true or a timeout occurs. Useful for waiting
* on a server response or for a ui change (fadeIn, etc.) to occur.
*
* @param testFx javascript condition that evaluates to a boolean,
* it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
* as a callback function.
* @param onReady what to do when testFx condition is fulfilled,
* it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
* as a callback function.
* @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used.
*/
"use strict";
var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 40001, //< Default Max Timeout is 10s
start = new Date().getTime(),
condition = false,
interval = setInterval(function() {
if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) {
// If not time-out yet and condition not yet fulfilled
condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); // eslint-disable-line no-eval
} else {
if(!condition) {
// If condition still not fulfilled (timeout but condition is 'false')
console.log("'waitFor()' timeout");
phantom.exit(1);
} else {
// Condition fulfilled (timeout and/or condition is 'true')
console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms.");
// Do what it's supposed to do once the condition is fulfilled
typeof(onReady) === "string" ? eval(onReady) : onReady(); // eslint-disable-line no-eval
clearInterval(interval); //< Stop this interval
}
}
}, 100); //< repeat check every 100ms
}
if (system.args.length !== 2) {
console.log('Usage: run-jasmine2.js URL');
phantom.exit(1);
}
var page = require('webpage').create();
page.onConsoleMessage = function(msg) {
// Route "console.log()" calls from within the Page context to the main
// Phantom context (i.e. current "this")
console.log(msg);
};
page.open(system.args[1], function(status){
"use strict";
if (status !== "success") {
console.log("Unable to access network");
phantom.exit();
} else {
waitFor(function(){
return page.evaluate(function(){
return (document.body.querySelector('.jasmine-symbol-summary .pending') === null &&
document.body.querySelector('.jasmine-duration') !== null);
});
}, function(){
var exitCode = page.evaluate(function(){
console.log('');
var title = 'Jasmine';
var version = document.body.querySelector('.jasmine-version').innerText;
var duration = document.body.querySelector('.jasmine-duration').innerText;
var banner = title + ' ' + version + ' ' + duration;
console.log(banner);
var list = document.body.querySelectorAll('.jasmine-results > .jasmine-failures > .jasmine-spec-detail.jasmine-failed');
if (list && list.length > 0) {
console.log('');
console.log(list.length + ' test(s) FAILED:');
for (var i = 0; i < list.length; ++i) {
var el = list[i],
desc = el.querySelector('.jasmine-description'),
msg = el.querySelector('.jasmine-messages > .jasmine-result-message');
console.log('');
console.log(desc.innerText);
console.log(msg.innerText);
console.log('');
}
return 1;
} else {
console.log(document.body.querySelector('.jasmine-alert > .jasmine-bar.jasmine-passed, .jasmine-alert > .jasmine-bar.skipped').innerText);
return 0;
}
});
phantom.exit(exitCode);
});
}
});

View File

@ -1,18 +1,31 @@
/*global config */
// Extra test dependencies // Extra test dependencies
config.paths.mock = "tests/mock"; config.paths.mock = "tests/mock";
config.paths.test_utils = "tests/utils"; config.paths['wait-until-promise'] = "node_modules/wait-until-promise/index";
config.paths['test-utils'] = "tests/utils";
config.paths.sinon = "node_modules/sinon/lib/sinon"; config.paths.sinon = "node_modules/sinon/lib/sinon";
config.paths.jasmine = "node_modules/jasmine-core/lib/jasmine-core/jasmine";
config.paths.transcripts = "converse-logs/converse-logs"; config.paths.transcripts = "converse-logs/converse-logs";
config.paths.jasmine = "node_modules/jasmine-core/lib/jasmine-core/jasmine";
config.paths.boot = "node_modules/jasmine-core/lib/jasmine-core/boot";
config.paths["jasmine-html"] = "node_modules/jasmine-core/lib/jasmine-core/jasmine-html"; config.paths["jasmine-html"] = "node_modules/jasmine-core/lib/jasmine-core/jasmine-html";
config.paths["console-runner"] = "node_modules/phantom-jasmine/lib/console-runner"; // config.paths["console-runner"] = "node_modules/phantom-jasmine/lib/console-runner";
config.shim.jasmine = {
exports: 'window.jasmineRequire'
};
config.shim['jasmine-html'] = { config.shim['jasmine-html'] = {
deps: ['jasmine'], deps: ['jasmine'],
exports: 'jasmine' exports: 'window.jasmineRequire'
}; };
config.shim.boot = {
deps: ['jasmine', 'jasmine-html'],
exports: 'window.jasmineRequire'
};
/*
config.shim['console-runner'] = { config.shim['console-runner'] = {
deps: ['jasmine'] deps: ['jasmine']
}; };
*/
require.config(config); require.config(config);
// Polyfill 'bind' which is not available in phantomjs < 2.0 // Polyfill 'bind' which is not available in phantomjs < 2.0
@ -35,13 +48,9 @@ if (!Function.prototype.bind) {
}; };
} }
require([ var specs = [
"jquery",
"mock",
"jasmine-html",
"sinon",
"console-runner",
//"spec/transcripts", //"spec/transcripts",
// "spec/profiling",
"spec/utils", "spec/utils",
"spec/converse", "spec/converse",
"spec/bookmarks", "spec/bookmarks",
@ -49,38 +58,31 @@ require([
"spec/disco", "spec/disco",
"spec/protocol", "spec/protocol",
"spec/presence", "spec/presence",
"spec/eventemitter",
"spec/ping",
"spec/xmppstatus",
"spec/mam", "spec/mam",
"spec/otr", "spec/otr",
"spec/eventemitter",
"spec/controlbox", "spec/controlbox",
"spec/chatbox", "spec/chatbox",
"spec/chatroom", "spec/chatroom",
"spec/minchats", "spec/minchats",
"spec/notification", "spec/notification",
"spec/profiling", "spec/register"
"spec/ping", ];
"spec/register",
"spec/xmppstatus" require(['jquery', 'mock', 'boot', 'sinon', 'wait-until-promise'],
], function($, mock, jasmine, sinon) { function($, mock, jasmine, sinon, waitUntilPromise) {
window.sinon = sinon; window.sinon = sinon;
window.localStorage.clear(); window.waitUntilPromise = waitUntilPromise['default'];
window.sessionStorage.clear(); window.localStorage.clear();
// Jasmine stuff window.sessionStorage.clear();
var jasmineEnv = jasmine.getEnv();
var reporter; // Load the specs
if (/PhantomJS/.test(navigator.userAgent)) { require(specs, function () {
reporter = new jasmine.ConsoleReporter(); // Initialize the HTML Reporter and execute the environment (setup by `boot.js`)
window.console_reporter = reporter; // http://stackoverflow.com/questions/19240302/does-jasmine-2-0-really-not-work-with-require-js
jasmineEnv.addReporter(reporter); window.onload();
jasmineEnv.updateInterval = 0; });
} else {
reporter = new jasmine.HtmlReporter();
jasmineEnv.addReporter(reporter);
jasmineEnv.specFilter = function(spec) {
return reporter.specFilter(spec);
};
jasmineEnv.updateInterval = 0;
}
jasmineEnv.execute();
} }
); );

View File

@ -1,12 +1,18 @@
(function (root, factory) { (function (root, factory) {
define("test_utils", ['converse', 'mock'], factory); define(['converse', 'es6-promise', 'mock', 'wait-until-promise'], factory);
}(this, function (converse_api, mock) { }(this, function (converse_api, Promise, mock, waitUntilPromise) {
var _ = converse_api.env._;
var $ = converse_api.env.jQuery; var $ = converse_api.env.jQuery;
var $pres = converse_api.env.$pres; var $pres = converse_api.env.$pres;
var $iq = converse_api.env.$iq; var $iq = converse_api.env.$iq;
var Strophe = converse_api.env.Strophe; var Strophe = converse_api.env.Strophe;
var utils = {}; var utils = {};
if (typeof window.Promise === 'undefined') {
waitUntilPromise.setPromiseImplementation(Promise);
}
utils.waitUntil = waitUntilPromise['default'];
utils.createRequest = function (iq) { utils.createRequest = function (iq) {
iq = typeof iq.tree == "function" ? iq.tree() : iq; iq = typeof iq.tree == "function" ? iq.tree() : iq;
var req = new Strophe.Request(iq, function() {}); var req = new Strophe.Request(iq, function() {});
@ -27,28 +33,6 @@
return this; return this;
}; };
utils.removeAllChatBoxes = function () {
var i, chatbox, num_chatboxes = converse.chatboxes.models.length;
for (i=num_chatboxes-1; i>-1; i--) {
chatbox = converse.chatboxes.models[i];
converse.chatboxviews.get(chatbox.get('id')).close();
converse.chatboxviews.get(chatbox.get('id')).$el.remove();
}
converse.chatboxviews.get('controlbox').close();
converse.chatboxviews.get('controlbox').$el.remove();
return this;
};
utils.initConverse = function () {
converse._tearDown();
converse._initialize();
};
utils.initRoster = function () {
converse.roster.browserStorage._clear();
converse.initRoster();
};
utils.openControlBox = function () { utils.openControlBox = function () {
var $toggle = $(".toggle-controlbox"); var $toggle = $(".toggle-controlbox");
if (!$("#controlbox").is(':visible')) { if (!$("#controlbox").is(':visible')) {
@ -69,11 +53,6 @@
return this; return this;
}; };
utils.removeControlBox = function () {
converse.controlboxtoggle.show();
$('#controlbox').remove();
};
utils.openContactsPanel = function (converse) { utils.openContactsPanel = function (converse) {
this.openControlBox(converse); this.openControlBox(converse);
var cbview = converse.chatboxviews.get('controlbox'); var cbview = converse.chatboxviews.get('controlbox');
@ -157,14 +136,6 @@
converse.connection.sendIQ.restore(); converse.connection.sendIQ.restore();
}; };
utils.removeRosterContacts = function () {
var model;
while (converse.rosterview.model.length) {
model = converse.rosterview.model.pop();
converse.rosterview.model.remove(model);
}
};
utils.clearBrowserStorage = function () { utils.clearBrowserStorage = function () {
window.localStorage.clear(); window.localStorage.clear();
window.sessionStorage.clear(); window.sessionStorage.clear();
@ -184,7 +155,7 @@
* *
* These contacts are not grouped. See below. * These contacts are not grouped. See below.
*/ */
var names, jid; var names, jid, subscription, requesting, ask;
if (type === 'requesting') { if (type === 'requesting') {
names = mock.req_names; names = mock.req_names;
subscription = 'none'; subscription = 'none';
@ -206,13 +177,13 @@
.createContacts(converse, 'pending'); .createContacts(converse, 'pending');
return this; return this;
} else { } else {
throw "Need to specify the type of contact to create"; throw Error("Need to specify the type of contact to create");
} }
if (typeof length === 'undefined') { if (typeof length === 'undefined') {
length = names.length; length = names.length;
} }
for (i=0; i<length; i++) { for (var i=0; i<length; i++) {
jid = names[i].replace(/ /g,'.').toLowerCase() + '@localhost'; jid = names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
if (!converse.roster.get(jid)) { if (!converse.roster.get(jid)) {
converse.roster.create({ converse.roster.create({