Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
converse.js
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
converse.js
Commits
506aa331
Commit
506aa331
authored
Jul 30, 2018
by
JC Brand
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Wait for promises before opening chats in API methods
parent
cb118b9c
Changes
14
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
2491 additions
and
2401 deletions
+2491
-2401
CHANGES.md
CHANGES.md
+3
-0
dist/converse.js
dist/converse.js
+24
-19
spec/bookmarks.js
spec/bookmarks.js
+93
-97
spec/chatbox.js
spec/chatbox.js
+463
-441
spec/chatroom.js
spec/chatroom.js
+735
-725
spec/http-file-upload.js
spec/http-file-upload.js
+291
-295
spec/messages.js
spec/messages.js
+636
-598
spec/minchats.js
spec/minchats.js
+43
-36
spec/roomslist.js
spec/roomslist.js
+105
-102
spec/spoilers.js
spec/spoilers.js
+26
-22
spec/user-details-modal.js
spec/user-details-modal.js
+10
-9
src/converse-muc-views.js
src/converse-muc-views.js
+1
-2
src/i18n.js
src/i18n.js
+7
-2
tests/utils.js
tests/utils.js
+54
-53
No files found.
CHANGES.md
View file @
506aa331
...
...
@@ -39,6 +39,9 @@
-
New API method
`_converse.api.vcard.update`
.
-
The
`contactStatusChanged`
event has been renamed to
`contactPresenceChanged`
and a event
`presenceChanged`
is now also triggered on the contact.
-
`_converse.api.chats.open`
and
`_converse.api.rooms.open`
now returns a
`Presence`
which resolves with the
`Backbone.Model`
representing the chat
object.
## UI changes
...
...
dist/converse.js
View file @
506aa331
...
...
@@ -76149,17 +76149,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
this.model.on('show', this.show, this);
this.model.occupants.on('add', this.showJoinNotification, this);
this.model.occupants.on('remove', this.showLeaveNotification, this);
this.model.occupants.on('change:show', occupant => {
if (!occupant.isMember() || _.includes(occupant.get('states'), '303')) {
return;
}
if (occupant.get('show') === 'offline') {
this.showLeaveNotification(occupant);
} else if (occupant.get('show') === 'online') {
this.showJoinNotification(occupant);
}
});
this.model.occupants.on('change:show', this.showJoinOrLeaveNotification, this);
this.createEmojiPicker();
this.createOccupantsView();
this.render().insertIntoDOM();
...
...
@@ -76169,8 +76159,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
const handler = () => {
if (!u.isPersistableModel(this.model)) {
// Happens during tests, nothing to do if this
// is a hanging chatbox (i.e. not in the
// collection anymore).
// is a hanging chatbox (i.e. not in the collection anymore).
return;
}
...
...
@@ -77047,6 +77036,18 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
}
},
showJoinOrLeaveNotification(occupant) {
if (!occupant.isMember() || _.includes(occupant.get('states'), '303')) {
return;
}
if (occupant.get('show') === 'offline') {
this.showLeaveNotification(occupant);
} else if (occupant.get('show') === 'online') {
this.showJoinNotification(occupant);
}
},
showJoinNotification(occupant) {
if (this.model.get('connection_status') !== converse.ROOMSTATUS.ENTERED) {
return;
...
...
@@ -77094,10 +77095,9 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
showLeaveNotification(occupant) {
const nick = occupant.get('nick'),
stat = occupant.get('status'),
last_el = this.content.lastElementChild,
last_msg_date = last_el.getAttribute('data-isodate');
last_el = this.content.lastElementChild;
if (
_.includes(_.get(last_el, 'classList', []), 'chat-info') && moment(last_msg_date
).isSame(new Date(), "day") && _.get(last_el, 'dataset', {}).join === `"${nick}"`) {
if (
last_el && _.includes(_.get(last_el, 'classList', []), 'chat-info') && moment(last_el.getAttribute('data-isodate')
).isSame(new Date(), "day") && _.get(last_el, 'dataset', {}).join === `"${nick}"`) {
let message;
if (_.isNil(stat)) {
...
...
@@ -77128,7 +77128,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
'data': `data-leave="${nick}"`
};
if (_.includes(_.get(last_el, 'classList', []), 'chat-info') && _.get(last_el, 'dataset', {}).leavejoin === `"${nick}"`) {
if (
last_el &&
_.includes(_.get(last_el, 'classList', []), 'chat-info') && _.get(last_el, 'dataset', {}).leavejoin === `"${nick}"`) {
last_el.outerHTML = tpl_info(data);
} else {
const el = u.stringToElement(tpl_info(data));
...
...
@@ -83843,8 +83843,13 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 400) {
jed_instance = new Jed(window.JSON.parse(xhr.responseText));
try {
const data = window.JSON.parse(xhr.responseText);
jed_instance = new Jed(data);
resolve();
} catch (e) {
xhr.onerror(e);
}
} else {
xhr.onerror();
}
spec/bookmarks.js
View file @
506aa331
...
...
@@ -34,24 +34,24 @@
});
spyOn
(
_converse
.
connection
,
'
getUniqueId
'
).
and
.
callThrough
();
test_utils
.
openChatRoom
(
_converse
,
'
theplay
'
,
'
conference.shakespeare.lit
'
,
'
JC
'
);
let
view
;
test_utils
.
openChatRoom
(
_converse
,
'
theplay
'
,
'
conference.shakespeare.lit
'
,
'
JC
'
)
.
then
(()
=>
{
var
jid
=
'
theplay@conference.shakespeare.lit
'
;
var
view
=
_converse
.
chatboxviews
.
get
(
jid
);
view
=
_converse
.
chatboxviews
.
get
(
jid
);
spyOn
(
view
,
'
renderBookmarkForm
'
).
and
.
callThrough
();
spyOn
(
view
,
'
closeForm
'
).
and
.
callThrough
();
test_utils
.
waitUntil
(
function
()
{
return
!
_
.
isNull
(
view
.
el
.
querySelector
(
'
.toggle-bookmark
'
));
},
300
).
then
(
function
()
{
var
$bookmark
=
$
(
view
.
el
).
find
(
'
.toggle-bookmark
'
);
$bookmark
[
0
].
click
();
return
test_utils
.
waitUntil
(()
=>
!
_
.
isNull
(
view
.
el
.
querySelector
(
'
.toggle-bookmark
'
)));
}).
then
(()
=>
{
var
bookmark
=
view
.
el
.
querySelector
(
'
.toggle-bookmark
'
);
bookmark
.
click
();
expect
(
view
.
renderBookmarkForm
).
toHaveBeenCalled
();
view
.
el
.
querySelector
(
'
.button-cancel
'
).
click
();
expect
(
view
.
closeForm
).
toHaveBeenCalled
();
expect
(
$bookmark
.
hasClass
(
'
on-button
'
),
false
);
expect
(
u
.
hasClass
(
'
on-button
'
,
bookmark
),
false
);
$bookmark
[
0
]
.
click
();
bookmark
.
click
();
expect
(
view
.
renderBookmarkForm
).
toHaveBeenCalled
();
/* Client uploads data:
...
...
@@ -93,7 +93,7 @@
view
.
el
.
querySelector
(
'
.btn-primary
'
).
click
();
expect
(
view
.
model
.
get
(
'
bookmarked
'
)).
toBeTruthy
();
expect
(
$bookmark
.
hasClass
(
'
on-button
'
),
true
);
expect
(
u
.
hasClass
(
'
on-button
'
,
bookmark
),
true
);
expect
(
sent_stanza
.
toLocaleString
()).
toBe
(
"
<iq type='set' from='dummy@localhost/resource' xmlns='jabber:client' id='
"
+
IQ_id
+
"
'>
"
+
...
...
@@ -175,17 +175,16 @@
it
(
"
displays that it's bookmarked through its bookmark icon
"
,
mock
.
initConverseWithPromises
(
null
,
[
'
rosterGroupsFetched
'
],
{},
function
(
done
,
_converse
)
{
let
view
;
test_utils
.
waitUntilDiscoConfirmed
(
_converse
,
_converse
.
bare_jid
,
[{
'
category
'
:
'
pubsub
'
,
'
type
'
:
'
pep
'
}],
[
'
http://jabber.org/protocol/pubsub#publish-options
'
]
).
then
(
function
()
{
test_utils
.
openChatRoom
(
_converse
,
'
lounge
'
,
'
localhost
'
,
'
dummy
'
);
var
view
=
_converse
.
chatboxviews
.
get
(
'
lounge@localhost
'
);
test_utils
.
waitUntil
(
function
()
{
return
!
_
.
isNull
(
view
.
el
.
querySelector
(
'
.toggle-bookmark
'
));
},
300
).
then
(
function
()
{
).
then
(()
=>
test_utils
.
openChatRoom
(
_converse
,
'
lounge
'
,
'
localhost
'
,
'
dummy
'
))
.
then
(()
=>
{
view
=
_converse
.
chatboxviews
.
get
(
'
lounge@localhost
'
);
return
test_utils
.
waitUntil
(()
=>
!
_
.
isNull
(
view
.
el
.
querySelector
(
'
.toggle-bookmark
'
)))
}).
then
(
function
()
{
var
bookmark_icon
=
view
.
el
.
querySelector
(
'
.toggle-bookmark
'
);
expect
(
_
.
includes
(
bookmark_icon
.
classList
,
'
button-on
'
)).
toBeFalsy
();
view
.
model
.
set
(
'
bookmarked
'
,
true
);
...
...
@@ -194,27 +193,25 @@
expect
(
_
.
includes
(
bookmark_icon
.
classList
,
'
button-on
'
)).
toBeFalsy
();
done
();
});
});
}));
it
(
"
can be unbookmarked
"
,
mock
.
initConverseWithPromises
(
null
,
[
'
rosterGroupsFetched
'
],
{},
function
(
done
,
_converse
)
{
let
sent_stanza
,
IQ_id
,
view
,
sendIQ
;
test_utils
.
waitUntilDiscoConfirmed
(
_converse
,
_converse
.
bare_jid
,
[{
'
category
'
:
'
pubsub
'
,
'
type
'
:
'
pep
'
}],
[
'
http://jabber.org/protocol/pubsub#publish-options
'
]
).
then
(
function
()
{
var
sent_stanza
,
IQ_id
;
var
sendIQ
=
_converse
.
connection
.
sendIQ
;
test_utils
.
openChatRoom
(
_converse
,
'
theplay
'
,
'
conference.shakespeare.lit
'
,
'
JC
'
);
).
then
(()
=>
{
sendIQ
=
_converse
.
connection
.
sendIQ
;
return
test_utils
.
openChatRoom
(
_converse
,
'
theplay
'
,
'
conference.shakespeare.lit
'
,
'
JC
'
);
}).
then
(()
=>
{
var
jid
=
'
theplay@conference.shakespeare.lit
'
;
var
view
=
_converse
.
chatboxviews
.
get
(
jid
);
test_utils
.
waitUntil
(
function
()
{
return
!
_
.
isNull
(
view
.
el
.
querySelector
(
'
.toggle-bookmark
'
));
},
300
).
then
(
function
()
{
view
=
_converse
.
chatboxviews
.
get
(
jid
);
return
test_utils
.
waitUntil
(()
=>
!
_
.
isNull
(
view
.
el
.
querySelector
(
'
.toggle-bookmark
'
)));
}).
then
(
function
()
{
spyOn
(
view
,
'
toggleBookmark
'
).
and
.
callThrough
();
spyOn
(
_converse
.
bookmarks
,
'
sendBookmarkStanza
'
).
and
.
callThrough
();
view
.
delegateEvents
();
...
...
@@ -227,17 +224,17 @@
});
expect
(
_converse
.
bookmarks
.
length
).
toBe
(
1
);
expect
(
view
.
model
.
get
(
'
bookmarked
'
)).
toBeTruthy
();
var
$bookmark_icon
=
$
(
view
.
el
.
querySelector
(
'
.toggle-bookmark
'
)
);
expect
(
$bookmark_icon
.
hasClass
(
'
button-on
'
)).
toBeTruthy
();
var
bookmark_icon
=
view
.
el
.
querySelector
(
'
.toggle-bookmark
'
);
expect
(
u
.
hasClass
(
'
button-on
'
,
bookmark_icon
)).
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
'
).
and
.
callThrough
();
$bookmark_icon
[
0
]
.
click
();
bookmark_icon
.
click
();
expect
(
view
.
toggleBookmark
).
toHaveBeenCalled
();
expect
(
$bookmark_icon
.
hasClass
(
'
button-on
'
)).
toBeFalsy
();
expect
(
u
.
hasClass
(
'
button-on
'
,
bookmark_icon
)).
toBeFalsy
();
expect
(
_converse
.
bookmarks
.
length
).
toBe
(
0
);
// Check that an IQ stanza is sent out, containing no
...
...
@@ -269,7 +266,6 @@
);
done
();
});
});
}));
});
...
...
@@ -585,9 +581,8 @@
'
name
'
:
'
The Play
'
,
'
nick
'
:
''
});
test_utils
.
waitUntil
(
function
()
{
return
$
(
'
#chatrooms .bookmarks.rooms-list .room-item:visible
'
).
length
;
},
300
).
then
(
function
()
{
test_utils
.
waitUntil
(()
=>
$
(
'
#chatrooms .bookmarks.rooms-list .room-item:visible
'
).
length
).
then
(
function
()
{
expect
(
$
(
'
#chatrooms .bookmarks.rooms-list
'
).
hasClass
(
'
collapsed
'
)).
toBeFalsy
();
expect
(
$
(
'
#chatrooms .bookmarks.rooms-list .room-item:visible
'
).
length
).
toBe
(
1
);
expect
(
_converse
.
bookmarksview
.
list_model
.
get
(
'
toggle-state
'
)).
toBe
(
_converse
.
OPENED
);
...
...
@@ -612,6 +607,7 @@
{
hide_open_bookmarks
:
true
},
function
(
done
,
_converse
)
{
const
jid
=
'
room@conference.example.org
'
;
test_utils
.
waitUntilDiscoConfirmed
(
_converse
,
_converse
.
bare_jid
,
[{
'
category
'
:
'
pubsub
'
,
'
type
'
:
'
pep
'
}],
...
...
@@ -625,14 +621,12 @@
_converse
.
emit
(
'
bookmarksInitialized
'
);
// Check that it's there
var
jid
=
'
room@conference.example.org
'
;
_converse
.
bookmarks
.
create
({
'
jid
'
:
jid
,
'
autojoin
'
:
false
,
'
name
'
:
'
The Play
'
,
'
nick
'
:
'
Othello
'
});
expect
(
_converse
.
bookmarks
.
length
).
toBe
(
1
);
var
room_els
=
_converse
.
bookmarksview
.
el
.
querySelectorAll
(
"
.open-room
"
);
expect
(
room_els
.
length
).
toBe
(
1
);
...
...
@@ -640,9 +634,11 @@
// Check that it disappears once the room is opened
var
bookmark
=
_converse
.
bookmarksview
.
el
.
querySelector
(
"
.open-room
"
);
bookmark
.
click
();
return
test_utils
.
waitUntil
(()
=>
_converse
.
chatboxviews
.
get
(
jid
));
}).
then
(()
=>
{
expect
(
u
.
hasClass
(
'
hidden
'
,
_converse
.
bookmarksview
.
el
.
querySelector
(
"
.available-chatroom
"
))).
toBeTruthy
();
// Check that it reappears once the room is closed
var
view
=
_converse
.
chatboxviews
.
get
(
jid
);
const
view
=
_converse
.
chatboxviews
.
get
(
jid
);
view
.
close
();
expect
(
u
.
hasClass
(
'
hidden
'
,
_converse
.
bookmarksview
.
el
.
querySelector
(
"
.available-chatroom
"
))).
toBeFalsy
();
done
();
...
...
spec/chatbox.js
View file @
506aa331
This diff is collapsed.
Click to expand it.
spec/chatroom.js
View file @
506aa331
This diff is collapsed.
Click to expand it.
spec/http-file-upload.js
View file @
506aa331
This diff is collapsed.
Click to expand it.
spec/messages.js
View file @
506aa331
This diff is collapsed.
Click to expand it.
spec/minchats.js
View file @
506aa331
...
...
@@ -13,13 +13,16 @@
function
(
done
,
_converse
)
{
test_utils
.
createContacts
(
_converse
,
'
current
'
);
_converse
.
emit
(
'
rosterContactsFetched
'
);
test_utils
.
openControlBox
();
_converse
.
minimized_chats
.
toggleview
.
model
.
browserStorage
.
_clear
();
_converse
.
minimized_chats
.
initToggle
();
var
contact_jid
,
chatview
;
contact_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
);
let
contact_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
let
chatview
;
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
)
.
then
(()
=>
{
chatview
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
expect
(
chatview
.
model
.
get
(
'
minimized
'
)).
toBeFalsy
();
expect
(
$
(
_converse
.
minimized_chats
.
el
).
is
(
'
:visible
'
)).
toBeFalsy
();
...
...
@@ -30,7 +33,8 @@
expect
(
_converse
.
minimized_chats
.
keys
()[
0
]).
toBe
(
contact_jid
);
contact_jid
=
mock
.
cur_names
[
1
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
);
return
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
);
}).
then
(()
=>
{
chatview
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
expect
(
chatview
.
model
.
get
(
'
minimized
'
)).
toBeFalsy
();
chatview
.
el
.
querySelector
(
'
.toggle-chatbox-button
'
).
click
();
...
...
@@ -39,6 +43,7 @@
expect
(
_converse
.
minimized_chats
.
keys
().
length
).
toBe
(
2
);
expect
(
_
.
includes
(
_converse
.
minimized_chats
.
keys
(),
contact_jid
)).
toBeTruthy
();
done
();
});
}));
it
(
"
can be toggled to hide or show minimized chats
"
,
...
...
@@ -47,24 +52,26 @@
function
(
done
,
_converse
)
{
test_utils
.
createContacts
(
_converse
,
'
current
'
);
_converse
.
emit
(
'
rosterContactsFetched
'
);
test_utils
.
openControlBox
();
_converse
.
minimized_chats
.
toggleview
.
model
.
browserStorage
.
_clear
();
_converse
.
minimized_chats
.
initToggle
();
var
contact_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
);
var
chatview
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
expect
(
$
(
_converse
.
minimized_chats
.
el
).
is
(
'
:visible
'
)).
toBeFalsy
();
const
contact_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
)
.
then
(()
=>
{
const
chatview
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
expect
(
u
.
isVisible
(
_converse
.
minimized_chats
.
el
)).
toBeFalsy
();
chatview
.
model
.
set
({
'
minimized
'
:
true
});
expect
(
$
(
_converse
.
minimized_chats
.
el
).
is
(
'
:visible
'
)).
toBeTruthy
();
expect
(
u
.
isVisible
(
_converse
.
minimized_chats
.
el
)).
toBeTruthy
();
expect
(
_converse
.
minimized_chats
.
keys
().
length
).
toBe
(
1
);
expect
(
_converse
.
minimized_chats
.
keys
()[
0
]).
toBe
(
contact_jid
);
expect
(
$
(
_converse
.
minimized_chats
.
el
.
querySelector
(
'
.minimized-chats-flyout
'
)).
is
(
'
:visible
'
)).
toBeTruthy
();
expect
(
u
.
isVisible
(
_converse
.
minimized_chats
.
el
.
querySelector
(
'
.minimized-chats-flyout
'
)
)).
toBeTruthy
();
expect
(
_converse
.
minimized_chats
.
toggleview
.
model
.
get
(
'
collapsed
'
)).
toBeFalsy
();
_converse
.
minimized_chats
.
el
.
querySelector
(
'
#toggle-minimized-chats
'
).
click
();
return
test_utils
.
waitUntil
(()
=>
u
.
isVisible
(
u
.
isVisible
(
_converse
.
minimized_chats
.
el
.
querySelector
(
'
.minimized-chats-flyout
'
))))
.
then
(
function
()
{
return
test_utils
.
waitUntil
(()
=>
u
.
isVisible
(
_converse
.
minimized_chats
.
el
.
querySelector
(
'
.minimized-chats-flyout
'
)));
}).
then
(()
=>
{
expect
(
_converse
.
minimized_chats
.
toggleview
.
model
.
get
(
'
collapsed
'
)).
toBeTruthy
();
done
();
});
...
...
spec/roomslist.js
View file @
506aa331
...
...
@@ -12,25 +12,26 @@
describe
(
"
A list of open rooms
"
,
function
()
{
it
(
"
is shown in the
\"
Rooms
\"
panel
"
,
mock
.
initConverseWithPromises
(
null
,
[
'
rosterGroupsFetched
'
],
null
,
[
'
rosterGroupsFetched
'
,
'
chatBoxesFetched
'
],
{
allow_bookmarks
:
false
// Makes testing easier, otherwise we
// have to mock stanza traffic.
},
function
(
done
,
_converse
)
{
test_utils
.
openControlBox
();
var
controlbox
=
_converse
.
chatboxviews
.
get
(
'
controlbox
'
);
var
list
=
controlbox
.
el
.
querySelector
(
'
div.rooms-list-container
'
);
const
controlbox
=
_converse
.
chatboxviews
.
get
(
'
controlbox
'
);
let
list
=
controlbox
.
el
.
querySelector
(
'
div.rooms-list-container
'
);
expect
(
_
.
includes
(
list
.
classList
,
'
hidden
'
)).
toBeTruthy
();
test_utils
.
openChatRoom
(
_converse
,
'
room
'
,
'
conference.shakespeare.lit
'
,
'
JC
'
)
;
let
room_els
;
test_utils
.
openChatRoom
(
_converse
,
'
room
'
,
'
conference.shakespeare.lit
'
,
'
JC
'
)
.
then
(()
=>
{
expect
(
_
.
isUndefined
(
_converse
.
rooms_list_view
)).
toBeFalsy
();
var
room_els
=
_converse
.
rooms_list_view
.
el
.
querySelectorAll
(
"
.open-room
"
);
room_els
=
_converse
.
rooms_list_view
.
el
.
querySelectorAll
(
"
.open-room
"
);
expect
(
room_els
.
length
).
toBe
(
1
);
expect
(
room_els
[
0
].
innerText
).
toBe
(
'
room@conference.shakespeare.lit
'
);
test_utils
.
openChatRoom
(
_converse
,
'
lounge
'
,
'
localhost
'
,
'
dummy
'
);
return
test_utils
.
openChatRoom
(
_converse
,
'
lounge
'
,
'
localhost
'
,
'
dummy
'
);
}).
then
(()
=>
{
room_els
=
_converse
.
rooms_list_view
.
el
.
querySelectorAll
(
"
.open-room
"
);
expect
(
room_els
.
length
).
toBe
(
2
);
...
...
@@ -50,6 +51,7 @@
list
=
controlbox
.
el
.
querySelector
(
'
div.rooms-list-container
'
);
expect
(
_
.
includes
(
list
.
classList
,
'
hidden
'
)).
toBeTruthy
();
done
();
});
}
));
});
...
...
@@ -57,26 +59,26 @@
describe
(
"
A groupchat shown in the groupchats list
"
,
function
()
{
it
(
"
is highlighted if its currently open
"
,
mock
.
initConverseWithPromises
(
null
,
[
'
rosterGroupsFetched
'
],
null
,
[
'
rosterGroupsFetched
'
,
'
chatBoxesFetched
'
],
{
whitelisted_plugins
:
[
'
converse-roomslist
'
],
allow_bookmarks
:
false
// Makes testing easier, otherwise we
// have to mock stanza traffic.
},
function
(
done
,
_converse
)
{
spyOn
(
_converse
,
'
isSingleton
'
).
and
.
callFake
(
function
()
{
return
true
;
});
spyOn
(
_converse
,
'
isSingleton
'
).
and
.
callFake
(()
=>
true
);
let
room_els
,
item
;
test_utils
.
openControlBox
();
_converse
.
api
.
rooms
.
open
(
'
coven@chat.shakespeare.lit
'
,
{
'
nick
'
:
'
some1
'
});
let
room_els
=
_converse
.
rooms_list_view
.
el
.
querySelectorAll
(
"
.available-chatroom
"
);
_converse
.
api
.
rooms
.
open
(
'
coven@chat.shakespeare.lit
'
,
{
'
nick
'
:
'
some1
'
})
.
then
(()
=>
{
room_els
=
_converse
.
rooms_list_view
.
el
.
querySelectorAll
(
"
.available-chatroom
"
);
expect
(
room_els
.
length
).
toBe
(
1
);
let
item
=
room_els
[
0
];
item
=
room_els
[
0
];
expect
(
u
.
hasClass
(
'
open
'
,
item
)).
toBe
(
true
);
expect
(
item
.
textContent
.
trim
()).
toBe
(
'
coven@chat.shakespeare.lit
'
);
_converse
.
api
.
rooms
.
open
(
'
balcony@chat.shakespeare.lit
'
,
{
'
nick
'
:
'
some1
'
});
return
_converse
.
api
.
rooms
.
open
(
'
balcony@chat.shakespeare.lit
'
,
{
'
nick
'
:
'
some1
'
});
}).
then
(()
=>
{
room_els
=
_converse
.
rooms_list_view
.
el
.
querySelectorAll
(
"
.open-room
"
);
expect
(
room_els
.
length
).
toBe
(
2
);
...
...
@@ -85,18 +87,21 @@
item
=
room_els
[
0
];
expect
(
item
.
textContent
.
trim
()).
toBe
(
'
balcony@chat.shakespeare.lit
'
);
done
();
});
}));
it
(
"
has an info icon which opens a details modal when clicked
"
,
mock
.
initConverseWithPromises
(
null
,
[
'
rosterGroupsFetched
'
],
null
,
[
'
rosterGroupsFetched
'
,
'
chatBoxesFetched
'
],
{
whitelisted_plugins
:
[
'
converse-roomslist
'
],
allow_bookmarks
:
false
// Makes testing easier, otherwise we
// have to mock stanza traffic.
},
function
(
done
,
_converse
)
{
let
view
;
test_utils
.
openControlBox
();
_converse
.
api
.
rooms
.
open
(
'
coven@chat.shakespeare.lit
'
,
{
'
nick
'
:
'
some1
'
});
const
view
=
_converse
.
chatboxviews
.
get
(
'
coven@chat.shakespeare.lit
'
);
_converse
.
api
.
rooms
.
open
(
'
coven@chat.shakespeare.lit
'
,
{
'
nick
'
:
'
some1
'
})
.
then
(()
=>
{
view
=
_converse
.
chatboxviews
.
get
(
'
coven@chat.shakespeare.lit
'
);
const
last_stanza
=
_
.
last
(
_converse
.
connection
.
IQ_stanzas
).
nodeTree
;
const
IQ_id
=
last_stanza
.
getAttribute
(
'
id
'
);
const
features_stanza
=
$iq
({
...
...
@@ -127,9 +132,8 @@
.
c
(
'
field
'
,
{
'
type
'
:
'
text-single
'
,
'
var
'
:
'
muc#roominfo_occupants
'
,
'
label
'
:
'
Number of occupants
'
})
.
c
(
'
value
'
).
t
(
0
);
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
features_stanza
));
test_utils
.
waitUntil
(()
=>
view
.
model
.
get
(
'
connection_status
'
)
===
converse
.
ROOMSTATUS
.
CONNECTING
)
.
then
(
function
()
{
return
test_utils
.
waitUntil
(()
=>
view
.
model
.
get
(
'
connection_status
'
)
===
converse
.
ROOMSTATUS
.
CONNECTING
)
}).
then
(
function
()
{
var
presence
=
$pres
({
to
:
_converse
.
connection
.
jid
,
from
:
'
coven@chat.shakespeare.lit/some1
'
,
...
...
@@ -201,12 +205,10 @@
},
function
(
done
,
_converse
)
{
spyOn
(
window
,
'
confirm
'
).
and
.
callFake
(
function
()
{
return
true
;
});
spyOn
(
window
,
'
confirm
'
).
and
.
callFake
(()
=>
true
);
expect
(
_converse
.
chatboxes
.
length
).
toBe
(
1
);
test_utils
.
openChatRoom
(
_converse
,
'
lounge
'
,
'
conference.shakespeare.lit
'
,
'
JC
'
);
test_utils
.
openChatRoom
(
_converse
,
'
lounge
'
,
'
conference.shakespeare.lit
'
,
'
JC
'
)
.
then
(()
=>
{
expect
(
_converse
.
chatboxes
.
length
).
toBe
(
2
);
var
room_els
=
_converse
.
rooms_list_view
.
el
.
querySelectorAll
(
"
.open-room
"
);
expect
(
room_els
.
length
).
toBe
(
1
);
...
...
@@ -218,6 +220,7 @@
expect
(
room_els
.
length
).
toBe
(
0
);
expect
(
_converse
.
chatboxes
.
length
).
toBe
(
1
);
done
();
});
}));
it
(
"
shows unread messages directed at the user
"
,
mock
.
initConverseWithAsync
(
...
...
spec/spoilers.js
View file @
506aa331
...
...
@@ -92,12 +92,14 @@
it
(
"
can be sent without a hint
"
,
mock
.
initConverseWithPromises
(
null
,
[
'
rosterGroupsFetched
'
],
{},
null
,
[
'
rosterGroupsFetched
'
,
'
chatBoxesFetched
'
],
{},
function
(
done
,
_converse
)
{
test_utils
.
createContacts
(
_converse
,
'
current
'
);
test_utils
.
createContacts
(
_converse
,
'
current
'
,
1
);
_converse
.
emit
(
'
rosterContactsFetched
'
);
test_utils
.
openControlBox
();
var
contact_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
const
contact_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
// XXX: We need to send a presence from the contact, so that we
// have a resource, that resource is then queried to see
...
...
@@ -108,9 +110,9 @@
'
to
'
:
'
dummy@localhost
'
});
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
presence
));
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
)
;
test_utils
.
waitUntilDiscoConfirmed
(
_converse
,
contact_jid
+
'
/phone
'
,
[],
[
Strophe
.
NS
.
SPOILER
]).
then
(
function
()
{
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
)
.
then
(()
=>
test_utils
.
waitUntilDiscoConfirmed
(
_converse
,
contact_jid
+
'
/phone
'
,
[],
[
Strophe
.
NS
.
SPOILER
]))
.
then
(()
=>
{
var
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
spyOn
(
view
,
'
onMessageSubmitted
'
).
and
.
callThrough
();
spyOn
(
_converse
.
connection
,
'
send
'
);
...
...
@@ -167,10 +169,12 @@
it
(
"
can be sent with a hint
"
,
mock
.
initConverseWithPromises
(
null
,
[
'
rosterGroupsFetched
'
],
{},
null
,
[
'
rosterGroupsFetched
'
,
'
chatBoxesFetched
'
],
{},
function
(
done
,
_converse
)
{
test_utils
.
createContacts
(
_converse
,
'
current
'
);
test_utils
.
createContacts
(
_converse
,
'
current
'
,
1
);
_converse
.
emit
(
'
rosterContactsFetched
'
);
test_utils
.
openControlBox
();
var
contact_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
...
...
@@ -183,9 +187,9 @@
'
to
'
:
'
dummy@localhost
'
});
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
presence
));
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
)
;
test_utils
.
waitUntilDiscoConfirmed
(
_converse
,
contact_jid
+
'
/phone
'
,
[],
[
Strophe
.
NS
.
SPOILER
]).
then
(
function
()
{
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
)
.
then
(()
=>
test_utils
.
waitUntilDiscoConfirmed
(
_converse
,
contact_jid
+
'
/phone
'
,
[],
[
Strophe
.
NS
.
SPOILER
]))
.
then
(()
=>
{
var
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
var
spoiler_toggle
=
view
.
el
.
querySelector
(
'
.toggle-compose-spoiler
'
);
spoiler_toggle
.
click
();
...
...
spec/user-details-modal.js
View file @
506aa331
...
...
@@ -58,16 +58,17 @@
test_utils
.
createContacts
(
_converse
,
'
current
'
);
_converse
.
emit
(
'
rosterContactsFetched
'
);
let
view
,
modal
;
const
contact_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
)
;
const
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
)
.
then
(()
=>
{
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
const
show_modal_button
=
view
.
el
.
querySelector
(
'
.show-user-details-modal
'
);
expect
(
u
.
isVisible
(
show_modal_button
)).
toBeTruthy
();
show_modal_button
.
click
();
const
modal
=
view
.
user_details_modal
;
test_utils
.
waitUntil
(()
=>
u
.
isVisible
(
modal
.
el
),
2000
)
.
then
(
function
()
{
modal
=
view
.
user_details_modal
;
return
test_utils
.
waitUntil
(()
=>
u
.
isVisible
(
modal
.
el
),
2000
);
})
.
then
(
function
()
{
spyOn
(
window
,
'
confirm
'
).
and
.
returnValue
(
true
);
spyOn
(
view
.
model
.
contact
,
'
removeFromRoster
'
).
and
.
callFake
(
function
(
callback
,
errback
)
{
errback
();
...
...
src/converse-muc-views.js
View file @
506aa331
...
...
@@ -561,8 +561,7 @@
const
handler
=
()
=>
{
if
(
!
u
.
isPersistableModel
(
this
.
model
))
{
// Happens during tests, nothing to do if this
// is a hanging chatbox (i.e. not in the
// collection anymore).
// is a hanging chatbox (i.e. not in the collection anymore).
return
;
}
this
.
populateAndJoin
();
...
...
src/i18n.js
View file @
506aa331
...
...
@@ -148,8 +148,13 @@
);
xhr
.
onload
=
function
()
{
if
(
xhr
.
status
>=
200
&&
xhr
.
status
<
400
)
{
jed_instance
=
new
Jed
(
window
.
JSON
.
parse
(
xhr
.
responseText
));
try
{
const
data
=
window
.
JSON
.
parse
(
xhr
.
responseText
);
jed_instance
=
new
Jed
(
data
);
resolve
();
}
catch
(
e
)
{
xhr
.
onerror
(
e
);
}
}
else
{
xhr
.
onerror
();
}
...
...
tests/utils.js
View file @
506aa331
...
...
@@ -98,8 +98,9 @@
return
views
;
};
utils
.
openChatBoxFor
=
function
(
converse
,
jid
)
{
return
converse
.
roster
.
get
(
jid
).
trigger
(
"
open
"
);
utils
.
openChatBoxFor
=
function
(
_converse
,
jid
)
{
_converse
.
roster
.
get
(
jid
).
trigger
(
"
open
"
);
return
utils
.
waitUntil
(()
=>
_converse
.
chatboxviews
.
get
(
jid
));
};
utils
.
openChatRoomViaModal
=
function
(
_converse
,
jid
,
nick
)
{
...
...
@@ -121,14 +122,14 @@
};
utils
.
openChatRoom
=
function
(
_converse
,
room
,
server
,
nick
)
{
_converse
.
api
.
rooms
.
open
(
`
${
room
}
@
${
server
}
`
);
return
_converse
.
api
.
rooms
.
open
(
`
${
room
}
@
${
server
}
`
);
};
utils
.
openAndEnterChatRoom
=
function
(
_converse
,
room
,
server
,
nick
)
{
let
last_stanza
;
return
new
Promise
(
function
(
resolve
,
reject
)
{
_converse
.
api
.
rooms
.
open
(
`
${
room
}
@
${
server
}
`
);
return
new
Promise
(
(
resolve
,
reject
)
=>
{
return
_converse
.
api
.
rooms
.
open
(
`
${
room
}
@
${
server
}
`
).
then
(()
=>
{
const
view
=
_converse
.
chatboxviews
.
get
((
room
+
'
@
'
+
server
).
toLowerCase
());
// We pretend this is a new room, so no disco info is returned.
let
last_stanza
=
_
.
last
(
_converse
.
connection
.
IQ_stanzas
).
nodeTree
;
...
...
@@ -178,7 +179,7 @@
.
c
(
'
status
'
).
attrs
({
code
:
'
110
'
});
_converse
.
connection
.
_dataRecv
(
utils
.
createRequest
(
presence
));
resolve
();
}).
catch
(
_
.
partial
(
console
.
error
,
_
));
}).
catch
(
_
.
partial
(
console
.
error
,
_
));
}).
catch
(
_
.
partial
(
console
.
error
,
_
));
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment