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
53b3f2d0
Commit
53b3f2d0
authored
Oct 26, 2018
by
JC Brand
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix failing tests and rewrite to use async/await
parent
65190834
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
641 additions
and
675 deletions
+641
-675
spec/bookmarks.js
spec/bookmarks.js
+214
-209
spec/chatbox.js
spec/chatbox.js
+80
-106
spec/chatroom.js
spec/chatroom.js
+25
-26
spec/http-file-upload.js
spec/http-file-upload.js
+259
-263
spec/notification.js
spec/notification.js
+42
-39
spec/roster.js
spec/roster.js
+18
-31
spec/spoilers.js
spec/spoilers.js
+3
-0
tests/runner.js
tests/runner.js
+0
-1
No files found.
spec/bookmarks.js
View file @
53b3f2d0
...
...
@@ -9,12 +9,13 @@
],
factory
);
}
(
this
,
function
(
jasmine
,
$
,
mock
,
test_utils
)
{
"
use strict
"
;
var
$iq
=
converse
.
env
.
$iq
,
$msg
=
converse
.
env
.
$msg
,
Backbone
=
converse
.
env
.
Backbone
,
Strophe
=
converse
.
env
.
Strophe
,
_
=
converse
.
env
.
_
,
u
=
converse
.
env
.
utils
;
const
$iq
=
converse
.
env
.
$iq
,
$msg
=
converse
.
env
.
$msg
,
Backbone
=
converse
.
env
.
Backbone
,
Strophe
=
converse
.
env
.
Strophe
,
sizzle
=
converse
.
env
.
sizzle
,
_
=
converse
.
env
.
_
,
u
=
converse
.
env
.
utils
;
describe
(
"
A chat room
"
,
function
()
{
...
...
@@ -369,242 +370,246 @@
});
}));
it
(
"
can be retrieved from the XMPP server
"
,
mock
.
initConverseWithPromises
(
[
'
send
'
],
[
'
chatBoxesFetched
'
,
'
roomsPanelRendered
'
,
'
rosterGroupsFetched
'
],
{},
function
(
done
,
_converse
)
{
async
function
(
done
,
_converse
)
{
test_utils
.
waitUntilDiscoConfirmed
(
await
test_utils
.
waitUntilDiscoConfirmed
(
_converse
,
_converse
.
bare_jid
,
[{
'
category
'
:
'
pubsub
'
,
'
type
'
:
'
pep
'
}],
[
'
http://jabber.org/protocol/pubsub#publish-options
'
]
).
then
(
function
()
{
/* Client requests all items
* -------------------------
*
* <iq from='juliet@capulet.lit/randomID' type='get' id='retrieve1'>
* <pubsub xmlns='http://jabber.org/protocol/pubsub'>
* <items node='storage:bookmarks'/>
* </pubsub>
* </iq>
*/
var
IQ_id
;
expect
(
_
.
filter
(
_converse
.
connection
.
send
.
calls
.
all
(),
function
(
call
)
{
var
stanza
=
call
.
args
[
0
];
if
(
!
(
stanza
instanceof
Element
)
||
stanza
.
nodeName
!==
'
iq
'
)
{
return
;
}
// XXX: Wrapping in a div is a workaround for PhantomJS
var
div
=
document
.
createElement
(
'
div
'
);
div
.
appendChild
(
stanza
);
if
(
div
.
innerHTML
===
'
<iq from="dummy@localhost/resource" type="get"
'
+
'
xmlns="jabber:client" id="
'
+
stanza
.
getAttribute
(
'
id
'
)
+
'
">
'
+
'
<pubsub xmlns="http://jabber.org/protocol/pubsub">
'
+
'
<items node="storage:bookmarks"></items>
'
+
'
</pubsub>
'
+
'
</iq>
'
)
{
IQ_id
=
stanza
.
getAttribute
(
'
id
'
);
return
true
;
);
/* Client requests all items
* -------------------------
*
* <iq from='juliet@capulet.lit/randomID' type='get' id='retrieve1'>
* <pubsub xmlns='http://jabber.org/protocol/pubsub'>
* <items node='storage:bookmarks'/>
* </pubsub>
* </iq>
*/
let
IQ_id
;
const
call
=
await
test_utils
.
waitUntil
(()
=>
_
.
filter
(
_converse
.
connection
.
send
.
calls
.
all
(),
call
=>
{
const
stanza
=
call
.
args
[
0
];
if
(
!
(
stanza
instanceof
Element
)
||
stanza
.
nodeName
!==
'
iq
'
)
{
return
;
}
if
(
sizzle
(
'
items[node="storage:bookmarks"]
'
,
stanza
).
length
)
{
IQ_id
=
stanza
.
getAttribute
(
'
id
'
);
return
true
;
}
}
}).
length
).
toBe
(
1
);
/*
* Server returns all items
* ------------------------
* <iq type='result'
* to='juliet@capulet.lit/randomID'
* id='retrieve1'>
* <pubsub xmlns='http://jabber.org/protocol/pubsub'>
* <items node='storage:bookmarks'>
* <item id='current'>
* <storage xmlns='storage:bookmarks'>
* <conference name='The Play's the Thing'
* autojoin='true'
* jid='theplay@conference.shakespeare.lit'>
* <nick>JC</nick>
* </conference>
* </storage>
* </item>
* </items>
* </pubsub>
* </iq>
*/
expect
(
_converse
.
bookmarks
.
models
.
length
).
toBe
(
0
);
spyOn
(
_converse
.
bookmarks
,
'
onBookmarksReceived
'
).
and
.
callThrough
();
var
stanza
=
$iq
({
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
result
'
,
'
id
'
:
IQ_id
})
).
pop
()
);
expect
(
Strophe
.
serialize
(
call
.
args
[
0
])).
toBe
(
`<iq from="dummy@localhost/resource" id="
${
IQ_id
}
" type="get" xmlns="jabber:client">`
+
'
<pubsub xmlns="http://jabber.org/protocol/pubsub">
'
+
'
<items node="storage:bookmarks"/>
'
+
'
</pubsub>
'
+
'
</iq>
'
);
/*
* Server returns all items
* ------------------------
* <iq type='result'
* to='juliet@capulet.lit/randomID'
* id='retrieve1'>
* <pubsub xmlns='http://jabber.org/protocol/pubsub'>
* <items node='storage:bookmarks'>
* <item id='current'>
* <storage xmlns='storage:bookmarks'>
* <conference name='The Play's the Thing'
* autojoin='true'
* jid='theplay@conference.shakespeare.lit'>
* <nick>JC</nick>
* </conference>
* </storage>
* </item>
* </items>
* </pubsub>
* </iq>
*/
expect
(
_converse
.
bookmarks
.
models
.
length
).
toBe
(
0
);
spyOn
(
_converse
.
bookmarks
,
'
onBookmarksReceived
'
).
and
.
callThrough
();
var
stanza
=
$iq
({
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
result
'
,
'
id
'
:
IQ_id
})
.
c
(
'
pubsub
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
PUBSUB
})
.
c
(
'
items
'
,
{
'
node
'
:
'
storage:bookmarks
'
})
.
c
(
'
item
'
,
{
'
id
'
:
'
current
'
})
.
c
(
'
storage
'
,
{
'
xmlns
'
:
'
storage:bookmarks
'
})
.
c
(
'
conference
'
,
{
'
name
'
:
'
The Play's the Thing
'
,
'
autojoin
'
:
'
true
'
,
'
jid
'
:
'
theplay@conference.shakespeare.lit
'
}).
c
(
'
nick
'
).
t
(
'
JC
'
).
up
().
up
()
.
c
(
'
conference
'
,
{
'
name
'
:
'
Another room
'
,
'
autojoin
'
:
'
false
'
,
'
jid
'
:
'
another@conference.shakespeare.lit
'
});
// Purposefully exclude the <nick> element to test #1043
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
await
test_utils
.
waitUntil
(()
=>
_converse
.
bookmarks
.
onBookmarksReceived
.
calls
.
count
());
expect
(
_converse
.
bookmarks
.
models
.
length
).
toBe
(
2
);
expect
(
_converse
.
bookmarks
.
findWhere
({
'
jid
'
:
'
theplay@conference.shakespeare.lit
'
}).
get
(
'
autojoin
'
)).
toBe
(
true
);
expect
(
_converse
.
bookmarks
.
findWhere
({
'
jid
'
:
'
another@conference.shakespeare.lit
'
}).
get
(
'
autojoin
'
)).
toBe
(
false
);
done
();
}));
describe
(
"
The rooms panel
"
,
function
()
{
it
(
"
shows a list of bookmarks
"
,
mock
.
initConverseWithPromises
(
[
'
send
'
],
[
'
rosterGroupsFetched
'
],
{},
async
function
(
done
,
_converse
)
{
await
test_utils
.
waitUntilDiscoConfirmed
(
_converse
,
_converse
.
bare_jid
,
[{
'
category
'
:
'
pubsub
'
,
'
type
'
:
'
pep
'
}],
[
'
http://jabber.org/protocol/pubsub#publish-options
'
]
);
test_utils
.
openControlBox
();
let
IQ_id
;
const
call
=
await
test_utils
.
waitUntil
(()
=>
_
.
filter
(
_converse
.
connection
.
send
.
calls
.
all
(),
call
=>
{
const
stanza
=
call
.
args
[
0
];
if
(
!
(
stanza
instanceof
Element
)
||
stanza
.
nodeName
!==
'
iq
'
)
{
return
;
}
if
(
sizzle
(
'
items[node="storage:bookmarks"]
'
,
stanza
).
length
)
{
IQ_id
=
stanza
.
getAttribute
(
'
id
'
);
return
true
;
}
}
).
pop
()
);
expect
(
Strophe
.
serialize
(
call
.
args
[
0
])).
toBe
(
`<iq from="dummy@localhost/resource" id="
${
IQ_id
}
" type="get" xmlns="jabber:client">`
+
'
<pubsub xmlns="http://jabber.org/protocol/pubsub">
'
+
'
<items node="storage:bookmarks"/>
'
+
'
</pubsub>
'
+
'
</iq>
'
);
const
stanza
=
$iq
({
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
result
'
,
'
id
'
:
IQ_id
})
.
c
(
'
pubsub
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
PUBSUB
})
.
c
(
'
items
'
,
{
'
node
'
:
'
storage:bookmarks
'
})
.
c
(
'
item
'
,
{
'
id
'
:
'
current
'
})
.
c
(
'
storage
'
,
{
'
xmlns
'
:
'
storage:bookmarks
'
})
.
c
(
'
conference
'
,
{
'
name
'
:
'
The Play's the Thing
'
,
'
autojoin
'
:
'
tru
e
'
,
'
autojoin
'
:
'
fals
e
'
,
'
jid
'
:
'
theplay@conference.shakespeare.lit
'
}).
c
(
'
nick
'
).
t
(
'
JC
'
).
up
().
up
()
.
c
(
'
conference
'
,
{
'
name
'
:
'
1st Bookmark
'
,
'
autojoin
'
:
'
false
'
,
'
jid
'
:
'
first@conference.shakespeare.lit
'
}).
c
(
'
nick
'
).
t
(
'
JC
'
).
up
().
up
()
.
c
(
'
conference
'
,
{
'
autojoin
'
:
'
false
'
,
'
jid
'
:
'
noname@conference.shakespeare.lit
'
}).
c
(
'
nick
'
).
t
(
'
JC
'
).
up
().
up
()
.
c
(
'
conference
'
,
{
'
name
'
:
'
Bookmark with a very very long name that will be shortened
'
,
'
autojoin
'
:
'
false
'
,
'
jid
'
:
'
longname@conference.shakespeare.lit
'
}).
c
(
'
nick
'
).
t
(
'
JC
'
).
up
().
up
()
.
c
(
'
conference
'
,
{
'
name
'
:
'
Another room
'
,
'
autojoin
'
:
'
false
'
,
'
jid
'
:
'
another@conference.shakespeare.lit
'
})
;
// Purposefully exclude the <nick> element to test #1043
})
.
c
(
'
nick
'
).
t
(
'
JC
'
).
up
().
up
();
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
return
test_utils
.
waitUntil
(()
=>
_converse
.
bookmarks
.
onBookmarksReceived
.
calls
.
count
(),
300
)
}).
then
(()
=>
{
expect
(
_converse
.
bookmarks
.
models
.
length
).
toBe
(
2
);
expect
(
_converse
.
bookmarks
.
findWhere
({
'
jid
'
:
'
theplay@conference.shakespeare.lit
'
}).
get
(
'
autojoin
'
)).
toBe
(
true
);
expect
(
_converse
.
bookmarks
.
findWhere
({
'
jid
'
:
'
another@conference.shakespeare.lit
'
}).
get
(
'
autojoin
'
)).
toBe
(
false
);
done
();
}).
catch
(
_
.
partial
(
console
.
error
,
_
));
}));
describe
(
"
The rooms panel
"
,
function
()
{
it
(
"
shows a list of bookmarks
"
,
mock
.
initConverseWithPromises
(
[
'
send
'
],
[
'
rosterGroupsFetched
'
],
{},
function
(
done
,
_converse
)
{
test_utils
.
waitUntilDiscoConfirmed
(
_converse
,
_converse
.
bare_jid
,
[{
'
category
'
:
'
pubsub
'
,
'
type
'
:
'
pep
'
}],
[
'
http://jabber.org/protocol/pubsub#publish-options
'
]
).
then
(
function
()
{
test_utils
.
openControlBox
();
var
IQ_id
;
expect
(
_
.
filter
(
_converse
.
connection
.
send
.
calls
.
all
(),
function
(
call
)
{
var
stanza
=
call
.
args
[
0
];
if
(
!
(
stanza
instanceof
Element
)
||
stanza
.
nodeName
!==
'
iq
'
)
{
return
;
}
// XXX: Wrapping in a div is a workaround for PhantomJS
var
div
=
document
.
createElement
(
'
div
'
);
div
.
appendChild
(
stanza
);
if
(
div
.
innerHTML
===
'
<iq from="dummy@localhost/resource" type="get"
'
+
'
xmlns="jabber:client" id="
'
+
stanza
.
getAttribute
(
'
id
'
)
+
'
">
'
+
'
<pubsub xmlns="http://jabber.org/protocol/pubsub">
'
+
'
<items node="storage:bookmarks"></items>
'
+
'
</pubsub>
'
+
'
</iq>
'
)
{
IQ_id
=
stanza
.
getAttribute
(
'
id
'
);
return
true
;
}
}).
length
).
toBe
(
1
);
var
stanza
=
$iq
({
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
result
'
,
'
id
'
:
IQ_id
})
.
c
(
'
pubsub
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
PUBSUB
})
.
c
(
'
items
'
,
{
'
node
'
:
'
storage:bookmarks
'
})
.
c
(
'
item
'
,
{
'
id
'
:
'
current
'
})
.
c
(
'
storage
'
,
{
'
xmlns
'
:
'
storage:bookmarks
'
})
.
c
(
'
conference
'
,
{
'
name
'
:
'
The Play's the Thing
'
,
'
autojoin
'
:
'
false
'
,
'
jid
'
:
'
theplay@conference.shakespeare.lit
'
}).
c
(
'
nick
'
).
t
(
'
JC
'
).
up
().
up
()
.
c
(
'
conference
'
,
{
'
name
'
:
'
1st Bookmark
'
,
'
autojoin
'
:
'
false
'
,
'
jid
'
:
'
first@conference.shakespeare.lit
'
}).
c
(
'
nick
'
).
t
(
'
JC
'
).
up
().
up
()
.
c
(
'
conference
'
,
{
'
autojoin
'
:
'
false
'
,
'
jid
'
:
'
noname@conference.shakespeare.lit
'
}).
c
(
'
nick
'
).
t
(
'
JC
'
).
up
().
up
()
.
c
(
'
conference
'
,
{
'
name
'
:
'
Bookmark with a very very long name that will be shortened
'
,
'
autojoin
'
:
'
false
'
,
'
jid
'
:
'
longname@conference.shakespeare.lit
'
}).
c
(
'
nick
'
).
t
(
'
JC
'
).
up
().
up
()
.
c
(
'
conference
'
,
{
'
name
'
:
'
Another room
'
,
'
autojoin
'
:
'
false
'
,
'
jid
'
:
'
another@conference.shakespeare.lit
'
}).
c
(
'
nick
'
).
t
(
'
JC
'
).
up
().
up
();
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
test_utils
.
waitUntil
(()
=>
document
.
querySelectorAll
(
'
#chatrooms div.bookmarks.rooms-list .room-item
'
).
length
,
300
)
.
then
(()
=>
{
expect
(
document
.
querySelectorAll
(
'
#chatrooms div.bookmarks.rooms-list .room-item
'
).
length
).
toBe
(
5
);
const
els
=
document
.
querySelectorAll
(
'
#chatrooms div.bookmarks.rooms-list .room-item a.list-item-link
'
);
expect
(
els
[
0
].
textContent
).
toBe
(
"
1st Bookmark
"
);
expect
(
els
[
1
].
textContent
).
toBe
(
"
Another room
"
);
expect
(
els
[
2
].
textContent
).
toBe
(
"
Bookmark with a very very long name that will be shortened
"
);
expect
(
els
[
3
].
textContent
).
toBe
(
"
noname@conference.shakespeare.lit
"
);
expect
(
els
[
4
].
textContent
).
toBe
(
"
The Play's the Thing
"
);
spyOn
(
window
,
'
confirm
'
).
and
.
returnValue
(
true
);
document
.
querySelector
(
'
#chatrooms .bookmarks.rooms-list .room-item:nth-child(2) a:nth-child(2)
'
).
click
();
expect
(
window
.
confirm
).
toHaveBeenCalled
();
return
test_utils
.
waitUntil
(()
=>
document
.
querySelectorAll
(
'
#chatrooms div.bookmarks.rooms-list .room-item
'
).
length
===
4
,
300
)
}).
then
(()
=>
{
const
els
=
document
.
querySelectorAll
(
'
#chatrooms div.bookmarks.rooms-list .room-item a.list-item-link
'
);
expect
(
els
[
0
].
textContent
).
toBe
(
"
1st Bookmark
"
);
expect
(
els
[
1
].
textContent
).
toBe
(
"
Bookmark with a very very long name that will be shortened
"
);
expect
(
els
[
2
].
textContent
).
toBe
(
"
noname@conference.shakespeare.lit
"
);
expect
(
els
[
3
].
textContent
).
toBe
(
"
The Play's the Thing
"
);
done
();
}).
catch
(
_
.
partial
(
console
.
error
,
_
));
});
await
test_utils
.
waitUntil
(()
=>
document
.
querySelectorAll
(
'
#chatrooms div.bookmarks.rooms-list .room-item
'
).
length
);
expect
(
document
.
querySelectorAll
(
'
#chatrooms div.bookmarks.rooms-list .room-item
'
).
length
).
toBe
(
5
);
let
els
=
document
.
querySelectorAll
(
'
#chatrooms div.bookmarks.rooms-list .room-item a.list-item-link
'
);
expect
(
els
[
0
].
textContent
).
toBe
(
"
1st Bookmark
"
);
expect
(
els
[
1
].
textContent
).
toBe
(
"
Another room
"
);
expect
(
els
[
2
].
textContent
).
toBe
(
"
Bookmark with a very very long name that will be shortened
"
);
expect
(
els
[
3
].
textContent
).
toBe
(
"
noname@conference.shakespeare.lit
"
);
expect
(
els
[
4
].
textContent
).
toBe
(
"
The Play's the Thing
"
);
spyOn
(
window
,
'
confirm
'
).
and
.
returnValue
(
true
);
document
.
querySelector
(
'
#chatrooms .bookmarks.rooms-list .room-item:nth-child(2) a:nth-child(2)
'
).
click
();
expect
(
window
.
confirm
).
toHaveBeenCalled
();
await
test_utils
.
waitUntil
(()
=>
document
.
querySelectorAll
(
'
#chatrooms div.bookmarks.rooms-list .room-item
'
).
length
===
4
)
els
=
document
.
querySelectorAll
(
'
#chatrooms div.bookmarks.rooms-list .room-item a.list-item-link
'
);
expect
(
els
[
0
].
textContent
).
toBe
(
"
1st Bookmark
"
);
expect
(
els
[
1
].
textContent
).
toBe
(
"
Bookmark with a very very long name that will be shortened
"
);
expect
(
els
[
2
].
textContent
).
toBe
(
"
noname@conference.shakespeare.lit
"
);
expect
(
els
[
3
].
textContent
).
toBe
(
"
The Play's the Thing
"
);
done
();
}));
it
(
"
remembers the toggle state of the bookmarks list
"
,
mock
.
initConverseWithPromises
(
[
'
send
'
],
[
'
rosterGroupsFetched
'
],
{},
function
(
done
,
_converse
)
{
[
'
send
'
],
[
'
rosterGroupsFetched
'
],
{},
async
function
(
done
,
_converse
)
{
test_utils
.
openControlBox
();
test_utils
.
waitUntilDiscoConfirmed
(
await
test_utils
.
waitUntilDiscoConfirmed
(
_converse
,
_converse
.
bare_jid
,
[{
'
category
'
:
'
pubsub
'
,
'
type
'
:
'
pep
'
}],
[
'
http://jabber.org/protocol/pubsub#publish-options
'
]
).
then
(
function
()
{
var
IQ_id
;
expect
(
_
.
filter
(
_converse
.
connection
.
send
.
calls
.
all
(),
function
(
call
)
{
var
stanza
=
call
.
args
[
0
];
if
(
!
(
stanza
instanceof
Element
)
||
stanza
.
nodeName
!==
'
iq
'
)
{
return
;
}
// XXX: Wrapping in a div is a workaround for PhantomJS
var
div
=
document
.
createElement
(
'
div
'
);
div
.
appendChild
(
stanza
);
if
(
div
.
innerHTML
===
'
<iq from="dummy@localhost/resource" type="get"
'
+
'
xmlns="jabber:client" id="
'
+
stanza
.
getAttribute
(
'
id
'
)
+
'
">
'
+
'
<pubsub xmlns="http://jabber.org/protocol/pubsub">
'
+
'
<items node="storage:bookmarks"></items>
'
+
'
</pubsub>
'
+
'
</iq>
'
)
{
IQ_id
=
stanza
.
getAttribute
(
'
id
'
);
return
true
;
);
let
IQ_id
;
const
call
=
await
test_utils
.
waitUntil
(()
=>
_
.
filter
(
_converse
.
connection
.
send
.
calls
.
all
(),
call
=>
{
const
stanza
=
call
.
args
[
0
];
if
(
!
(
stanza
instanceof
Element
)
||
stanza
.
nodeName
!==
'
iq
'
)
{
return
;
}
if
(
sizzle
(
'
items[node="storage:bookmarks"]
'
,
stanza
).
length
)
{
IQ_id
=
stanza
.
getAttribute
(
'
id
'
);
return
true
;
}
}
}).
length
).
toBe
(
1
);
).
pop
()
);
expect
(
Strophe
.
serialize
(
call
.
args
[
0
])).
toBe
(
`<iq from="dummy@localhost/resource" id="
${
IQ_id
}
" type="get" xmlns="jabber:client">`
+
'
<pubsub xmlns="http://jabber.org/protocol/pubsub">
'
+
'
<items node="storage:bookmarks"/>
'
+
'
</pubsub>
'
+
'
</iq>
'
);
var
stanza
=
$iq
({
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
result
'
,
'
id
'
:
IQ_id
})
.
c
(
'
pubsub
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
PUBSUB
})
.
c
(
'
items
'
,
{
'
node
'
:
'
storage:bookmarks
'
})
.
c
(
'
item
'
,
{
'
id
'
:
'
current
'
})
.
c
(
'
storage
'
,
{
'
xmlns
'
:
'
storage:bookmarks
'
});
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
const
stanza
=
$iq
({
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
result
'
,
'
id
'
:
IQ_id
})
.
c
(
'
pubsub
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
PUBSUB
})
.
c
(
'
items
'
,
{
'
node
'
:
'
storage:bookmarks
'
})
.
c
(
'
item
'
,
{
'
id
'
:
'
current
'
})
.
c
(
'
storage
'
,
{
'
xmlns
'
:
'
storage:bookmarks
'
});
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
_converse
.
bookmarks
.
create
({
'
jid
'
:
'
theplay@conference.shakespeare.lit
'
,
'
autojoin
'
:
false
,
'
name
'
:
'
The Play
'
,
'
nick
'
:
''
});
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
);
$
(
'
#chatrooms .bookmarks-toggle
'
)[
0
].
click
();
expect
(
$
(
'
#chatrooms .bookmarks.rooms-list
'
).
hasClass
(
'
collapsed
'
)).
toBeTruthy
();
expect
(
_converse
.
bookmarksview
.
list_model
.
get
(
'
toggle-state
'
)).
toBe
(
_converse
.
CLOSED
);
$
(
'
#chatrooms .bookmarks-toggle
'
)[
0
].
click
();
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
);
done
();
});
_converse
.
bookmarks
.
create
({
'
jid
'
:
'
theplay@conference.shakespeare.lit
'
,
'
autojoin
'
:
false
,
'
name
'
:
'
The Play
'
,
'
nick
'
:
''
});
await
test_utils
.
waitUntil
(()
=>
$
(
'
#chatrooms .bookmarks.rooms-list .room-item:visible
'
).
length
);
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
);
$
(
'
#chatrooms .bookmarks-toggle
'
)[
0
].
click
();
expect
(
$
(
'
#chatrooms .bookmarks.rooms-list
'
).
hasClass
(
'
collapsed
'
)).
toBeTruthy
();
expect
(
_converse
.
bookmarksview
.
list_model
.
get
(
'
toggle-state
'
)).
toBe
(
_converse
.
CLOSED
);
$
(
'
#chatrooms .bookmarks-toggle
'
)[
0
].
click
();
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
);
done
();
}));
});
});
...
...
spec/chatbox.js
View file @
53b3f2d0
...
...
@@ -150,7 +150,8 @@
}));
it
(
"
can be trimmed to conserve space
"
,
mock
.
initConverseWithPromises
(
null
,
[
'
rosterGroupsFetched
'
],
{},
function
(
done
,
_converse
)
{
mock
.
initConverseWithPromises
(
null
,
[
'
rosterGroupsFetched
'
],
{},
async
function
(
done
,
_converse
)
{
spyOn
(
_converse
.
chatboxviews
,
'
trimChats
'
);
...
...
@@ -163,51 +164,47 @@
test_utils
.
openControlBox
();
let
online_contacts
;
var
i
,
jid
,
chatbox
,
chatboxview
,
trimmedview
;
let
jid
,
chatboxview
;
// openControlBox was called earlier, so the controlbox is
// visible, but no other chat boxes have been created.
expect
(
_converse
.
chatboxes
.
length
).
toEqual
(
1
);
expect
(
document
.
querySelectorAll
(
"
#conversejs .chatbox
"
).
length
).
toBe
(
1
);
// Controlbox is open
_converse
.
rosterview
.
update
();
// XXX: Hack to make sure $roster element is attached.
test_utils
.
waitUntil
(()
=>
_converse
.
rosterview
.
el
.
querySelectorAll
(
'
.roster-group li
'
).
length
)
.
then
(()
=>
{
// Test that they can be maximized again
online_contacts
=
_converse
.
rosterview
.
el
.
querySelectorAll
(
'
.roster-group .current-xmpp-contact a.open-chat
'
);
expect
(
online_contacts
.
length
).
toBe
(
15
);
for
(
i
=
0
;
i
<
online_contacts
.
length
;
i
++
)
{
const
el
=
online_contacts
[
i
];
el
.
click
();
}
return
test_utils
.
waitUntil
(()
=>
_converse
.
chatboxes
.
length
==
16
)
}).
then
(()
=>
{
expect
(
_converse
.
chatboxviews
.
trimChats
.
calls
.
count
()).
toBe
(
16
);
for
(
i
=
0
;
i
<
online_contacts
.
length
;
i
++
)
{
const
el
=
online_contacts
[
i
];
jid
=
_
.
trim
(
el
.
textContent
.
trim
()).
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
chatboxview
=
_converse
.
chatboxviews
.
get
(
jid
);
spyOn
(
chatboxview
,
'
minimize
'
).
and
.
callThrough
();
chatboxview
.
model
.
set
({
'
minimized
'
:
true
});
expect
(
trimmed_chatboxes
.
addChat
).
toHaveBeenCalled
();
expect
(
chatboxview
.
minimize
).
toHaveBeenCalled
();
}
return
test_utils
.
waitUntil
(()
=>
_converse
.
chatboxviews
.
keys
().
length
);
}).
then
(
function
()
{
var
key
=
_converse
.
chatboxviews
.
keys
()[
1
];
trimmedview
=
trimmed_chatboxes
.
get
(
key
);
chatbox
=
trimmedview
.
model
;
spyOn
(
chatbox
,
'
maximize
'
).
and
.
callThrough
();
spyOn
(
trimmedview
,
'
restore
'
).
and
.
callThrough
();
trimmedview
.
delegateEvents
();
trimmedview
.
el
.
querySelector
(
"
a.restore-chat
"
).
click
();
expect
(
trimmedview
.
restore
).
toHaveBeenCalled
();
expect
(
chatbox
.
maximize
).
toHaveBeenCalled
();
expect
(
_converse
.
chatboxviews
.
trimChats
.
calls
.
count
()).
toBe
(
17
);
done
();
});
await
test_utils
.
waitUntil
(()
=>
_converse
.
rosterview
.
el
.
querySelectorAll
(
'
.roster-group li
'
).
length
);
// Test that they can be maximized again
const
online_contacts
=
_converse
.
rosterview
.
el
.
querySelectorAll
(
'
.roster-group .current-xmpp-contact a.open-chat
'
);
expect
(
online_contacts
.
length
).
toBe
(
15
);
let
i
;
for
(
i
=
0
;
i
<
online_contacts
.
length
;
i
++
)
{
const
el
=
online_contacts
[
i
];
el
.
click
();
}
await
test_utils
.
waitUntil
(()
=>
_converse
.
chatboxes
.
length
==
16
);
expect
(
_converse
.
chatboxviews
.
trimChats
.
calls
.
count
()).
toBe
(
16
);
for
(
i
=
0
;
i
<
online_contacts
.
length
;
i
++
)
{
const
el
=
online_contacts
[
i
];
jid
=
_
.
trim
(
el
.
textContent
.
trim
()).
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
chatboxview
=
_converse
.
chatboxviews
.
get
(
jid
);
spyOn
(
chatboxview
,
'
minimize
'
).
and
.
callThrough
();
chatboxview
.
model
.
set
({
'
minimized
'
:
true
});
expect
(
trimmed_chatboxes
.
addChat
).
toHaveBeenCalled
();
expect
(
chatboxview
.
minimize
).
toHaveBeenCalled
();
}
await
test_utils
.
waitUntil
(()
=>
_converse
.
chatboxviews
.
keys
().
length
);
var
key
=
_converse
.
chatboxviews
.
keys
()[
1
];
const
trimmedview
=
trimmed_chatboxes
.
get
(
key
);
const
chatbox
=
trimmedview
.
model
;
spyOn
(
chatbox
,
'
maximize
'
).
and
.
callThrough
();
spyOn
(
trimmedview
,
'
restore
'
).
and
.
callThrough
();
trimmedview
.
delegateEvents
();
trimmedview
.
el
.
querySelector
(
"
a.restore-chat
"
).
click
();
expect
(
trimmedview
.
restore
).
toHaveBeenCalled
();
expect
(
chatbox
.
maximize
).
toHaveBeenCalled
();
expect
(
_converse
.
chatboxviews
.
trimChats
.
calls
.
count
()).
toBe
(
17
);
done
();
}));
it
(
"
can be opened in minimized mode initially
"
,
...
...
@@ -453,105 +450,82 @@
it
(
"
contains a button for inserting emojis
"
,
mock
.
initConverseWithPromises
(
null
,
[
'
rosterGroupsFetched
'
,
'
chatBoxesFetched
'
],
{},
function
(
done
,
_converse
)
{
async
function
(
done
,
_converse
)
{
test_utils
.
createContacts
(
_converse
,
'
current
'
);
_converse
.
emit
(
'
rosterContactsFetched
'
);
test_utils
.
openControlBox
();
let
timeout
=
false
,
view
,
toolbar
;
const
contact_jid
=
mock
.
cur_names
[
2
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
)
.
then
(()
=>
{
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
toolbar
=
view
.
el
.
querySelector
(
'
ul.chat-toolbar
'
);
expect
(
toolbar
.
querySelectorAll
(
'
li.toggle-smiley
'
).
length
).
toBe
(
1
);
// Register spies
spyOn
(
view
,
'
toggleEmojiMenu
'
).
and
.
callThrough
();
spyOn
(
view
,
'
insertEmoji
'
).
and
.
callThrough
();
view
.
delegateEvents
();
// We need to rebind all events otherwise our spy won't be called
toolbar
.
querySelector
(
'
li.toggle-smiley
'
).
click
();
return
test_utils
.
waitUntil
(()
=>
u
.
isVisible
(
view
.
el
.
querySelector
(
'
.toggle-smiley .emoji-picker-container
'
),
500
));
}).
then
(()
=>
{
var
picker
=
view
.
el
.
querySelector
(
'
.toggle-smiley .emoji-picker-container
'
);
var
items
=
picker
.
querySelectorAll
(
'
.emoji-picker li
'
);
items
[
0
].
click
()
expect
(
view
.
insertEmoji
).
toHaveBeenCalled
();
setTimeout
(
function
()
{
timeout
=
true
;
},
100
);
return
test_utils
.
waitUntil
(()
=>
timeout
,
500
);
}).
then
(()
=>
{
timeout
=
false
;
toolbar
.
querySelector
(
'
li.toggle-smiley
'
).
click
();
// Close the panel again
return
test_utils
.
waitUntil
(()
=>
!
view
.
el
.
querySelector
(
'
.toggle-smiley .toolbar-menu
'
).
offsetHeight
,
500
);
}).
then
(()
=>
{
setTimeout
(
function
()
{
timeout
=
true
;
},
100
);
return
test_utils
.
waitUntil
(()
=>
timeout
,
500
);
}).
then
(()
=>
{
toolbar
.
querySelector
(
'
li.toggle-smiley
'
).
click
();
expect
(
view
.
toggleEmojiMenu
).
toHaveBeenCalled
();
return
test_utils
.
waitUntil
(()
=>
u
.
isVisible
(
view
.
el
.
querySelector
(
'
.toggle-smiley .emoji-picker-container
'
)),
500
);
}).
then
(()
=>
{
var
nodes
=
view
.
el
.
querySelectorAll
(
'
.toggle-smiley ul li
'
);
nodes
[
nodes
.
length
-
1
].
click
();
expect
(
view
.
el
.
querySelector
(
'
textarea.chat-textarea
'
).
value
).
toBe
(
'
:grinning:
'
);
expect
(
view
.
insertEmoji
).
toHaveBeenCalled
();
done
();
}).
catch
(
_
.
partial
(
_converse
.
log
,
_
,
Strophe
.
LogLevel
.
FATAL
));
await
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
);
const
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
const
toolbar
=
view
.
el
.
querySelector
(
'
ul.chat-toolbar
'
);
expect
(
toolbar
.
querySelectorAll
(
'
li.toggle-smiley
'
).
length
).
toBe
(
1
);
// Register spies
spyOn
(
view
,
'
toggleEmojiMenu
'
).
and
.
callThrough
();
spyOn
(
view
,
'
insertEmoji
'
).
and
.
callThrough
();
view
.
delegateEvents
();
// We need to rebind all events otherwise our spy won't be called
toolbar
.
querySelector
(
'
li.toggle-smiley
'
).
click
();
await
test_utils
.
waitUntil
(()
=>
u
.
isVisible
(
view
.
el
.
querySelector
(
'
.toggle-smiley .emoji-picker-container
'
)));
var
picker
=
view
.
el
.
querySelector
(
'
.toggle-smiley .emoji-picker-container
'
);
var
items
=
picker
.
querySelectorAll
(
'
.emoji-picker li
'
);
items
[
0
].
click
()
expect
(
view
.
insertEmoji
).
toHaveBeenCalled
();
expect
(
view
.
el
.
querySelector
(
'
textarea.chat-textarea
'
).
value
).
toBe
(
'
:grinning:
'
);
toolbar
.
querySelector
(
'
li.toggle-smiley
'
).
click
();
// Close the panel again
done
();
}));
it
(
"
can contain a button for starting a call
"
,
mock
.
initConverseWithPromises
(
null
,
[
'
rosterGroupsFetched
'
,
'
chatBoxesFetched
'
],
{},
function
(
done
,
_converse
)
{
async
function
(
done
,
_converse
)
{
test_utils
.
createContacts
(
_converse
,
'
current
'
);
_converse
.
emit
(
'
rosterContactsFetched
'
);
test_utils
.
openControlBox
();
let
view
,
toolbar
,
call_button
;
let
toolbar
,
call_button
;
const
contact_jid
=
mock
.
cur_names
[
2
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
spyOn
(
_converse
,
'
emit
'
);
// First check that the button doesn't show if it's not enabled
// via "visible_toolbar_buttons"
_converse
.
visible_toolbar_buttons
.
call
=
false
;
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
)
.
then
(()
=>
{
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
toolbar
=
view
.
el
.
querySelector
(
'
ul.chat-toolbar
'
);
call_button
=
toolbar
.
querySelector
(
'
.toggle-call
'
);
expect
(
_
.
isNull
(
call_button
)).
toBeTruthy
();
view
.
close
();
// Now check that it's shown if enabled and that it emits
// callButtonClicked
_converse
.
visible_toolbar_buttons
.
call
=
true
;
// enable the button
return
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
);
}).
then
(()
=>
{
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
toolbar
=
view
.
el
.
querySelector
(
'
ul.chat-toolbar
'
);
call_button
=
toolbar
.
querySelector
(
'
.toggle-call
'
);
call_button
.
click
();
expect
(
_converse
.
emit
).
toHaveBeenCalledWith
(
'
callButtonClicked
'
,
jasmine
.
any
(
Object
));
done
();
});
await
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
);
let
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
toolbar
=
view
.
el
.
querySelector
(
'
ul.chat-toolbar
'
);
call_button
=
toolbar
.
querySelector
(
'
.toggle-call
'
);
expect
(
_
.
isNull
(
call_button
)).
toBeTruthy
();
view
.
close
();
// Now check that it's shown if enabled and that it emits
// callButtonClicked
_converse
.
visible_toolbar_buttons
.
call
=
true
;
// enable the button
await
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
);
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
toolbar
=
view
.
el
.
querySelector
(
'
ul.chat-toolbar
'
);
call_button
=
toolbar
.
querySelector
(
'
.toggle-call
'
);
call_button
.
click
();
expect
(
_converse
.
emit
).
toHaveBeenCalledWith
(
'
callButtonClicked
'
,
jasmine
.
any
(
Object
));
done
();
}));
});
describe
(
"
A Chat Status Notification
"
,
function
()
{
it
(
"
does not open a new chatbox
"
,
mock
.
initConverseWithPromises
(
null
,
[
'
rosterGroupsFetched
'
],
{},
function
(
done
,
_converse
)
{
mock
.
initConverseWithPromises
(
null
,
[
'
rosterGroupsFetched
'
],
{},
function
(
done
,
_converse
)
{
test_utils
.
createContacts
(
_converse
,
'
current
'
);
test_utils
.
openControlBox
();
spyOn
(
_converse
,
'
emit
'
);
var
sender_jid
=
mock
.
cur_names
[
1
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
const
sender_jid
=
mock
.
cur_names
[
1
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
// <composing> state
var
msg
=
$msg
({
const
msg
=
$msg
({
'
from
'
:
sender_jid
,
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
chat
'
,
...
...
spec/chatroom.js
View file @
53b3f2d0
...
...
@@ -2329,35 +2329,34 @@
}));
it
(
"
can be minimized by clicking a DOM element with class 'toggle-chatbox-button'
"
,
mock
.
initConverseWithPromises
(
null
,
[
'
rosterGroupsFetched
'
,
'
chatBoxesFetched
'
],
{},
function
(
done
,
_converse
)
{
mock
.
initConverseWithPromises
(
null
,
[
'
rosterGroupsFetched
'
,
'
chatBoxesFetched
'
],
{},
async
function
(
done
,
_converse
)
{
test_utils
.
openChatRoom
(
_converse
,
'
lounge
'
,
'
localhost
'
,
'
dummy
'
)
.
then
(()
=>
{
const
view
=
_converse
.
chatboxviews
.
get
(
'
lounge@localhost
'
),
trimmed_chatboxes
=
_converse
.
minimized_chats
;
await
test_utils
.
openChatRoom
(
_converse
,
'
lounge
'
,
'
localhost
'
,
'
dummy
'
);
const
view
=
_converse
.
chatboxviews
.
get
(
'
lounge@localhost
'
),
trimmed_chatboxes
=
_converse
.
minimized_chats
;
spyOn
(
view
,
'
minimize
'
).
and
.
callThrough
();
spyOn
(
view
,
'
maximize
'
).
and
.
callThrough
();
spyOn
(
_converse
,
'
emit
'
);
view
.
delegateEvents
();
// We need to rebind all events otherwise our spy won't be called
view
.
el
.
querySelector
(
'
.toggle-chatbox-button
'
).
click
();
expect
(
view
.
minimize
).
toHaveBeenCalled
();
expect
(
_converse
.
emit
).
toHaveBeenCalledWith
(
'
chatBoxMinimized
'
,
jasmine
.
any
(
Object
));
expect
(
u
.
isVisible
(
view
.
el
)).
toBeFalsy
();
expect
(
view
.
model
.
get
(
'
minimized
'
)).
toBeTruthy
();
expect
(
view
.
minimize
).
toHaveBeenCalled
();
var
trimmedview
=
trimmed_chatboxes
.
get
(
view
.
model
.
get
(
'
id
'
));
trimmedview
.
el
.
querySelector
(
"
a.restore-chat
"
).
click
();
expect
(
view
.
maximize
).
toHaveBeenCalled
();
expect
(
_converse
.
emit
).
toHaveBeenCalledWith
(
'
chatBoxMaximized
'
,
jasmine
.
any
(
Object
));
expect
(
view
.
model
.
get
(
'
minimized
'
)).
toBeFalsy
();
expect
(
_converse
.
emit
.
calls
.
count
(),
3
);
done
();
spyOn
(
view
,
'
minimize
'
).
and
.
callThrough
();
spyOn
(
view
,
'
maximize
'
).
and
.
callThrough
();
spyOn
(
_converse
,
'
emit
'
);
view
.
delegateEvents
();
// We need to rebind all events otherwise our spy won't be called
view
.
el
.
querySelector
(
'
.toggle-chatbox-button
'
).
click
();
expect
(
view
.
minimize
).
toHaveBeenCalled
();
expect
(
_converse
.
emit
).
toHaveBeenCalledWith
(
'
chatBoxMinimized
'
,
jasmine
.
any
(
Object
));
expect
(
u
.
isVisible
(
view
.
el
)).
toBeFalsy
();
expect
(
view
.
model
.
get
(
'
minimized
'
)).
toBeTruthy
();
expect
(
view
.
minimize
).
toHaveBeenCalled
();
await
test_utils
.
waitUntil
(()
=>
trimmed_chatboxes
.
get
(
view
.
model
.
get
(
'
id
'
)));
const
trimmedview
=
trimmed_chatboxes
.
get
(
view
.
model
.
get
(
'
id
'
));
trimmedview
.
el
.
querySelector
(
"
a.restore-chat
"
).
click
();
expect
(
view
.
maximize
).
toHaveBeenCalled
();
expect
(
_converse
.
emit
).
toHaveBeenCalledWith
(
'
chatBoxMaximized
'
,
jasmine
.
any
(
Object
));
expect
(
view
.
model
.
get
(
'
minimized
'
)).
toBeFalsy
();
expect
(
_converse
.
emit
.
calls
.
count
(),
3
);
done
();
});
}));
it
(
"
can be closed again by clicking a DOM element with class 'close-chatbox-button'
"
,
...
...
spec/http-file-upload.js
View file @
53b3f2d0
...
...
@@ -14,159 +14,159 @@
describe
(
"
Discovering support
"
,
function
()
{
it
(
"
is done automatically
"
,
mock
.
initConverseWithAsync
(
function
(
done
,
_converse
)
{
it
(
"
is done automatically
"
,
mock
.
initConverseWithAsync
(
async
function
(
done
,
_converse
)
{
var
IQ_stanzas
=
_converse
.
connection
.
IQ_stanzas
;
var
IQ_ids
=
_converse
.
connection
.
IQ_ids
;
test_utils
.
waitUntilDiscoConfirmed
(
_converse
,
_converse
.
bare_jid
,
[],
[]).
then
(
function
()
{
test_utils
.
waitUntil
(
function
()
{
await
test_utils
.
waitUntilDiscoConfirmed
(
_converse
,
_converse
.
bare_jid
,
[],
[]);
await
test_utils
.
waitUntil
(()
=>
_
.
filter
(
IQ_stanzas
,
iq
=>
iq
.
nodeTree
.
querySelector
(
'
iq[to="localhost"] query[xmlns="http://jabber.org/protocol/disco#info"]
'
)).
length
);
/* <iq type='result'
* from='plays.shakespeare.lit'
* to='romeo@montague.net/orchard'
* id='info1'>
* <query xmlns='http://jabber.org/protocol/disco#info'>
* <identity
* category='server'
* type='im'/>
* <feature var='http://jabber.org/protocol/disco#info'/>
* <feature var='http://jabber.org/protocol/disco#items'/>
* </query>
* </iq>
*/
let
stanza
=
_
.
find
(
IQ_stanzas
,
function
(
iq
)
{
return
iq
.
nodeTree
.
querySelector
(
'
iq[to="localhost"] query[xmlns="http://jabber.org/protocol/disco#info"]
'
);
});
var
info_IQ_id
=
IQ_ids
[
IQ_stanzas
.
indexOf
(
stanza
)];
stanza
=
$iq
({
'
type
'
:
'
result
'
,
'
from
'
:
'
localhost
'
,
'
to
'
:
'
dummy@localhost/resource
'
,
'
id
'
:
info_IQ_id
}).
c
(
'
query
'
,
{
'
xmlns
'
:
'
http://jabber.org/protocol/disco#info
'
})
.
c
(
'
identity
'
,
{
'
category
'
:
'
server
'
,
'
type
'
:
'
im
'
}).
up
()
.
c
(
'
feature
'
,
{
'
var
'
:
'
http://jabber.org/protocol/disco#info
'
}).
up
()
.
c
(
'
feature
'
,
{
'
var
'
:
'
http://jabber.org/protocol/disco#items
'
});
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
const
entities
=
await
_converse
.
api
.
disco
.
entities
.
get
();
expect
(
entities
.
length
).
toBe
(
2
);
expect
(
_
.
includes
(
entities
.
pluck
(
'
jid
'
),
'
localhost
'
)).
toBe
(
true
);
expect
(
_
.
includes
(
entities
.
pluck
(
'
jid
'
),
'
dummy@localhost
'
)).
toBe
(
true
);
expect
(
entities
.
get
(
_converse
.
domain
).
features
.
length
).
toBe
(
2
);
expect
(
entities
.
get
(
_converse
.
domain
).
identities
.
length
).
toBe
(
1
);
// Converse.js sees that the entity has a disco#items feature,
// so it will make a query for it.
await
test_utils
.
waitUntil
(()
=>
_
.
filter
(
IQ_stanzas
,
iq
=>
iq
.
nodeTree
.
querySelector
(
'
iq[to="localhost"] query[xmlns="http://jabber.org/protocol/disco#items"]
'
)
).
length
);
/* <iq from='montague.tld'
* id='step_01'
* to='romeo@montague.tld/garden'
* type='result'>
* <query xmlns='http://jabber.org/protocol/disco#items'>
* <item jid='upload.montague.tld' name='HTTP File Upload' />
* <item jid='conference.montague.tld' name='Chatroom Service' />
* </query>
* </iq>
*/
stanza
=
_
.
find
(
IQ_stanzas
,
function
(
iq
)
{
return
iq
.
nodeTree
.
querySelector
(
'
iq[to="localhost"] query[xmlns="http://jabber.org/protocol/disco#items"]
'
);
});
var
items_IQ_id
=
IQ_ids
[
IQ_stanzas
.
indexOf
(
stanza
)];
stanza
=
$iq
({
'
type
'
:
'
result
'
,
'
from
'
:
'
localhost
'
,
'
to
'
:
'
dummy@localhost/resource
'
,
'
id
'
:
items_IQ_id
}).
c
(
'
query
'
,
{
'
xmlns
'
:
'
http://jabber.org/protocol/disco#items
'
})
.
c
(
'
item
'
,
{
'
jid
'
:
'
upload.localhost
'
,
'
name
'
:
'
HTTP File Upload
'
});
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
_converse
.
api
.
disco
.
entities
.
get
().
then
(
function
(
entities
)
{
expect
(
entities
.
length
).
toBe
(
2
);
expect
(
entities
.
get
(
'
localhost
'
).
items
.
length
).
toBe
(
1
);
return
test_utils
.
waitUntil
(
function
()
{
// Converse.js sees that the entity has a disco#info feature,
// so it will make a query for it.
return
_
.
filter
(
IQ_stanzas
,
function
(
iq
)
{
return
iq
.
nodeTree
.
querySelector
(
'
iq[to="localhost"] query[xmlns="http://jabber.org/protocol/disco#info"]
'
);
}).
length
>
0
;
},
300
).
then
(
function
()
{
/* <iq type='result'
* from='plays.shakespeare.lit'
* to='romeo@montague.net/orchard'
* id='info1'>
* <query xmlns='http://jabber.org/protocol/disco#info'>
* <identity
* category='server'
* type='im'/>
* <feature var='http://jabber.org/protocol/disco#info'/>
* <feature var='http://jabber.org/protocol/disco#items'/>
* </query>
* </iq>
*/
var
stanza
=
_
.
find
(
IQ_stanzas
,
function
(
iq
)
{
return
iq
.
nodeTree
.
querySelector
(
'
iq[to="localhost"] query[xmlns="http://jabber.org/protocol/disco#info"]
'
);
});
var
info_IQ_id
=
IQ_ids
[
IQ_stanzas
.
indexOf
(
stanza
)];
stanza
=
$iq
({
'
type
'
:
'
result
'
,
'
from
'
:
'
localhost
'
,
'
to
'
:
'
dummy@localhost/resource
'
,
'
id
'
:
info_IQ_id
}).
c
(
'
query
'
,
{
'
xmlns
'
:
'
http://jabber.org/protocol/disco#info
'
})
.
c
(
'
identity
'
,
{
'
category
'
:
'
server
'
,
'
type
'
:
'
im
'
}).
up
()
.
c
(
'
feature
'
,
{
'
var
'
:
'
http://jabber.org/protocol/disco#info
'
}).
up
()
.
c
(
'
feature
'
,
{
'
var
'
:
'
http://jabber.org/protocol/disco#items
'
});
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
_converse
.
api
.
disco
.
entities
.
get
().
then
(
function
(
entities
)
{
expect
(
entities
.
length
).
toBe
(
2
);
expect
(
_
.
includes
(
entities
.
pluck
(
'
jid
'
),
'
localhost
'
)).
toBe
(
true
);
expect
(
_
.
includes
(
entities
.
pluck
(
'
jid
'
),
'
dummy@localhost
'
)).
toBe
(
true
);
expect
(
entities
.
get
(
_converse
.
domain
).
features
.
length
).
toBe
(
2
);
expect
(
entities
.
get
(
_converse
.
domain
).
identities
.
length
).
toBe
(
1
);
return
test_utils
.
waitUntil
(
function
()
{
// Converse.js sees that the entity has a disco#items feature,
// so it will make a query for it.
return
_
.
filter
(
IQ_stanzas
,
function
(
iq
)
{
return
iq
.
nodeTree
.
querySelector
(
'
iq[to="localhost"] query[xmlns="http://jabber.org/protocol/disco#items"]
'
);
}).
length
>
0
;
},
300
);
});
}).
then
(
function
()
{
/* <iq from='montague.tld'
* id='step_01'
* to='romeo@montague.tld/garden'
* type='result'>
* <query xmlns='http://jabber.org/protocol/disco#items'>
* <item jid='upload.montague.tld' name='HTTP File Upload' />
* <item jid='conference.montague.tld' name='Chatroom Service' />
* </query>
* </iq>
*/
var
stanza
=
_
.
find
(
IQ_stanzas
,
function
(
iq
)
{
return
iq
.
nodeTree
.
querySelector
(
'
iq[to="localhost"] query[xmlns="http://jabber.org/protocol/disco#items"]
'
);
});
var
items_IQ_id
=
IQ_ids
[
IQ_stanzas
.
indexOf
(
stanza
)];
stanza
=
$iq
({
'
type
'
:
'
result
'
,
'
from
'
:
'
localhost
'
,
'
to
'
:
'
dummy@localhost/resource
'
,
'
id
'
:
items_IQ_id
}).
c
(
'
query
'
,
{
'
xmlns
'
:
'
http://jabber.org/protocol/disco#items
'
})
.
c
(
'
item
'
,
{
'
jid
'
:
'
upload.localhost
'
,
'
name
'
:
'
HTTP File Upload
'
});
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
_converse
.
api
.
disco
.
entities
.
get
().
then
(
function
(
entities
)
{
expect
(
entities
.
length
).
toBe
(
2
);
expect
(
entities
.
get
(
'
localhost
'
).
items
.
length
).
toBe
(
1
);
return
test_utils
.
waitUntil
(
function
()
{
// Converse.js sees that the entity has a disco#info feature,
// so it will make a query for it.
return
_
.
filter
(
IQ_stanzas
,
function
(
iq
)
{
return
iq
.
nodeTree
.
querySelector
(
'
iq[to="upload.localhost"] query[xmlns="http://jabber.org/protocol/disco#info"]
'
);
}).
length
>
0
;
},
300
);
});
}).
then
(
function
()
{
var
stanza
=
_
.
find
(
IQ_stanzas
,
function
(
iq
)
{
return
iq
.
nodeTree
.
querySelector
(
'
iq[to="upload.localhost"] query[xmlns="http://jabber.org/protocol/disco#info"]
'
);
});
var
IQ_id
=
IQ_ids
[
IQ_stanzas
.
indexOf
(
stanza
)];
expect
(
stanza
.
toLocaleString
()).
toBe
(
`<iq from="dummy@localhost/resource" id="`
+
IQ_id
+
`" to="upload.localhost" type="get" xmlns="jabber:client">`
+
`<query xmlns="http://jabber.org/protocol/disco#info"/>`
+
`</iq>`
);
// Upload service responds and reports a maximum file size of 5MiB
/* <iq from='upload.montague.tld'
* id='step_02'
* to='romeo@montague.tld/garden'
* type='result'>
* <query xmlns='http://jabber.org/protocol/disco#info'>
* <identity category='store'
* type='file'
* name='HTTP File Upload' />
* <feature var='urn:xmpp:http:upload:0' />
* <x type='result' xmlns='jabber:x:data'>
* <field var='FORM_TYPE' type='hidden'>
* <value>urn:xmpp:http:upload:0</value>
* </field>
* <field var='max-file-size'>
* <value>5242880</value>
* </field>
* </x>
* </query>
* </iq>
*/
stanza
=
$iq
({
'
type
'
:
'
result
'
,
'
to
'
:
'
dummy@localhost/resource
'
,
'
id
'
:
IQ_id
,
'
from
'
:
'
upload.localhost
'
})
.
c
(
'
query
'
,
{
'
xmlns
'
:
'
http://jabber.org/protocol/disco#info
'
})
.
c
(
'
identity
'
,
{
'
category
'
:
'
store
'
,
'
type
'
:
'
file
'
,
'
name
'
:
'
HTTP File Upload
'
}).
up
()
.
c
(
'
feature
'
,
{
'
var
'
:
'
urn:xmpp:http:upload:0
'
}).
up
()
.
c
(
'
x
'
,
{
'
type
'
:
'
result
'
,
'
xmlns
'
:
'
jabber:x:data
'
})
.
c
(
'
field
'
,
{
'
var
'
:
'
FORM_TYPE
'
,
'
type
'
:
'
hidden
'
})
.
c
(
'
value
'
).
t
(
'
urn:xmpp:http:upload:0
'
).
up
().
up
()
.
c
(
'
field
'
,
{
'
var
'
:
'
max-file-size
'
})
.
c
(
'
value
'
).
t
(
'
5242880
'
);
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
}).
length
>
0
;
},
300
);
});
_converse
.
api
.
disco
.
entities
.
get
().
then
(
function
(
entities
)
{
expect
(
entities
.
get
(
'
localhost
'
).
items
.
get
(
'
upload.localhost
'
).
identities
.
where
({
'
category
'
:
'
store
'
}).
length
).
toBe
(
1
);
_converse
.
api
.
disco
.
supports
(
Strophe
.
NS
.
HTTPUPLOAD
,
_converse
.
domain
).
then
(
function
(
result
)
{
expect
(
result
.
length
).
toBe
(
1
);
expect
(
result
[
0
].
get
(
'
jid
'
)).
toBe
(
'
upload.localhost
'
);
expect
(
result
[
0
].
dataforms
.
where
({
'
FORM_TYPE
'
:
{
value
:
"
urn:xmpp:http:upload:0
"
,
type
:
"
hidden
"
}}).
length
).
toBe
(
1
);
done
();
}
);
}).
catch
(
_
.
partial
(
_converse
.
log
,
_
,
Strophe
.
LogLevel
.
FATAL
));
})
})
stanza
=
await
test_utils
.
waitUntil
(()
=>
_
.
filter
(
IQ_stanzas
,
iq
=>
iq
.
nodeTree
.
querySelector
(
'
iq[to="upload.localhost"] query[xmlns="http://jabber.org/protocol/disco#info"]
'
)
).
pop
()
);
const
IQ_id
=
IQ_ids
[
IQ_stanzas
.
indexOf
(
stanza
)];
expect
(
stanza
.
toLocaleString
()).
toBe
(
`<iq from="dummy@localhost/resource" id="`
+
IQ_id
+
`" to="upload.localhost" type="get" xmlns="jabber:client">`
+
`<query xmlns="http://jabber.org/protocol/disco#info"/>`
+
`</iq>`
);
// Upload service responds and reports a maximum file size of 5MiB
/* <iq from='upload.montague.tld'
* id='step_02'
* to='romeo@montague.tld/garden'
* type='result'>
* <query xmlns='http://jabber.org/protocol/disco#info'>
* <identity category='store'
* type='file'
* name='HTTP File Upload' />
* <feature var='urn:xmpp:http:upload:0' />
* <x type='result' xmlns='jabber:x:data'>
* <field var='FORM_TYPE' type='hidden'>
* <value>urn:xmpp:http:upload:0</value>
* </field>
* <field var='max-file-size'>
* <value>5242880</value>
* </field>
* </x>
* </query>
* </iq>
*/
stanza
=
$iq
({
'
type
'
:
'
result
'
,
'
to
'
:
'
dummy@localhost/resource
'
,
'
id
'
:
IQ_id
,
'
from
'
:
'
upload.localhost
'
})
.
c
(
'
query
'
,
{
'
xmlns
'
:
'
http://jabber.org/protocol/disco#info
'
})
.
c
(
'
identity
'
,
{
'
category
'
:
'
store
'
,
'
type
'
:
'
file
'
,
'
name
'
:
'
HTTP File Upload
'
}).
up
()
.
c
(
'
feature
'
,
{
'
var
'
:
'
urn:xmpp:http:upload:0
'
}).
up
()
.
c
(
'
x
'
,
{
'
type
'
:
'
result
'
,
'
xmlns
'
:
'
jabber:x:data
'
})
.
c
(
'
field
'
,
{
'
var
'
:
'
FORM_TYPE
'
,
'
type
'
:
'
hidden
'
})
.
c
(
'
value
'
).
t
(
'
urn:xmpp:http:upload:0
'
).
up
().
up
()
.
c
(
'
field
'
,
{
'
var
'
:
'
max-file-size
'
})
.
c
(
'
value
'
).
t
(
'
5242880
'
);
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
_converse
.
api
.
disco
.
entities
.
get
().
then
(
function
(
entities
)
{
expect
(
entities
.
get
(
'
localhost
'
).
items
.
get
(
'
upload.localhost
'
).
identities
.
where
({
'
category
'
:
'
store
'
}).
length
).
toBe
(
1
);
_converse
.
api
.
disco
.
supports
(
Strophe
.
NS
.
HTTPUPLOAD
,
_converse
.
domain
).
then
(
function
(
result
)
{
expect
(
result
.
length
).
toBe
(
1
);
expect
(
result
[
0
].
get
(
'
jid
'
)).
toBe
(
'
upload.localhost
'
);
expect
(
result
[
0
].
dataforms
.
where
({
'
FORM_TYPE
'
:
{
value
:
"
urn:xmpp:http:upload:0
"
,
type
:
"
hidden
"
}}).
length
).
toBe
(
1
);
done
();
}
);
}).
catch
(
_
.
partial
(
_converse
.
log
,
_
,
Strophe
.
LogLevel
.
FATAL
));
}));
});
...
...
@@ -474,128 +474,124 @@
done
();
}));
it
(
"
shows an error message if the file is too large
"
,
mock
.
initConverseWithAsync
(
function
(
done
,
_converse
)
{
it
(
"
shows an error message if the file is too large
"
,
mock
.
initConverseWithAsync
(
async
function
(
done
,
_converse
)
{
const
IQ_stanzas
=
_converse
.
connection
.
IQ_stanzas
;
const
IQ_ids
=
_converse
.
connection
.
IQ_ids
;
const
send_backup
=
XMLHttpRequest
.
prototype
.
send
;
let
view
,
contact_jid
;
test_utils
.
waitUntilDiscoConfirmed
(
_converse
,
_converse
.
bare_jid
,
[],
[])
.
then
(()
=>
test_utils
.
waitUntil
(()
=>
_
.
filter
(
IQ_stanzas
,
(
iq
)
=>
iq
.
nodeTree
.
querySelector
(
'
iq[to="localhost"] query[xmlns="http://jabber.org/protocol/disco#info"]
'
)).
length
)).
then
(()
=>
{
var
stanza
=
_
.
find
(
IQ_stanzas
,
function
(
iq
)
{
return
iq
.
nodeTree
.
querySelector
(
'
iq[to="localhost"] query[xmlns="http://jabber.org/protocol/disco#info"]
'
);
});
var
info_IQ_id
=
IQ_ids
[
IQ_stanzas
.
indexOf
(
stanza
)];
stanza
=
$iq
({
'
type
'
:
'
result
'
,
'
from
'
:
'
localhost
'
,
'
to
'
:
'
dummy@localhost/resource
'
,
'
id
'
:
info_IQ_id
}).
c
(
'
query
'
,
{
'
xmlns
'
:
'
http://jabber.org/protocol/disco#info
'
})
.
c
(
'
identity
'
,
{
'
category
'
:
'
server
'
,
'
type
'
:
'
im
'
}).
up
()
.
c
(
'
feature
'
,
{
'
var
'
:
'
http://jabber.org/protocol/disco#info
'
}).
up
()
.
c
(
'
feature
'
,
{
'
var
'
:
'
http://jabber.org/protocol/disco#items
'
});
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
return
_converse
.
api
.
disco
.
entities
.
get
();
}).
then
(
function
(
entities
)
{
expect
(
entities
.
length
).
toBe
(
2
);
expect
(
_
.
includes
(
entities
.
pluck
(
'
jid
'
),
'
localhost
'
)).
toBe
(
true
);
expect
(
_
.
includes
(
entities
.
pluck
(
'
jid
'
),
'
dummy@localhost
'
)).
toBe
(
true
);
expect
(
entities
.
get
(
_converse
.
domain
).
features
.
length
).
toBe
(
2
);
expect
(
entities
.
get
(
_converse
.
domain
).
identities
.
length
).
toBe
(
1
);
return
test_utils
.
waitUntil
(
function
()
{
// Converse.js sees that the entity has a disco#items feature,
// so it will make a query for it.
return
_
.
filter
(
IQ_stanzas
,
function
(
iq
)
{
return
iq
.
nodeTree
.
querySelector
(
'
iq[to="localhost"] query[xmlns="http://jabber.org/protocol/disco#items"]
'
);
}).
length
>
0
;
},
300
);
}).
then
(
function
()
{
var
stanza
=
_
.
find
(
IQ_stanzas
,
function
(
iq
)
{
await
test_utils
.
waitUntilDiscoConfirmed
(
_converse
,
_converse
.
bare_jid
,
[],
[]);
await
test_utils
.
waitUntil
(()
=>
_
.
filter
(
IQ_stanzas
,
iq
=>
iq
.
nodeTree
.
querySelector
(
'
iq[to="localhost"] query[xmlns="http://jabber.org/protocol/disco#info"]
'
)).
length
);
var
stanza
=
_
.
find
(
IQ_stanzas
,
function
(
iq
)
{
return
iq
.
nodeTree
.
querySelector
(
'
iq[to="localhost"] query[xmlns="http://jabber.org/protocol/disco#info"]
'
);
});
var
info_IQ_id
=
IQ_ids
[
IQ_stanzas
.
indexOf
(
stanza
)];
stanza
=
$iq
({
'
type
'
:
'
result
'
,
'
from
'
:
'
localhost
'
,
'
to
'
:
'
dummy@localhost/resource
'
,
'
id
'
:
info_IQ_id
}).
c
(
'
query
'
,
{
'
xmlns
'
:
'
http://jabber.org/protocol/disco#info
'
})
.
c
(
'
identity
'
,
{
'
category
'
:
'
server
'
,
'
type
'
:
'
im
'
}).
up
()
.
c
(
'
feature
'
,
{
'
var
'
:
'
http://jabber.org/protocol/disco#info
'
}).
up
()
.
c
(
'
feature
'
,
{
'
var
'
:
'
http://jabber.org/protocol/disco#items
'
});
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
let
entities
=
await
_converse
.
api
.
disco
.
entities
.
get
();
expect
(
entities
.
length
).
toBe
(
2
);
expect
(
_
.
includes
(
entities
.
pluck
(
'
jid
'
),
'
localhost
'
)).
toBe
(
true
);
expect
(
_
.
includes
(
entities
.
pluck
(
'
jid
'
),
'
dummy@localhost
'
)).
toBe
(
true
);
expect
(
entities
.
get
(
_converse
.
domain
).
features
.
length
).
toBe
(
2
);
expect
(
entities
.
get
(
_converse
.
domain
).
identities
.
length
).
toBe
(
1
);
await
test_utils
.
waitUntil
(
function
()
{
// Converse.js sees that the entity has a disco#items feature,
// so it will make a query for it.
return
_
.
filter
(
IQ_stanzas
,
function
(
iq
)
{
return
iq
.
nodeTree
.
querySelector
(
'
iq[to="localhost"] query[xmlns="http://jabber.org/protocol/disco#items"]
'
);
});
var
items_IQ_id
=
IQ_ids
[
IQ_stanzas
.
indexOf
(
stanza
)]
;
stanza
=
$iq
({
'
type
'
:
'
result
'
,
'
from
'
:
'
localhost
'
,
'
to
'
:
'
dummy@localhost/resource
'
,
'
id
'
:
items_IQ_id
}).
c
(
'
query
'
,
{
'
xmlns
'
:
'
http://jabber.org/protocol/disco#items
'
})
.
c
(
'
item
'
,
{
'
jid
'
:
'
upload.
localhost
'
,
'
name
'
:
'
HTTP File Upload
'
});
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
_converse
.
api
.
disco
.
entities
.
get
().
then
(
function
(
entities
)
{
expect
(
entities
.
length
).
toBe
(
2
);
expect
(
entities
.
get
(
'
localhost
'
).
items
.
length
).
toBe
(
1
);
return
test_utils
.
waitUntil
(
function
()
{
// Converse.js sees that the entity has a disco#info feature,
// so it will make a query for it.
return
_
.
filter
(
IQ_stanzas
,
function
(
iq
)
{
return
iq
.
nodeTree
.
querySelector
(
'
iq[to="upload.localhost"] query[xmlns="http://jabber.org/protocol/disco#info"]
'
);
}).
length
>
0
;
},
300
);
});
}).
then
(
function
()
{
var
stanza
=
_
.
find
(
IQ_stanzas
,
function
(
iq
)
{
})
.
length
>
0
;
},
300
)
;
stanza
=
_
.
find
(
IQ_stanzas
,
function
(
iq
)
{
return
iq
.
nodeTree
.
querySelector
(
'
iq[to="localhost"] query[xmlns="http://jabber.org/protocol/disco#items"]
'
);
});
var
items_IQ_id
=
IQ_ids
[
IQ_stanzas
.
indexOf
(
stanza
)];
stanza
=
$iq
({
'
type
'
:
'
result
'
,
'
from
'
:
'
localhost
'
,
'
to
'
:
'
dummy@localhost/resource
'
,
'
id
'
:
items_IQ_id
}).
c
(
'
query
'
,
{
'
xmlns
'
:
'
http://jabber.org/protocol/disco#items
'
})
.
c
(
'
item
'
,
{
'
jid
'
:
'
upload.localhost
'
,
'
name
'
:
'
HTTP File Upload
'
}
);
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
entities
=
await
_converse
.
api
.
disco
.
entities
.
get
()
expect
(
entities
.
length
).
toBe
(
2
);
expect
(
entities
.
get
(
'
localhost
'
).
items
.
length
).
toBe
(
1
)
;
await
test_utils
.
waitUntil
(
function
()
{
// Converse.js sees that the entity has a disco#info feature,
// so it will make a query for it.
return
_
.
filter
(
IQ_stanzas
,
function
(
iq
)
{
return
iq
.
nodeTree
.
querySelector
(
'
iq[to="upload.localhost"] query[xmlns="http://jabber.org/protocol/disco#info"]
'
);
});
var
IQ_id
=
IQ_ids
[
IQ_stanzas
.
indexOf
(
stanza
)];
expect
(
stanza
.
toLocaleString
()).
toBe
(
`<iq from="dummy@localhost/resource" id="
${
IQ_id
}
" to="upload.localhost" type="get" xmlns="jabber:client">`
+
`<query xmlns="http://jabber.org/protocol/disco#info"/>`
+
`</iq>`
);
// Upload service responds and reports a maximum file size of 5MiB
stanza
=
$iq
({
'
type
'
:
'
result
'
,
'
to
'
:
'
dummy@localhost/resource
'
,
'
id
'
:
IQ_id
,
'
from
'
:
'
upload.localhost
'
})
.
c
(
'
query
'
,
{
'
xmlns
'
:
'
http://jabber.org/protocol/disco#info
'
})
.
c
(
'
identity
'
,
{
'
category
'
:
'
store
'
,
'
type
'
:
'
file
'
,
'
name
'
:
'
HTTP File Upload
'
}).
up
()
.
c
(
'
feature
'
,
{
'
var
'
:
'
urn:xmpp:http:upload:0
'
}).
up
()
.
c
(
'
x
'
,
{
'
type
'
:
'
result
'
,
'
xmlns
'
:
'
jabber:x:data
'
})
.
c
(
'
field
'
,
{
'
var
'
:
'
FORM_TYPE
'
,
'
type
'
:
'
hidden
'
})
.
c
(
'
value
'
).
t
(
'
urn:xmpp:http:upload:0
'
).
up
().
up
()
.
c
(
'
field
'
,
{
'
var
'
:
'
max-file-size
'
})
.
c
(
'
value
'
).
t
(
'
5242880
'
);
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
return
_converse
.
api
.
disco
.
entities
.
get
();
}).
then
(
function
(
entities
)
{
expect
(
entities
.
get
(
'
localhost
'
).
items
.
get
(
'
upload.localhost
'
).
identities
.
where
({
'
category
'
:
'
store
'
}).
length
).
toBe
(
1
);
return
_converse
.
api
.
disco
.
supports
(
Strophe
.
NS
.
HTTPUPLOAD
,
_converse
.
domain
);
}).
then
(
function
(
result
)
{
test_utils
.
createContacts
(
_converse
,
'
current
'
);
_converse
.
emit
(
'
rosterContactsFetched
'
);
}).
length
>
0
;
},
300
);
contact_jid
=
mock
.
cur_names
[
2
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
return
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
);
}).
then
(()
=>
{
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
var
file
=
{
'
type
'
:
'
image/jpeg
'
,
'
size
'
:
'
5242881
'
,
'
lastModifiedDate
'
:
""
,
'
name
'
:
"
my-juliet.jpg
"
};
view
.
model
.
sendFiles
([
file
]);
return
test_utils
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
.message
'
).
length
)
}).
then
(
function
()
{
const
messages
=
view
.
el
.
querySelectorAll
(
'
.message.chat-error
'
);
expect
(
messages
.
length
).
toBe
(
1
);
expect
(
messages
[
0
].
textContent
).
toBe
(
'
The size of your file, my-juliet.jpg, exceeds the maximum allowed by your server, which is 5 MB.
'
);
done
();
}).
catch
(
_
.
partial
(
_converse
.
log
,
_
,
Strophe
.
LogLevel
.
FATAL
))
stanza
=
_
.
find
(
IQ_stanzas
,
function
(
iq
)
{
return
iq
.
nodeTree
.
querySelector
(
'
iq[to="upload.localhost"] query[xmlns="http://jabber.org/protocol/disco#info"]
'
);
});
var
IQ_id
=
IQ_ids
[
IQ_stanzas
.
indexOf
(
stanza
)];
expect
(
stanza
.
toLocaleString
()).
toBe
(
`<iq from="dummy@localhost/resource" id="
${
IQ_id
}
" to="upload.localhost" type="get" xmlns="jabber:client">`
+
`<query xmlns="http://jabber.org/protocol/disco#info"/>`
+
`</iq>`
);
// Upload service responds and reports a maximum file size of 5MiB
stanza
=
$iq
({
'
type
'
:
'
result
'
,
'
to
'
:
'
dummy@localhost/resource
'
,
'
id
'
:
IQ_id
,
'
from
'
:
'
upload.localhost
'
})
.
c
(
'
query
'
,
{
'
xmlns
'
:
'
http://jabber.org/protocol/disco#info
'
})
.
c
(
'
identity
'
,
{
'
category
'
:
'
store
'
,
'
type
'
:
'
file
'
,
'
name
'
:
'
HTTP File Upload
'
}).
up
()
.
c
(
'
feature
'
,
{
'
var
'
:
'
urn:xmpp:http:upload:0
'
}).
up
()
.
c
(
'
x
'
,
{
'
type
'
:
'
result
'
,
'
xmlns
'
:
'
jabber:x:data
'
})
.
c
(
'
field
'
,
{
'
var
'
:
'
FORM_TYPE
'
,
'
type
'
:
'
hidden
'
})
.
c
(
'
value
'
).
t
(
'
urn:xmpp:http:upload:0
'
).
up
().
up
()
.
c
(
'
field
'
,
{
'
var
'
:
'
max-file-size
'
})
.
c
(
'
value
'
).
t
(
'
5242880
'
);
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
entities
=
await
_converse
.
api
.
disco
.
entities
.
get
();
expect
(
entities
.
get
(
'
localhost
'
).
items
.
get
(
'
upload.localhost
'
).
identities
.
where
({
'
category
'
:
'
store
'
}).
length
).
toBe
(
1
);
const
result
=
await
_converse
.
api
.
disco
.
supports
(
Strophe
.
NS
.
HTTPUPLOAD
,
_converse
.
domain
);
test_utils
.
createContacts
(
_converse
,
'
current
'
);
_converse
.
emit
(
'
rosterContactsFetched
'
);
const
contact_jid
=
mock
.
cur_names
[
2
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
await
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
);
const
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
var
file
=
{
'
type
'
:
'
image/jpeg
'
,
'
size
'
:
'
5242881
'
,
'
lastModifiedDate
'
:
""
,
'
name
'
:
"
my-juliet.jpg
"
};
view
.
model
.
sendFiles
([
file
]);
await
test_utils
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
.message
'
).
length
)
const
messages
=
view
.
el
.
querySelectorAll
(
'
.message.chat-error
'
);
expect
(
messages
.
length
).
toBe
(
1
);
expect
(
messages
[
0
].
textContent
).
toBe
(
'
The size of your file, my-juliet.jpg, exceeds the maximum allowed by your server, which is 5 MB.
'
);
done
();
}));
});
});
...
...
spec/notification.js
View file @
53b3f2d0
...
...
@@ -159,47 +159,50 @@
it
(
"
is played when the current user is mentioned in a chat room
"
,
mock
.
initConverseWithPromises
(
null
,
[
'
rosterGroupsFetched
'
],
{},
function
(
done
,
_converse
)
{
async
function
(
done
,
_converse
)
{
test_utils
.
createContacts
(
_converse
,
'
current
'
);
test_utils
.
openAndEnterChatRoom
(
_converse
,
'
lounge
'
,
'
localhost
'
,
'
dummy
'
).
then
(
function
()
{
_converse
.
play_sounds
=
true
;
spyOn
(
_converse
,
'
playSoundNotification
'
);
var
view
=
_converse
.
chatboxviews
.
get
(
'
lounge@localhost
'
);
if
(
!
$
(
view
.
el
).
find
(
'
.chat-area
'
).
length
)
{
view
.
renderChatArea
();
}
var
text
=
'
This message will play a sound because it mentions dummy
'
;
var
message
=
$msg
({
from
:
'
lounge@localhost/otheruser
'
,
id
:
'
1
'
,
to
:
'
dummy@localhost
'
,
type
:
'
groupchat
'
}).
c
(
'
body
'
).
t
(
text
);
view
.
model
.
onMessage
(
message
.
nodeTree
);
expect
(
_converse
.
playSoundNotification
).
toHaveBeenCalled
();
text
=
"
This message won't play a sound
"
;
message
=
$msg
({
from
:
'
lounge@localhost/otheruser
'
,
id
:
'
2
'
,
to
:
'
dummy@localhost
'
,
type
:
'
groupchat
'
}).
c
(
'
body
'
).
t
(
text
);
view
.
model
.
onMessage
(
message
.
nodeTree
);
expect
(
_converse
.
playSoundNotification
,
1
);
_converse
.
play_sounds
=
false
;
text
=
"
This message won't play a sound because it is sent by dummy
"
;
message
=
$msg
({
from
:
'
lounge@localhost/dummy
'
,
id
:
'
3
'
,
to
:
'
dummy@localhost
'
,
type
:
'
groupchat
'
}).
c
(
'
body
'
).
t
(
text
);
view
.
model
.
onMessage
(
message
.
nodeTree
);
expect
(
_converse
.
playSoundNotification
,
1
);
_converse
.
play_sounds
=
false
;
done
();
});
await
test_utils
.
openAndEnterChatRoom
(
_converse
,
'
lounge
'
,
'
localhost
'
,
'
dummy
'
);
_converse
.
play_sounds
=
true
;
spyOn
(
_converse
,
'
playSoundNotification
'
);
const
view
=
_converse
.
chatboxviews
.
get
(
'
lounge@localhost
'
);
if
(
!
view
.
el
.
querySelectorAll
(
'
.chat-area
'
).
length
)
{
view
.
renderChatArea
();
}
let
text
=
'
This message will play a sound because it mentions dummy
'
;
let
message
=
$msg
({
from
:
'
lounge@localhost/otheruser
'
,
id
:
'
1
'
,
to
:
'
dummy@localhost
'
,
type
:
'
groupchat
'
}).
c
(
'
body
'
).
t
(
text
);
view
.
model
.
onMessage
(
message
.
nodeTree
);
await
test_utils
.
waitUntil
(()
=>
_converse
.
playSoundNotification
.
calls
.
count
());
expect
(
_converse
.
playSoundNotification
).
toHaveBeenCalled
();
text
=
"
This message won't play a sound
"
;
message
=
$msg
({
from
:
'
lounge@localhost/otheruser
'
,
id
:
'
2
'
,
to
:
'
dummy@localhost
'
,
type
:
'
groupchat
'
}).
c
(
'
body
'
).
t
(
text
);
view
.
model
.
onMessage
(
message
.
nodeTree
);
expect
(
_converse
.
playSoundNotification
,
1
);
_converse
.
play_sounds
=
false
;
text
=
"
This message won't play a sound because it is sent by dummy
"
;
message
=
$msg
({
from
:
'
lounge@localhost/dummy
'
,
id
:
'
3
'
,
to
:
'
dummy@localhost
'
,
type
:
'
groupchat
'
}).
c
(
'
body
'
).
t
(
text
);
view
.
model
.
onMessage
(
message
.
nodeTree
);
expect
(
_converse
.
playSoundNotification
,
1
);
_converse
.
play_sounds
=
false
;
done
();
}));
});
});
...
...
spec/roster.js
View file @
53b3f2d0
...
...
@@ -10,28 +10,21 @@
const
u
=
converse
.
env
.
utils
;
const
checkHeaderToggling
=
function
(
group
)
{
var
$group
=
$
(
group
);
const
checkHeaderToggling
=
async
function
(
group
)
{
var
toggle
=
group
.
querySelector
(
'
a.group-toggle
'
);
expect
(
u
.
isVisible
(
$group
[
0
]
)).
toBeTruthy
();
expect
(
$group
.
find
(
'
ul.collapsed
'
).
length
).
toBe
(
0
);
expect
(
u
.
isVisible
(
group
)).
toBeTruthy
();
expect
(
group
.
querySelectorAll
(
'
ul.collapsed
'
).
length
).
toBe
(
0
);
expect
(
u
.
hasClass
(
'
fa-caret-right
'
,
toggle
.
firstElementChild
)).
toBeFalsy
();
expect
(
u
.
hasClass
(
'
fa-caret-down
'
,
toggle
.
firstElementChild
)).
toBeTruthy
();
toggle
.
click
();
return
test_utils
.
waitUntil
(
function
()
{
return
$group
.
find
(
'
ul.collapsed
'
).
length
===
1
;
},
500
).
then
(
function
()
{
expect
(
u
.
hasClass
(
'
fa-caret-right
'
,
toggle
.
firstElementChild
)).
toBeTruthy
();
expect
(
u
.
hasClass
(
'
fa-caret-down
'
,
toggle
.
firstElementChild
)).
toBeFalsy
();
toggle
.
click
();
return
test_utils
.
waitUntil
(
function
()
{
return
$group
.
find
(
'
li
'
).
length
===
$group
.
find
(
'
li:visible
'
).
length
},
500
);
}).
then
(
function
()
{
expect
(
u
.
hasClass
(
'
fa-caret-right
'
,
toggle
.
firstElementChild
)).
toBeFalsy
();
expect
(
u
.
hasClass
(
'
fa-caret-down
'
,
toggle
.
firstElementChild
)).
toBeTruthy
();
});
await
test_utils
.
waitUntil
(()
=>
group
.
querySelectorAll
(
'
ul.collapsed
'
).
length
===
1
);
expect
(
u
.
hasClass
(
'
fa-caret-right
'
,
toggle
.
firstElementChild
)).
toBeTruthy
();
expect
(
u
.
hasClass
(
'
fa-caret-down
'
,
toggle
.
firstElementChild
)).
toBeFalsy
();
toggle
.
click
();
await
test_utils
.
waitUntil
(()
=>
group
.
querySelectorAll
(
'
li
'
).
length
===
$
(
group
).
find
(
'
li:visible
'
).
length
);
expect
(
u
.
hasClass
(
'
fa-caret-right
'
,
toggle
.
firstElementChild
)).
toBeFalsy
();
expect
(
u
.
hasClass
(
'
fa-caret-down
'
,
toggle
.
firstElementChild
)).
toBeTruthy
();
};
...
...
@@ -501,7 +494,7 @@
it
(
"
remembers whether it is closed or opened
"
,
mock
.
initConverseWithPromises
(
null
,
[
'
rosterGroupsFetched
'
],
{},
function
(
done
,
_converse
)
{
async
function
(
done
,
_converse
)
{
_converse
.
roster_groups
=
true
;
test_utils
.
openControlBox
();
...
...
@@ -524,20 +517,14 @@
});
}
});
var
view
=
_converse
.
rosterview
.
get
(
'
colleagues
'
);
var
$toggle
=
$
(
view
.
el
).
find
(
'
a.group-toggle
'
);
const
view
=
_converse
.
rosterview
.
get
(
'
colleagues
'
);
const
toggle
=
view
.
el
.
querySelector
(
'
a.group-toggle
'
);
expect
(
view
.
model
.
get
(
'
state
'
)).
toBe
(
'
opened
'
);
$toggle
[
0
].
click
();
return
test_utils
.
waitUntil
(
function
()
{
return
view
.
model
.
get
(
'
state
'
)
===
'
closed
'
;
},
500
).
then
(
function
()
{
$toggle
[
0
].
click
();
return
test_utils
.
waitUntil
(
function
()
{
return
view
.
model
.
get
(
'
state
'
)
===
'
opened
'
;
},
500
)
}).
then
(
function
()
{
done
();
});
toggle
.
click
();
await
test_utils
.
waitUntil
(()
=>
view
.
model
.
get
(
'
state
'
)
===
'
closed
'
);
toggle
.
click
();
await
test_utils
.
waitUntil
(()
=>
view
.
model
.
get
(
'
state
'
)
===
'
opened
'
);
done
();
}));
});
...
...
spec/spoilers.js
View file @
53b3f2d0
...
...
@@ -105,6 +105,7 @@
spyOn
(
view
,
'
onMessageSubmitted
'
).
and
.
callThrough
();
spyOn
(
_converse
.
connection
,
'
send
'
);
await
test_utils
.
waitUntil
(()
=>
view
.
el
.
querySelector
(
'
.toggle-compose-spoiler
'
));
let
spoiler_toggle
=
view
.
el
.
querySelector
(
'
.toggle-compose-spoiler
'
);
spoiler_toggle
.
click
();
...
...
@@ -178,6 +179,8 @@
await
test_utils
.
openChatBoxFor
(
_converse
,
contact_jid
);
await
test_utils
.
waitUntilDiscoConfirmed
(
_converse
,
contact_jid
+
'
/phone
'
,
[],
[
Strophe
.
NS
.
SPOILER
]);
const
view
=
_converse
.
chatboxviews
.
get
(
contact_jid
);
await
test_utils
.
waitUntil
(()
=>
view
.
el
.
querySelector
(
'
.toggle-compose-spoiler
'
));
let
spoiler_toggle
=
view
.
el
.
querySelector
(
'
.toggle-compose-spoiler
'
);
spoiler_toggle
.
click
();
...
...
tests/runner.js
View file @
53b3f2d0
...
...
@@ -179,7 +179,6 @@ require.config(config);
var
specs
=
[
"
jasmine
"
,
//"spec/transcripts",
//"spec/otr",
"
spec/spoilers
"
,
"
spec/profiling
"
,
"
spec/utils
"
,
...
...
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