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",
"never"
],
"valid-jsdoc": "error",
"valid-jsdoc": "off",
"vars-on-top": "off",
"wrap-iife": [
"error",

View File

@ -3,7 +3,6 @@ BUILDDIR = ./docs
BUNDLE ?= ./.bundle/bin/bundle
GRUNT ?= ./node_modules/.bin/grunt
HTTPSERVE ?= ./node_modules/.bin/http-server
JSHINT ?= ./node_modules/.bin/jshint
ESLINT ?= ./node_modules/.bin/eslint
PAPER =
PHANTOMJS ?= ./node_modules/.bin/phantomjs
@ -16,13 +15,6 @@ SPHINXOPTS =
# Internal variables.
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
all: dev dist
@ -184,18 +176,15 @@ build:: dev css
########################################################################
## Tests
.PHONY: jshint
jshint: stamp-npm
$(JSHINT) --config jshintrc $(CHECKSOURCES)
.PHONY: eslint
eslint: stamp-npm
$(ESLINT) src/
$(ESLINT) spec/
.PHONY: check
check: jshint eslint
$(PHANTOMJS) node_modules/phantom-jasmine/lib/run_jasmine_test.coffee tests.html
check: eslint
$(PHANTOMJS) tests/run-jasmine2.js tests.html
########################################################################
## Documentation

View File

@ -2,7 +2,7 @@
## 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)

View File

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

View File

@ -1,10 +1,12 @@
/*global waitUntilPromise */
(function (root, factory) {
define([
"jquery",
"converse-core",
"utils",
"mock",
"test_utils"
"test-utils"
], factory);
} (this, function ($, converse, utils, mock, test_utils) {
"use strict";
@ -17,17 +19,17 @@
it("can be bookmarked", mock.initConverse(function (_converse) {
var sent_stanza, IQ_id;
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;
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');
var jid = 'theplay@conference.shakespeare.lit';
var view = _converse.chatboxviews.get(jid);
spyOn(view, 'renderBookmarkForm').andCallThrough();
spyOn(view, 'cancelConfiguration').andCallThrough();
spyOn(view, 'renderBookmarkForm').and.callThrough();
spyOn(view, 'cancelConfiguration').and.callThrough();
var $bookmark = view.$el.find('.icon-pushpin');
$bookmark.click();
@ -146,85 +148,73 @@
describe("when bookmarked", function () {
it("displays that it's bookmarked through its bookmark icon", mock.initConverse(function (_converse) {
runs(function () {
test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy');
});
waits(100);
runs(function () {
var view = _converse.chatboxviews.get('lounge@localhost');
var $bookmark_icon = view.$('.icon-pushpin');
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();
});
test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy');
var view = _converse.chatboxviews.get('lounge@localhost');
var $bookmark_icon = view.$('.icon-pushpin');
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) {
var view, sent_stanza, IQ_id;
var sent_stanza, IQ_id;
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;
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 () {
test_utils.openChatRoom(_converse, 'theplay', 'conference.shakespeare.lit', 'JC');
});
waits(100);
runs(function () {
var jid = 'theplay@conference.shakespeare.lit';
view = _converse.chatboxviews.get(jid);
spyOn(view, 'toggleBookmark').andCallThrough();
spyOn(_converse.bookmarks, 'sendBookmarkStanza').andCallThrough();
view.delegateEvents();
_converse.bookmarks.create({
'jid': view.model.get('jid'),
'autojoin': false,
'name': 'The Play',
'nick': ' Othello'
});
expect(_converse.bookmarks.length).toBe(1);
});
waits(100);
runs(function () {
expect(view.model.get('bookmarked')).toBeTruthy();
var $bookmark_icon = view.$('.icon-pushpin');
expect($bookmark_icon.hasClass('button-on')).toBeTruthy();
$bookmark_icon.click();
expect(view.toggleBookmark).toHaveBeenCalled();
expect($bookmark_icon.hasClass('button-on')).toBeFalsy();
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>"
);
});
// 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 () {
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
/* The stored data is automatically pushed to all of the user's
* connected resources.
@ -305,7 +295,7 @@
it("can be retrieved from the XMPP server", mock.initConverse(function (_converse) {
var sent_stanza, IQ_id,
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;
IQ_id = sendIQ.bind(this)(iq, callback, errback);
});
@ -376,7 +366,7 @@
it("shows a list of bookmarks", mock.initConverse(function (_converse) {
var IQ_id;
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);
});
_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) {
runs(function () {
_converse.bookmarks.create({
'jid': 'theplay@conference.shakespeare.lit',
'autojoin': false,
'name': 'The Play',
'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.bookmarks.create({
'jid': 'theplay@conference.shakespeare.lit',
'autojoin': false,
'name': 'The Play',
'nick': ''
});
_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([
"converse-core",
"mock",
"test_utils"], factory);
"test-utils"], factory);
} (this, function (converse, mock, test_utils) {
var b64_sha1 = converse.env.b64_sha1;
var _ = converse.env._;
@ -52,9 +52,9 @@
describe("A chat state indication", function () {
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;
spyOn(_converse.connection, 'send').andCallFake(function (stanza) {
spyOn(_converse.connection, 'send').and.callFake(function (stanza) {
sent_stanza = stanza;
});
var i = 0;
@ -298,26 +298,23 @@
test_utils.createContacts(_converse, 'current');
var jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
var chatboxview;
waits('300'); // ChatBox.show() is debounced for 250ms
runs(function () {
// Test on chat that doesn't exist.
expect(_converse.api.chats.get('non-existing@jabber.org')).toBeFalsy();
var box = _converse.api.chats.open(jid);
expect(box instanceof Object).toBeTruthy();
expect(box.model.get('box_id')).toBe(b64_sha1(jid));
expect(
_.keys(box),
['close', 'endOTR', 'focus', 'get', 'initiateOTR', 'is_chatroom', 'maximize', 'minimize', 'open', 'set']
);
chatboxview = _converse.chatboxviews.get(jid);
expect(chatboxview.$el.is(':visible')).toBeTruthy();
// Test for multiple JIDs
var jid2 = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
var list = _converse.api.chats.open([jid, jid2]);
expect(_.isArray(list)).toBeTruthy();
expect(list[0].model.get('box_id')).toBe(b64_sha1(jid));
expect(list[1].model.get('box_id')).toBe(b64_sha1(jid2));
});
// Test on chat that doesn't exist.
expect(_converse.api.chats.get('non-existing@jabber.org')).toBeFalsy();
var box = _converse.api.chats.open(jid);
expect(box instanceof Object).toBeTruthy();
expect(box.model.get('box_id')).toBe(b64_sha1(jid));
expect(
_.keys(box),
['close', 'endOTR', 'focus', 'get', 'initiateOTR', 'is_chatroom', 'maximize', 'minimize', 'open', 'set']
);
chatboxview = _converse.chatboxviews.get(jid);
expect(chatboxview.$el.is(':visible')).toBeTruthy();
// Test for multiple JIDs
var jid2 = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
var list = _converse.api.chats.open([jid, jid2]);
expect(_.isArray(list)).toBeTruthy();
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",
"converse-core",
"mock",
"test_utils"], factory);
"test-utils"], factory);
} (this, function ($, converse, mock, test_utils) {
"use strict";
var Strophe = converse.env.Strophe;
@ -11,10 +11,10 @@
describe("Service Discovery", function () {
describe("Whenever converse.js discovers a new server feature", function () {
it("emits the serviceDiscovered event", mock.initConverse(function (_converse) {
spyOn(_converse, 'emit');
sinon.spy(_converse, 'emit');
_converse.features.create({'var': Strophe.NS.MAM});
expect(_converse.emit).toHaveBeenCalled();
expect(_converse.emit.argsForCall[0][1].get('var')).toBe(Strophe.NS.MAM);
expect(_converse.emit.called).toBe(true);
expect(_converse.emit.args[0][1].get('var')).toBe(Strophe.NS.MAM);
}));
});
});

View File

@ -1,5 +1,5 @@
(function (root, factory) {
define(["mock", "converse-core", "test_utils"], factory);
define(["mock", "converse-core", "test-utils"], factory);
} (this, function (mock, converse, test_utils) {
return describe("The _converse Event Emitter", function() {
@ -11,9 +11,9 @@
_converse.emit('connected');
expect(this.callback).toHaveBeenCalled();
_converse.emit('connected');
expect(this.callback.callCount, 2);
expect(this.callback.calls.count(), 2);
_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) {
@ -23,9 +23,9 @@
_converse.emit('connected');
expect(this.callback).toHaveBeenCalled();
_converse.emit('connected');
expect(this.callback.callCount, 1);
expect(this.callback.calls.count(), 1);
_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) {
@ -46,15 +46,15 @@
_converse.off('connected', this.callback);
_converse.emit('connected');
expect(this.callback.callCount, 1);
expect(this.anotherCallback.callCount, 2);
expect(this.callback.calls.count(), 1);
expect(this.anotherCallback.calls.count(), 2);
_converse.once('connected', this.neverCalled);
_converse.off('connected', this.neverCalled);
_converse.emit('connected');
expect(this.callback.callCount, 1);
expect(this.anotherCallback.callCount, 3);
expect(this.callback.calls.count(), 1);
expect(this.anotherCallback.calls.count(), 3);
expect(this.neverCalled).not.toHaveBeenCalled();
}));
});

View File

@ -4,7 +4,7 @@
"converse-core",
"utils",
"mock",
"test_utils"
"test-utils"
], factory);
} (this, function ($, converse, utils, mock, test_utils) {
"use strict";
@ -25,23 +25,18 @@
* </message
*/
sinon.spy(utils, 'isHeadlineMessage');
runs(function () {
var stanza = $msg({
'xmlns': 'jabber:client',
'to': 'dummy@localhost',
'type': 'chat',
'from': 'gapowa20102106@rds-rostov.ru/Adium',
})
.c('nick', {'xmlns': "http://jabber.org/protocol/nick"}).t("-wwdmz").up()
.c('body').t('SORRY FOR THIS ADVERT');
_converse.connection._dataRecv(test_utils.createRequest(stanza));
});
waits(250);
runs(function () {
expect(utils.isHeadlineMessage.called).toBeTruthy();
expect(utils.isHeadlineMessage.returned(false)).toBeTruthy();
utils.isHeadlineMessage.restore();
});
var stanza = $msg({
'xmlns': 'jabber:client',
'to': 'dummy@localhost',
'type': 'chat',
'from': 'gapowa20102106@rds-rostov.ru/Adium',
})
.c('nick', {'xmlns': "http://jabber.org/protocol/nick"}).t("-wwdmz").up()
.c('body').t('SORRY FOR THIS ADVERT');
_converse.connection._dataRecv(test_utils.createRequest(stanza));
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) {
@ -59,53 +54,43 @@
* </message>
*/
sinon.spy(utils, 'isHeadlineMessage');
runs(function () {
var stanza = $msg({
'type': 'headline',
'from': 'notify.example.com',
'to': 'dummy@localhost',
'xml:lang': 'en'
})
.c('subject').t('SIEVE').up()
.c('body').t('&lt;juliet@example.com&gt; You got mail.').up()
.c('x', {'xmlns': 'jabber:x:oob'})
.c('url').t('imap://romeo@example.com/INBOX;UIDVALIDITY=385759043/;UID=18');
_converse.connection._dataRecv(test_utils.createRequest(stanza));
});
waits(250);
runs(function () {
expect(
_.includes(
_converse.chatboxviews.keys(),
'notify.example.com')
).toBeTruthy();
expect(utils.isHeadlineMessage.called).toBeTruthy();
expect(utils.isHeadlineMessage.returned(true)).toBeTruthy();
utils.isHeadlineMessage.restore(); // unwraps
});
var stanza = $msg({
'type': 'headline',
'from': 'notify.example.com',
'to': 'dummy@localhost',
'xml:lang': 'en'
})
.c('subject').t('SIEVE').up()
.c('body').t('&lt;juliet@example.com&gt; You got mail.').up()
.c('x', {'xmlns': 'jabber:x:oob'})
.c('url').t('imap://romeo@example.com/INBOX;UIDVALIDITY=385759043/;UID=18');
_converse.connection._dataRecv(test_utils.createRequest(stanza));
expect(
_.includes(
_converse.chatboxviews.keys(),
'notify.example.com')
).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) {
_converse.allow_non_roster_messaging = false;
sinon.spy(utils, 'isHeadlineMessage');
runs(function () {
var stanza = $msg({
'type': 'headline',
'from': 'andre5114@jabber.snc.ru/Spark',
'to': 'dummy@localhost',
'xml:lang': 'en'
})
.c('nick').t('gpocy').up()
.c('body').t('Здравствуйте друзья');
_converse.connection._dataRecv(test_utils.createRequest(stanza));
});
waits(250);
runs(function () {
expect(_.without('controlbox', _converse.chatboxviews.keys()).length).toBe(0);
expect(utils.isHeadlineMessage.called).toBeTruthy();
expect(utils.isHeadlineMessage.returned(true)).toBeTruthy();
utils.isHeadlineMessage.restore(); // unwraps
});
var stanza = $msg({
'type': 'headline',
'from': 'andre5114@jabber.snc.ru/Spark',
'to': 'dummy@localhost',
'xml:lang': 'en'
})
.c('nick').t('gpocy').up()
.c('body').t('Здравствуйте друзья');
_converse.connection._dataRecv(test_utils.createRequest(stanza));
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) {
define(["mock", "converse-core", "test_utils"], factory);
define(["mock", "converse-core", "test-utils"], factory);
} (this, function (mock, converse, test_utils) {
"use strict";
var _ = converse.env._;
@ -18,7 +18,7 @@
it("can be used to query for all archived messages", mock.initConverse(function (_converse) {
var sent_stanza, IQ_id;
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;
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) {
var sent_stanza, IQ_id;
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;
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) {
var sent_stanza, IQ_id;
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;
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) {
var sent_stanza, IQ_id;
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;
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) {
var sent_stanza, IQ_id;
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;
IQ_id = sendIQ.bind(this)(iq, callback, errback);
});
@ -169,7 +169,7 @@
it("can be used to page through results", mock.initConverse(function (_converse) {
var sent_stanza, IQ_id;
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;
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) {
var sent_stanza, IQ_id;
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;
IQ_id = sendIQ.bind(this)(iq, callback, errback);
});
@ -242,7 +242,7 @@
}
var sent_stanza, IQ_id;
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;
IQ_id = sendIQ.bind(this)(iq, callback, errback);
});
@ -280,7 +280,7 @@
}
var sent_stanza, IQ_id;
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;
IQ_id = sendIQ.bind(this)(iq, callback, errback);
});
@ -352,7 +352,7 @@
_converse.connection._dataRecv(test_utils.createRequest(stanza));
expect(callback).toHaveBeenCalled();
var args = callback.argsForCall[0];
var args = callback.calls.argsFor(0);
expect(args[0].length).toBe(2);
expect(args[0][0].outerHTML).toBe(msg1.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) {
var sent_stanza, IQ_id;
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;
IQ_id = sendIQ.bind(this)(iq, callback, errback);
});
spyOn(_converse, 'onMAMPreferences').andCallThrough();
spyOn(_converse, 'onMAMPreferences').and.callThrough();
_converse.message_archiving = 'never';
var feature = new _converse.Feature({
'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);
expect(_converse.connection.sendIQ).toHaveBeenCalled();
@ -407,7 +407,7 @@
expect(_converse.onMAMPreferences).toHaveBeenCalled();
expect(_converse.connection.sendIQ.callCount).toBe(2);
expect(_converse.connection.sendIQ.calls.count()).toBe(2);
expect(sent_stanza.toString()).toBe(
"<iq type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
"<prefs xmlns='urn:xmpp:mam:0' default='never'>"+

View File

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

View File

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

View File

@ -1,5 +1,5 @@
(function (root, factory) {
define(["mock", "converse-core", "test_utils"], factory);
define(["mock", "converse-core", "test-utils"], factory);
} (this, function (mock, converse, test_utils) {
var $ = converse.env.jQuery;
var Strophe = converse.env.Strophe;
@ -41,7 +41,7 @@
spyOn(_converse.connection, 'send');
chatbox.set('otr_status', 1); // Set OTR status to UNVERIFIED, to mock an encrypted session
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('private').length).toBe(1);
expect($sent.find('private').attr('xmlns')).toBe('urn:xmpp:carbons:2');

View File

@ -1,5 +1,5 @@
(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) {
"use strict";
@ -7,16 +7,16 @@
describe("Ping and pong handlers", function () {
it("are registered when _converse.js is connected", mock.initConverse(function (_converse) {
spyOn(_converse, 'registerPingHandler').andCallThrough();
spyOn(_converse, 'registerPongHandler').andCallThrough();
spyOn(_converse, 'registerPingHandler').and.callThrough();
spyOn(_converse, 'registerPongHandler').and.callThrough();
_converse.emit('connected');
expect(_converse.registerPingHandler).toHaveBeenCalled();
expect(_converse.registerPongHandler).toHaveBeenCalled();
}));
it("are registered when _converse.js reconnected", mock.initConverse(function (_converse) {
spyOn(_converse, 'registerPingHandler').andCallThrough();
spyOn(_converse, 'registerPongHandler').andCallThrough();
spyOn(_converse, 'registerPingHandler').and.callThrough();
spyOn(_converse, 'registerPongHandler').and.callThrough();
_converse.emit('reconnected');
expect(_converse.registerPingHandler).toHaveBeenCalled();
expect(_converse.registerPongHandler).toHaveBeenCalled();
@ -28,7 +28,7 @@
it("is sent out when _converse.js pings a server", mock.initConverse(function (_converse) {
var sent_stanza, IQ_id;
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;
IQ_id = sendIQ.bind(this)(iq, callback, errback);
});

View File

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

View File

@ -3,7 +3,7 @@
"jquery",
"converse-core",
"mock",
"test_utils"], factory);
"test-utils"], factory);
} (this, function ($, converse, mock, test_utils) {
"use strict";
var Strophe = converse.env.Strophe;
@ -46,175 +46,171 @@
* that session. A client MUST acknowledge each roster push with an IQ
* 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 interaction between roster items and subscription states.
*/
_converse.roster_groups = false;
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);
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
panel.delegateEvents(); // Rebind all events so that our spy gets called
/* Add a new contact through the UI */
var $form = panel.$('form.add-xmpp-contact');
expect($form.is(":visible")).toBeFalsy();
// Click the "Add a contact" link.
panel.$('.toggle-xmpp-contact-form').click();
// Check that the $form appears
expect($form.is(":visible")).toBeTruthy();
// Fill in the form and submit
$form.find('input').val('contact@example.org');
$form.submit();
/* Add a new contact through the UI */
var $form = panel.$('form.add-xmpp-contact');
expect($form.is(":visible")).toBeFalsy();
// Click the "Add a contact" link.
panel.$('.toggle-xmpp-contact-form').click();
// Check that the $form appears
expect($form.is(":visible")).toBeTruthy();
// Fill in the form and submit
$form.find('input').val('contact@example.org');
$form.submit();
/* In preparation for being able to render the contact in the
* user's client interface and for the server to keep track of the
* subscription, the user's client SHOULD perform a "roster set"
* for the new roster item.
*/
expect(panel.addContactFromForm).toHaveBeenCalled();
expect(_converse.roster.addAndSubscribe).toHaveBeenCalled();
expect(_converse.roster.addContact).toHaveBeenCalled();
// The form should not be visible anymore.
expect($form.is(":visible")).toBeFalsy();
/* In preparation for being able to render the contact in the
* user's client interface and for the server to keep track of the
* subscription, the user's client SHOULD perform a "roster set"
* for the new roster item.
*/
expect(panel.addContactFromForm).toHaveBeenCalled();
expect(_converse.roster.addAndSubscribe).toHaveBeenCalled();
expect(_converse.roster.addContact).toHaveBeenCalled();
// The form should not be visible anymore.
expect($form.is(":visible")).toBeFalsy();
/* _converse request consists of sending an IQ
* stanza of type='set' containing a <query/> element qualified by
* the 'jabber:iq:roster' namespace, which in turn contains an
* <item/> element that defines the new roster item; the <item/>
* element MUST possess a 'jid' attribute, MAY possess a 'name'
* attribute, MUST NOT possess a 'subscription' attribute, and MAY
* contain one or more <group/> child elements:
*
* <iq type='set' id='set1'>
* <query xmlns='jabber:iq:roster'>
* <item
* jid='contact@example.org'
* name='MyContact'>
* <group>MyBuddies</group>
* </item>
* </query>
* </iq>
*/
expect(_converse.roster.sendContactAddIQ).toHaveBeenCalled();
expect(sent_stanza.toLocaleString()).toBe(
"<iq type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
"<query xmlns='jabber:iq:roster'>"+
"<item jid='contact@example.org' name='contact@example.org'/>"+
"</query>"+
"</iq>"
);
/* As a result, the user's server (1) MUST initiate a roster push
* for the new roster item to all available resources associated
* with _converse user that have requested the roster, setting the
* 'subscription' attribute to a value of "none"; and (2) MUST
* reply to the sending resource with an IQ result indicating the
* success of the roster set:
*
* <iq type='set'>
* <query xmlns='jabber:iq:roster'>
* <item
* jid='contact@example.org'
* subscription='none'
* name='MyContact'>
* <group>MyBuddies</group>
* </item>
* </query>
* </iq>
*/
var create = _converse.roster.create;
spyOn(_converse.connection, 'send').andCallFake(function (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();
/* _converse request consists of sending an IQ
* stanza of type='set' containing a <query/> element qualified by
* the 'jabber:iq:roster' namespace, which in turn contains an
* <item/> element that defines the new roster item; the <item/>
* element MUST possess a 'jid' attribute, MAY possess a 'name'
* attribute, MUST NOT possess a 'subscription' attribute, and MAY
* contain one or more <group/> child elements:
*
* <iq type='set' id='set1'>
* <query xmlns='jabber:iq:roster'>
* <item
* jid='contact@example.org'
* name='MyContact'>
* <group>MyBuddies</group>
* </item>
* </query>
* </iq>
*/
expect(_converse.roster.sendContactAddIQ).toHaveBeenCalled();
expect(sent_stanza.toLocaleString()).toBe(
"<iq type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
"<query xmlns='jabber:iq:roster'>"+
"<item jid='contact@example.org' name='contact@example.org'/>"+
"</query>"+
"</iq>"
);
/* As a result, the user's server (1) MUST initiate a roster push
* for the new roster item to all available resources associated
* with _converse user that have requested the roster, setting the
* 'subscription' attribute to a value of "none"; and (2) MUST
* reply to the sending resource with an IQ result indicating the
* success of the roster set:
*
* <iq type='set'>
* <query xmlns='jabber:iq:roster'>
* <item
* jid='contact@example.org'
* subscription='none'
* name='MyContact'>
* <group>MyBuddies</group>
* </item>
* </query>
* </iq>
*/
var create = _converse.roster.create;
spyOn(_converse.connection, 'send').and.callFake(function (stanza) {
sent_stanza = stanza;
});
waits(50);
runs(function () {
// Check that the user is now properly shown as a pending
// contact in the roster.
spyOn(_converse.roster, 'create').and.callFake(function () {
contact = create.apply(_converse.roster, arguments);
spyOn(contact, 'subscribe').and.callThrough();
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")');
expect($header.length).toBe(1);
expect($header.is(":visible")).toBeTruthy();
var $contacts = $header.parent().nextUntil('dt', 'dd');
expect($contacts.length).toBe(1);
spyOn(contact, "ackSubscribe").andCallThrough();
spyOn(contact, "ackSubscribe").and.callThrough();
/* Here we assume the "happy path" that the contact
* approves the subscription request
*
@ -301,8 +297,8 @@
*
* <presence from='contact@example.org' to='user@example.com' type='subscribe'/>
*/
spyOn(contact, 'authorize').andCallThrough();
spyOn(_converse.roster, 'handleIncomingSubscription').andCallThrough();
spyOn(contact, 'authorize').and.callThrough();
spyOn(_converse.roster, 'handleIncomingSubscription').and.callThrough();
stanza = $pres({
'to': _converse.bare_jid,
'from': 'contact@example.org/resource',
@ -348,6 +344,7 @@
// The class on the contact will now have switched.
expect($contacts.hasClass('to')).toBeFalsy();
expect($contacts.hasClass('both')).toBeTruthy();
done();
});
}));
@ -356,110 +353,101 @@
* the interaction between roster items and subscription states.
*/
var contact, stanza, sent_stanza, sent_IQ;
runs(function () {
test_utils.openControlBox(_converse);
});
waits(100);
runs(function () {
// Add a new roster contact via roster push
stanza = $iq({'type': 'set'}).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));
});
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();
test_utils.openControlBox(_converse);
// Add a new roster contact via roster push
stanza = $iq({'type': 'set'}).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));
// 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").and.callThrough();
spyOn(_converse.connection, 'send').andCallFake(function (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, 'send').and.callFake(function (stanza) {
sent_stanza = stanza;
});
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';
_converse.roster_groups = false;
runs(function () {
test_utils.openControlBox(_converse);
test_utils.createContacts(_converse, 'current');
test_utils.openControlBox(_converse);
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")');
// remove the first user
$($header.parent().nextUntil('dt', 'dd').find('.remove-xmpp-contact').get(0)).click();
@ -497,31 +485,31 @@
_converse.connection._dataRecv(test_utils.createRequest(stanza));
// Our contact has now been removed
expect(typeof _converse.roster.get(jid) === "undefined").toBeTruthy();
done();
});
}));
it("Receiving a subscription request", mock.initConverse(function (_converse) {
runs(function () {
test_utils.openControlBox(_converse);
test_utils.createContacts(_converse, 'current'); // Create some contacts so that we can test positioning
});
waits(50);
runs(function () {
spyOn(_converse, "emit");
/* <presence
* from='user@example.com'
* to='contact@example.org'
* type='subscribe'/>
*/
var stanza = $pres({
'to': _converse.bare_jid,
'from': 'contact@example.org',
'type': 'subscribe'
}).c('nick', {
'xmlns': Strophe.NS.NICK,
}).t('Clint Contact');
_converse.connection._dataRecv(test_utils.createRequest(stanza));
expect(_converse.emit).toHaveBeenCalledWith('contactRequest', jasmine.any(Object));
test_utils.openControlBox(_converse);
test_utils.createContacts(_converse, 'current'); // Create some contacts so that we can test positioning
spyOn(_converse, "emit");
/* <presence
* from='user@example.com'
* to='contact@example.org'
* type='subscribe'/>
*/
var stanza = $pres({
'to': _converse.bare_jid,
'from': 'contact@example.org',
'type': 'subscribe'
}).c('nick', {
'xmlns': Strophe.NS.NICK,
}).t('Clint Contact');
_converse.connection._dataRecv(test_utils.createRequest(stanza));
expect(_converse.emit).toHaveBeenCalledWith('contactRequest', jasmine.any(Object));
test_utils.waitUntil(function () {
return $('a:contains("Contact requests")').length;
}).then(function () {
var $header = $('a:contains("Contact requests")');
expect($header.length).toBe(1);
expect($header.is(":visible")).toBeTruthy();

View File

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

View File

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

View File

@ -1,5 +1,5 @@
(function (root, factory) {
define(["mock", "converse-core", "test_utils"], factory);
define(["mock", "converse-core", "test-utils"], factory);
} (this, function (mock, converse, test_utils) {
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) {
_converse.xmppstatus.save({'status': 'online'});
spyOn(_converse.xmppstatus, 'setStatusMessage').andCallThrough();
spyOn(_converse.xmppstatus, 'setStatusMessage').and.callThrough();
spyOn(_converse.connection, 'send');
_converse.xmppstatus.setStatusMessage("I'm also happy!");
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('status').length).toBe(1);
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.overview": "node_modules/backbone.overview/backbone.overview",
"eventemitter": "node_modules/otr/build/dep/eventemitter",
"es6-promise": "node_modules/es6-promise/dist/es6-promise",
"jquery": "node_modules/jquery/dist/jquery",
"jquery-private": "src/jquery-private",
"jquery.browser": "node_modules/jquery.browser/dist/jquery.browser",

View File

@ -4,12 +4,16 @@
<head>
<title>Converse.js Tests</title>
<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 type="text/css" rel="stylesheet" media="screen" href="css/theme.css" />
<link type="text/css" rel="stylesheet" media="screen" href="css/converse.css" />
<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>
.tests-brand-heading {
margin-top: 1em;
@ -21,7 +25,8 @@
<body>
<div id="header_wrap" class="outer">
<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>
</header>
</div>

View File

@ -44,7 +44,7 @@
'preventDefault': function () {}
};
mock.mock_connection = function () {
mock.mock_connection = function () { // eslint-disable-line wrap-iife
return function () {
Strophe.Bosh.prototype._processRequest = function () {}; // Don't attempt to send out stanzas
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) {
return function () {
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 func(converse);
initConverse(settings);
return func(initConverse(settings));
};
};
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
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.jasmine = "node_modules/jasmine-core/lib/jasmine-core/jasmine";
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["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'] = {
deps: ['jasmine'],
exports: 'jasmine'
exports: 'window.jasmineRequire'
};
config.shim.boot = {
deps: ['jasmine', 'jasmine-html'],
exports: 'window.jasmineRequire'
};
/*
config.shim['console-runner'] = {
deps: ['jasmine']
};
*/
require.config(config);
// Polyfill 'bind' which is not available in phantomjs < 2.0
@ -35,13 +48,9 @@ if (!Function.prototype.bind) {
};
}
require([
"jquery",
"mock",
"jasmine-html",
"sinon",
"console-runner",
var specs = [
//"spec/transcripts",
// "spec/profiling",
"spec/utils",
"spec/converse",
"spec/bookmarks",
@ -49,38 +58,31 @@ require([
"spec/disco",
"spec/protocol",
"spec/presence",
"spec/eventemitter",
"spec/ping",
"spec/xmppstatus",
"spec/mam",
"spec/otr",
"spec/eventemitter",
"spec/controlbox",
"spec/chatbox",
"spec/chatroom",
"spec/minchats",
"spec/notification",
"spec/profiling",
"spec/ping",
"spec/register",
"spec/xmppstatus"
], function($, mock, jasmine, sinon) {
window.sinon = sinon;
window.localStorage.clear();
window.sessionStorage.clear();
// Jasmine stuff
var jasmineEnv = jasmine.getEnv();
var reporter;
if (/PhantomJS/.test(navigator.userAgent)) {
reporter = new jasmine.ConsoleReporter();
window.console_reporter = reporter;
jasmineEnv.addReporter(reporter);
jasmineEnv.updateInterval = 0;
} else {
reporter = new jasmine.HtmlReporter();
jasmineEnv.addReporter(reporter);
jasmineEnv.specFilter = function(spec) {
return reporter.specFilter(spec);
};
jasmineEnv.updateInterval = 0;
}
jasmineEnv.execute();
"spec/register"
];
require(['jquery', 'mock', 'boot', 'sinon', 'wait-until-promise'],
function($, mock, jasmine, sinon, waitUntilPromise) {
window.sinon = sinon;
window.waitUntilPromise = waitUntilPromise['default'];
window.localStorage.clear();
window.sessionStorage.clear();
// Load the specs
require(specs, function () {
// Initialize the HTML Reporter and execute the environment (setup by `boot.js`)
// http://stackoverflow.com/questions/19240302/does-jasmine-2-0-really-not-work-with-require-js
window.onload();
});
}
);

View File

@ -1,12 +1,18 @@
(function (root, factory) {
define("test_utils", ['converse', 'mock'], factory);
}(this, function (converse_api, mock) {
define(['converse', 'es6-promise', 'mock', 'wait-until-promise'], factory);
}(this, function (converse_api, Promise, mock, waitUntilPromise) {
var _ = converse_api.env._;
var $ = converse_api.env.jQuery;
var $pres = converse_api.env.$pres;
var $iq = converse_api.env.$iq;
var Strophe = converse_api.env.Strophe;
var utils = {};
if (typeof window.Promise === 'undefined') {
waitUntilPromise.setPromiseImplementation(Promise);
}
utils.waitUntil = waitUntilPromise['default'];
utils.createRequest = function (iq) {
iq = typeof iq.tree == "function" ? iq.tree() : iq;
var req = new Strophe.Request(iq, function() {});
@ -27,28 +33,6 @@
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 () {
var $toggle = $(".toggle-controlbox");
if (!$("#controlbox").is(':visible')) {
@ -69,11 +53,6 @@
return this;
};
utils.removeControlBox = function () {
converse.controlboxtoggle.show();
$('#controlbox').remove();
};
utils.openContactsPanel = function (converse) {
this.openControlBox(converse);
var cbview = converse.chatboxviews.get('controlbox');
@ -157,14 +136,6 @@
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 () {
window.localStorage.clear();
window.sessionStorage.clear();
@ -184,7 +155,7 @@
*
* These contacts are not grouped. See below.
*/
var names, jid;
var names, jid, subscription, requesting, ask;
if (type === 'requesting') {
names = mock.req_names;
subscription = 'none';
@ -206,13 +177,13 @@
.createContacts(converse, 'pending');
return this;
} 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') {
length = names.length;
}
for (i=0; i<length; i++) {
for (var i=0; i<length; i++) {
jid = names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
if (!converse.roster.get(jid)) {
converse.roster.create({