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
fc941270
Commit
fc941270
authored
Dec 03, 2017
by
JC Brand
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix failing tests
parent
393bbe02
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
475 additions
and
410 deletions
+475
-410
spec/chatbox.js
spec/chatbox.js
+161
-130
spec/chatroom.js
spec/chatroom.js
+10
-2
spec/protocol.js
spec/protocol.js
+283
-277
tests/utils.js
tests/utils.js
+21
-1
No files found.
spec/chatbox.js
View file @
fc941270
...
...
@@ -10,6 +10,7 @@
}
(
this
,
function
(
$
,
jasmine
,
utils
,
converse
,
mock
,
test_utils
)
{
"
use strict
"
;
var
_
=
converse
.
env
.
_
;
var
$iq
=
converse
.
env
.
$iq
;
var
$msg
=
converse
.
env
.
$msg
;
var
Strophe
=
converse
.
env
.
Strophe
;
var
moment
=
converse
.
env
.
moment
;
...
...
@@ -22,30 +23,37 @@
null
,
[
'
rosterGroupsFetched
'
],
{},
function
(
done
,
_converse
)
{
test_utils
.
createContacts
(
_converse
,
'
current
'
);
test_utils
.
openControlBox
();
test_utils
.
openContactsPanel
(
_converse
);
expect
(
_converse
.
chatboxes
.
length
).
toEqual
(
1
);
var
sender_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
var
message
=
'
/me is tired
'
;
var
msg
=
$msg
({
from
:
sender_jid
,
to
:
_converse
.
connection
.
jid
,
type
:
'
chat
'
,
id
:
(
new
Date
()).
getTime
()
}).
c
(
'
body
'
).
t
(
message
).
up
()
.
c
(
'
active
'
,
{
'
xmlns
'
:
'
http://jabber.org/protocol/chatstates
'
}).
tree
();
test_utils
.
waitUntilFeatureSupportConfirmed
(
_converse
,
'
vcard-temp
'
)
.
then
(
function
()
{
return
test_utils
.
waitUntil
(
function
()
{
return
_converse
.
xmppstatus
.
get
(
'
fullname
'
);
},
300
);
}).
then
(
function
()
{
test_utils
.
createContacts
(
_converse
,
'
current
'
);
test_utils
.
openControlBox
();
test_utils
.
openContactsPanel
(
_converse
);
expect
(
_converse
.
chatboxes
.
length
).
toEqual
(
1
);
var
sender_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
var
message
=
'
/me is tired
'
;
var
msg
=
$msg
({
from
:
sender_jid
,
to
:
_converse
.
connection
.
jid
,
type
:
'
chat
'
,
id
:
(
new
Date
()).
getTime
()
}).
c
(
'
body
'
).
t
(
message
).
up
()
.
c
(
'
active
'
,
{
'
xmlns
'
:
'
http://jabber.org/protocol/chatstates
'
}).
tree
();
_converse
.
chatboxes
.
onMessage
(
msg
);
var
view
=
_converse
.
chatboxviews
.
get
(
sender_jid
);
expect
(
_
.
includes
(
view
.
$el
.
find
(
'
.chat-msg-author
'
).
text
(),
'
**Max Frankfurter
'
)).
toBeTruthy
();
expect
(
view
.
$el
.
find
(
'
.chat-msg-content
'
).
text
()).
toBe
(
'
is tired
'
);
_converse
.
chatboxes
.
onMessage
(
msg
);
var
view
=
_converse
.
chatboxviews
.
get
(
sender_jid
);
expect
(
_
.
includes
(
view
.
$el
.
find
(
'
.chat-msg-author
'
).
text
(),
'
**Max Frankfurter
'
)).
toBeTruthy
();
expect
(
view
.
$el
.
find
(
'
.chat-msg-content
'
).
text
()).
toBe
(
'
is tired
'
);
message
=
'
/me is as well
'
;
test_utils
.
sendMessage
(
view
,
message
);
expect
(
_
.
includes
(
view
.
$el
.
find
(
'
.chat-msg-author:last
'
).
text
(),
'
**Max Mustermann
'
)).
toBeTruthy
();
expect
(
view
.
$el
.
find
(
'
.chat-msg-content:last
'
).
text
()).
toBe
(
'
is as well
'
);
done
();
message
=
'
/me is as well
'
;
test_utils
.
sendMessage
(
view
,
message
);
expect
(
_
.
includes
(
view
.
$el
.
find
(
'
.chat-msg-author:last
'
).
text
(),
'
**Max Mustermann
'
)).
toBeTruthy
();
expect
(
view
.
$el
.
find
(
'
.chat-msg-content:last
'
).
text
()).
toBe
(
'
is as well
'
);
done
();
});
}));
it
(
"
is created when you click on a roster item
"
,
...
...
@@ -527,7 +535,8 @@
describe
(
"
A Chat Message
"
,
function
()
{
describe
(
"
when received from someone else
"
,
function
()
{
it
(
"
can be received which will open a chatbox and be displayed inside it
"
,
it
(
"
will open a chatbox and be displayed inside it
"
,
mock
.
initConverseWithPromises
(
null
,
[
'
rosterGroupsFetched
'
],
{},
function
(
done
,
_converse
)
{
...
...
@@ -953,47 +962,55 @@
null
,
[
'
rosterGroupsFetched
'
],
{},
function
(
done
,
_converse
)
{
test_utils
.
createContacts
(
_converse
,
'
current
'
);
test_utils
.
openControlBox
();
test_utils
.
openContactsPanel
(
_converse
);
var
contact
,
sent_stanza
,
IQ_id
,
stanza
;
test_utils
.
waitUntilFeatureSupportConfirmed
(
_converse
,
'
vcard-temp
'
)
.
then
(
function
()
{
return
test_utils
.
waitUntil
(
function
()
{
return
_converse
.
xmppstatus
.
get
(
'
fullname
'
);
},
300
);
}).
then
(
function
()
{
test_utils
.
createContacts
(
_converse
,
'
current
'
);
test_utils
.
openControlBox
();
test_utils
.
openContactsPanel
(
_converse
);
// Send a message from a different resource
spyOn
(
_converse
,
'
log
'
);
var
msgtext
=
'
This is a sent carbon message
'
;
var
recipient_jid
=
mock
.
cur_names
[
5
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
var
msg
=
$msg
({
'
from
'
:
_converse
.
bare_jid
,
'
id
'
:
(
new
Date
()).
getTime
(),
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
chat
'
,
'
xmlns
'
:
'
jabber:client
'
}).
c
(
'
sent
'
,
{
'
xmlns
'
:
'
urn:xmpp:carbons:2
'
})
.
c
(
'
forwarded
'
,
{
'
xmlns
'
:
'
urn:xmpp:forward:0
'
})
.
c
(
'
message
'
,
{
'
xmlns
'
:
'
jabber:client
'
,
'
from
'
:
_converse
.
bare_jid
+
'
/another-resource
'
,
'
to
'
:
recipient_jid
,
'
type
'
:
'
chat
'
}).
c
(
'
body
'
).
t
(
msgtext
).
tree
();
_converse
.
chatboxes
.
onMessage
(
msg
);
// Send a message from a different resource
spyOn
(
_converse
,
'
log
'
);
var
msgtext
=
'
This is a sent carbon message
'
;
var
recipient_jid
=
mock
.
cur_names
[
5
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
var
msg
=
$msg
({
'
from
'
:
_converse
.
bare_jid
,
'
id
'
:
(
new
Date
()).
getTime
(),
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
chat
'
,
'
xmlns
'
:
'
jabber:client
'
}).
c
(
'
sent
'
,
{
'
xmlns
'
:
'
urn:xmpp:carbons:2
'
})
.
c
(
'
forwarded
'
,
{
'
xmlns
'
:
'
urn:xmpp:forward:0
'
})
.
c
(
'
message
'
,
{
'
xmlns
'
:
'
jabber:client
'
,
'
from
'
:
_converse
.
bare_jid
+
'
/another-resource
'
,
'
to
'
:
recipient_jid
,
'
type
'
:
'
chat
'
}).
c
(
'
body
'
).
t
(
msgtext
).
tree
();
_converse
.
chatboxes
.
onMessage
(
msg
);
// Check that the chatbox and its view now exist
var
chatbox
=
_converse
.
chatboxes
.
get
(
recipient_jid
);
var
chatboxview
=
_converse
.
chatboxviews
.
get
(
recipient_jid
);
expect
(
chatbox
).
toBeDefined
();
expect
(
chatboxview
).
toBeDefined
();
// Check that the message was received and check the message parameters
expect
(
chatbox
.
messages
.
length
).
toEqual
(
1
);
var
msg_obj
=
chatbox
.
messages
.
models
[
0
];
expect
(
msg_obj
.
get
(
'
message
'
)).
toEqual
(
msgtext
);
expect
(
msg_obj
.
get
(
'
fullname
'
)).
toEqual
(
_converse
.
xmppstatus
.
get
(
'
fullname
'
));
expect
(
msg_obj
.
get
(
'
sender
'
)).
toEqual
(
'
me
'
);
expect
(
msg_obj
.
get
(
'
delayed
'
)).
toEqual
(
false
);
// Now check that the message appears inside the chatbox in the DOM
var
$chat_content
=
chatboxview
.
$el
.
find
(
'
.chat-content
'
);
var
msg_txt
=
$chat_content
.
find
(
'
.chat-message
'
).
find
(
'
.chat-msg-content
'
).
text
();
expect
(
msg_txt
).
toEqual
(
msgtext
);
done
();
// Check that the chatbox and its view now exist
var
chatbox
=
_converse
.
chatboxes
.
get
(
recipient_jid
);
var
chatboxview
=
_converse
.
chatboxviews
.
get
(
recipient_jid
);
expect
(
chatbox
).
toBeDefined
();
expect
(
chatboxview
).
toBeDefined
();
// Check that the message was received and check the message parameters
expect
(
chatbox
.
messages
.
length
).
toEqual
(
1
);
var
msg_obj
=
chatbox
.
messages
.
models
[
0
];
expect
(
msg_obj
.
get
(
'
message
'
)).
toEqual
(
msgtext
);
expect
(
msg_obj
.
get
(
'
fullname
'
)).
toEqual
(
_converse
.
xmppstatus
.
get
(
'
fullname
'
));
expect
(
msg_obj
.
get
(
'
sender
'
)).
toEqual
(
'
me
'
);
expect
(
msg_obj
.
get
(
'
delayed
'
)).
toEqual
(
false
);
// Now check that the message appears inside the chatbox in the DOM
var
$chat_content
=
chatboxview
.
$el
.
find
(
'
.chat-content
'
);
var
msg_txt
=
$chat_content
.
find
(
'
.chat-message
'
).
find
(
'
.chat-msg-content
'
).
text
();
expect
(
msg_txt
).
toEqual
(
msgtext
);
done
();
});
}));
it
(
"
will be discarded if it's a malicious message meant to look like a carbon copy
"
,
...
...
@@ -1561,41 +1578,48 @@
null
,
[
'
rosterGroupsFetched
'
],
{},
function
(
done
,
_converse
)
{
test_utils
.
createContacts
(
_converse
,
'
current
'
);
// Send a message from a different resource
spyOn
(
_converse
,
'
log
'
);
var
recipient_jid
=
mock
.
cur_names
[
5
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
test_utils
.
openChatBoxFor
(
_converse
,
recipient_jid
);
var
msg
=
$msg
({
'
from
'
:
_converse
.
bare_jid
,
'
id
'
:
(
new
Date
()).
getTime
(),
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
chat
'
,
'
xmlns
'
:
'
jabber:client
'
}).
c
(
'
sent
'
,
{
'
xmlns
'
:
'
urn:xmpp:carbons:2
'
})
.
c
(
'
forwarded
'
,
{
'
xmlns
'
:
'
urn:xmpp:forward:0
'
})
.
c
(
'
message
'
,
{
'
xmlns
'
:
'
jabber:client
'
,
'
from
'
:
_converse
.
bare_jid
+
'
/another-resource
'
,
'
to
'
:
recipient_jid
,
'
type
'
:
'
chat
'
}).
c
(
'
composing
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
CHATSTATES
}).
tree
();
_converse
.
chatboxes
.
onMessage
(
msg
);
var
contact
,
sent_stanza
,
IQ_id
,
stanza
;
test_utils
.
waitUntilFeatureSupportConfirmed
(
_converse
,
'
vcard-temp
'
)
.
then
(
function
()
{
return
test_utils
.
waitUntil
(
function
()
{
return
_converse
.
xmppstatus
.
get
(
'
fullname
'
);
},
300
);
}).
then
(
function
()
{
test_utils
.
createContacts
(
_converse
,
'
current
'
);
// Send a message from a different resource
spyOn
(
_converse
,
'
log
'
);
var
recipient_jid
=
mock
.
cur_names
[
5
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
test_utils
.
openChatBoxFor
(
_converse
,
recipient_jid
);
var
msg
=
$msg
({
'
from
'
:
_converse
.
bare_jid
,
'
id
'
:
(
new
Date
()).
getTime
(),
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
chat
'
,
'
xmlns
'
:
'
jabber:client
'
}).
c
(
'
sent
'
,
{
'
xmlns
'
:
'
urn:xmpp:carbons:2
'
})
.
c
(
'
forwarded
'
,
{
'
xmlns
'
:
'
urn:xmpp:forward:0
'
})
.
c
(
'
message
'
,
{
'
xmlns
'
:
'
jabber:client
'
,
'
from
'
:
_converse
.
bare_jid
+
'
/another-resource
'
,
'
to
'
:
recipient_jid
,
'
type
'
:
'
chat
'
}).
c
(
'
composing
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
CHATSTATES
}).
tree
();
_converse
.
chatboxes
.
onMessage
(
msg
);
// Check that the chatbox and its view now exist
var
chatbox
=
_converse
.
chatboxes
.
get
(
recipient_jid
);
var
chatboxview
=
_converse
.
chatboxviews
.
get
(
recipient_jid
);
// Check that the message was received and check the message parameters
expect
(
chatbox
.
messages
.
length
).
toEqual
(
1
);
var
msg_obj
=
chatbox
.
messages
.
models
[
0
];
expect
(
msg_obj
.
get
(
'
fullname
'
)).
toEqual
(
_converse
.
xmppstatus
.
get
(
'
fullname
'
));
expect
(
msg_obj
.
get
(
'
sender
'
)).
toEqual
(
'
me
'
);
expect
(
msg_obj
.
get
(
'
delayed
'
)).
toEqual
(
false
);
var
$chat_content
=
chatboxview
.
$el
.
find
(
'
.chat-content
'
);
var
status_text
=
$chat_content
.
find
(
'
.chat-info.chat-event
'
).
text
();
expect
(
status_text
).
toBe
(
'
Typing from another device
'
);
done
();
// Check that the chatbox and its view now exist
var
chatbox
=
_converse
.
chatboxes
.
get
(
recipient_jid
);
var
chatboxview
=
_converse
.
chatboxviews
.
get
(
recipient_jid
);
// Check that the message was received and check the message parameters
expect
(
chatbox
.
messages
.
length
).
toEqual
(
1
);
var
msg_obj
=
chatbox
.
messages
.
models
[
0
];
expect
(
msg_obj
.
get
(
'
fullname
'
)).
toEqual
(
_converse
.
xmppstatus
.
get
(
'
fullname
'
));
expect
(
msg_obj
.
get
(
'
sender
'
)).
toEqual
(
'
me
'
);
expect
(
msg_obj
.
get
(
'
delayed
'
)).
toEqual
(
false
);
var
$chat_content
=
chatboxview
.
$el
.
find
(
'
.chat-content
'
);
var
status_text
=
$chat_content
.
find
(
'
.chat-info.chat-event
'
).
text
();
expect
(
status_text
).
toBe
(
'
Typing from another device
'
);
done
();
});
}));
});
...
...
@@ -1702,41 +1726,48 @@
null
,
[
'
rosterGroupsFetched
'
],
{},
function
(
done
,
_converse
)
{
test_utils
.
createContacts
(
_converse
,
'
current
'
);
// Send a message from a different resource
spyOn
(
_converse
,
'
log
'
);
var
recipient_jid
=
mock
.
cur_names
[
5
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
test_utils
.
openChatBoxFor
(
_converse
,
recipient_jid
);
var
msg
=
$msg
({
'
from
'
:
_converse
.
bare_jid
,
'
id
'
:
(
new
Date
()).
getTime
(),
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
chat
'
,
'
xmlns
'
:
'
jabber:client
'
}).
c
(
'
sent
'
,
{
'
xmlns
'
:
'
urn:xmpp:carbons:2
'
})
.
c
(
'
forwarded
'
,
{
'
xmlns
'
:
'
urn:xmpp:forward:0
'
})
.
c
(
'
message
'
,
{
'
xmlns
'
:
'
jabber:client
'
,
'
from
'
:
_converse
.
bare_jid
+
'
/another-resource
'
,
'
to
'
:
recipient_jid
,
'
type
'
:
'
chat
'
}).
c
(
'
paused
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
CHATSTATES
}).
tree
();
_converse
.
chatboxes
.
onMessage
(
msg
);
var
contact
,
sent_stanza
,
IQ_id
,
stanza
;
test_utils
.
waitUntilFeatureSupportConfirmed
(
_converse
,
'
vcard-temp
'
)
.
then
(
function
()
{
return
test_utils
.
waitUntil
(
function
()
{
return
_converse
.
xmppstatus
.
get
(
'
fullname
'
);
},
300
);
}).
then
(
function
()
{
test_utils
.
createContacts
(
_converse
,
'
current
'
);
// Send a message from a different resource
spyOn
(
_converse
,
'
log
'
);
var
recipient_jid
=
mock
.
cur_names
[
5
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@localhost
'
;
test_utils
.
openChatBoxFor
(
_converse
,
recipient_jid
);
var
msg
=
$msg
({
'
from
'
:
_converse
.
bare_jid
,
'
id
'
:
(
new
Date
()).
getTime
(),
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
chat
'
,
'
xmlns
'
:
'
jabber:client
'
}).
c
(
'
sent
'
,
{
'
xmlns
'
:
'
urn:xmpp:carbons:2
'
})
.
c
(
'
forwarded
'
,
{
'
xmlns
'
:
'
urn:xmpp:forward:0
'
})
.
c
(
'
message
'
,
{
'
xmlns
'
:
'
jabber:client
'
,
'
from
'
:
_converse
.
bare_jid
+
'
/another-resource
'
,
'
to
'
:
recipient_jid
,
'
type
'
:
'
chat
'
}).
c
(
'
paused
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
CHATSTATES
}).
tree
();
_converse
.
chatboxes
.
onMessage
(
msg
);
// Check that the chatbox and its view now exist
var
chatbox
=
_converse
.
chatboxes
.
get
(
recipient_jid
);
var
chatboxview
=
_converse
.
chatboxviews
.
get
(
recipient_jid
);
// Check that the message was received and check the message parameters
expect
(
chatbox
.
messages
.
length
).
toEqual
(
1
);
var
msg_obj
=
chatbox
.
messages
.
models
[
0
];
expect
(
msg_obj
.
get
(
'
fullname
'
)).
toEqual
(
_converse
.
xmppstatus
.
get
(
'
fullname
'
));
expect
(
msg_obj
.
get
(
'
sender
'
)).
toEqual
(
'
me
'
);
expect
(
msg_obj
.
get
(
'
delayed
'
)).
toEqual
(
false
);
var
$chat_content
=
chatboxview
.
$el
.
find
(
'
.chat-content
'
);
var
status_text
=
$chat_content
.
find
(
'
.chat-info.chat-event
'
).
text
();
expect
(
status_text
).
toBe
(
'
Stopped typing on the other device
'
);
done
();
// Check that the chatbox and its view now exist
var
chatbox
=
_converse
.
chatboxes
.
get
(
recipient_jid
);
var
chatboxview
=
_converse
.
chatboxviews
.
get
(
recipient_jid
);
// Check that the message was received and check the message parameters
expect
(
chatbox
.
messages
.
length
).
toEqual
(
1
);
var
msg_obj
=
chatbox
.
messages
.
models
[
0
];
expect
(
msg_obj
.
get
(
'
fullname
'
)).
toEqual
(
_converse
.
xmppstatus
.
get
(
'
fullname
'
));
expect
(
msg_obj
.
get
(
'
sender
'
)).
toEqual
(
'
me
'
);
expect
(
msg_obj
.
get
(
'
delayed
'
)).
toEqual
(
false
);
var
$chat_content
=
chatboxview
.
$el
.
find
(
'
.chat-content
'
);
var
status_text
=
$chat_content
.
find
(
'
.chat-info.chat-event
'
).
text
();
expect
(
status_text
).
toBe
(
'
Stopped typing on the other device
'
);
done
();
});
}));
});
...
...
spec/chatroom.js
View file @
fc941270
...
...
@@ -546,8 +546,16 @@
null
,
[
'
rosterGroupsFetched
'
],
{},
function
(
done
,
_converse
)
{
test_utils
.
createContacts
(
_converse
,
'
current
'
);
test_utils
.
openAndEnterChatRoom
(
_converse
,
'
lounge
'
,
'
localhost
'
,
'
dummy
'
).
then
(
function
()
{
test_utils
.
waitUntilFeatureSupportConfirmed
(
_converse
,
'
vcard-temp
'
)
.
then
(
function
()
{
return
test_utils
.
waitUntil
(
function
()
{
return
_converse
.
xmppstatus
.
get
(
'
fullname
'
);
},
300
);
}).
then
(
function
()
{
test_utils
.
createContacts
(
_converse
,
'
current
'
);
return
test_utils
.
openAndEnterChatRoom
(
_converse
,
'
lounge
'
,
'
localhost
'
,
'
dummy
'
);
}).
then
(
function
()
{
var
view
=
_converse
.
chatboxviews
.
get
(
'
lounge@localhost
'
);
if
(
!
view
.
$el
.
find
(
'
.chat-area
'
).
length
)
{
view
.
renderChatArea
();
}
var
message
=
'
/me is tired
'
;
...
...
spec/protocol.js
View file @
fc941270
...
...
@@ -54,178 +54,185 @@
{
roster_groups
:
false
},
function
(
done
,
_converse
)
{
/* The process by which a user subscribes to a contact, including
* the interaction between roster items and subscription states.
*/
var
contact
,
stanza
,
sent_stanza
,
IQ_id
;
test_utils
.
openControlBox
(
_converse
);
var
panel
=
_converse
.
chatboxviews
.
get
(
'
controlbox
'
).
contactspanel
;
spyOn
(
panel
,
"
addContactFromForm
"
).
and
.
callThrough
();
spyOn
(
_converse
.
roster
,
"
addAndSubscribe
"
).
and
.
callThrough
();
spyOn
(
_converse
.
roster
,
"
addContact
"
).
and
.
callThrough
();
spyOn
(
_converse
.
roster
,
"
sendContactAddIQ
"
).
and
.
callThrough
();
spyOn
(
_converse
.
api
.
vcard
,
"
get
"
).
and
.
callThrough
();
var
sendIQ
=
_converse
.
connection
.
sendIQ
;
spyOn
(
_converse
.
connection
,
'
sendIQ
'
).
and
.
callFake
(
function
(
iq
,
callback
,
errback
)
{
sent_stanza
=
iq
;
IQ_id
=
sendIQ
.
bind
(
this
)(
iq
,
callback
,
errback
);
});
panel
.
delegateEvents
();
// Rebind all events so that our spy gets called
/* Add a new contact through the UI */
var
form
=
panel
.
el
.
querySelector
(
'
form.add-xmpp-contact
'
);
expect
(
_
.
isNull
(
form
)).
toBeTruthy
();
// Click the "Add a contact" link.
panel
.
$
(
'
.toggle-xmpp-contact-form
'
).
click
();
// Check that the form appears
form
=
panel
.
el
.
querySelector
(
'
form.add-xmpp-contact
'
);
expect
(
form
.
parentElement
.
offsetHeight
).
not
.
toBe
(
0
);
expect
(
_
.
includes
(
form
.
parentElement
.
classList
,
'
collapsed
'
)).
toBeFalsy
();
// Fill in the form and submit
$
(
form
).
find
(
'
input
'
).
val
(
'
contact@example.org
'
);
$
(
form
).
submit
();
/* In preparation for being able to render the contact in the
* user's client interface and for the server to keep track of the
* subscription, the user's client SHOULD perform a "roster set"
* for the new roster item.
*/
expect
(
panel
.
addContactFromForm
).
toHaveBeenCalled
();
expect
(
_converse
.
roster
.
addAndSubscribe
).
toHaveBeenCalled
();
expect
(
_converse
.
roster
.
addContact
).
toHaveBeenCalled
();
// The form should not be visible anymore (by virtue of its
// parent being collapsed)
expect
(
form
.
parentElement
.
offsetHeight
).
toBe
(
0
);
expect
(
_
.
includes
(
form
.
parentElement
.
classList
,
'
collapsed
'
)).
toBeTrue
;
/* _converse request consists of sending an IQ
* stanza of type='set' containing a <query/> element qualified by
* the 'jabber:iq:roster' namespace, which in turn contains an
* <item/> element that defines the new roster item; the <item/>
* element MUST possess a 'jid' attribute, MAY possess a 'name'
* attribute, MUST NOT possess a 'subscription' attribute, and MAY
* contain one or more <group/> child elements:
*
* <iq type='set' id='set1'>
* <query xmlns='jabber:iq:roster'>
* <item
* jid='contact@example.org'
* name='MyContact'>
* <group>MyBuddies</group>
* </item>
* </query>
* </iq>
*/
expect
(
_converse
.
roster
.
sendContactAddIQ
).
toHaveBeenCalled
();
expect
(
sent_stanza
.
toLocaleString
()).
toBe
(
"
<iq type='set' xmlns='jabber:client' id='
"
+
IQ_id
+
"
'>
"
+
"
<query xmlns='jabber:iq:roster'>
"
+
"
<item jid='contact@example.org' name='contact@example.org'/>
"
+
"
</query>
"
+
"
</iq>
"
);
/* As a result, the user's server (1) MUST initiate a roster push
* for the new roster item to all available resources associated
* with _converse user that have requested the roster, setting the
* 'subscription' attribute to a value of "none"; and (2) MUST
* reply to the sending resource with an IQ result indicating the
* success of the roster set:
*
* <iq type='set'>
* <query xmlns='jabber:iq:roster'>
* <item
* jid='contact@example.org'
* subscription='none'
* name='MyContact'>
* <group>MyBuddies</group>
* </item>
* </query>
* </iq>
*/
var
create
=
_converse
.
roster
.
create
;
var
sent_stanzas
=
[];
spyOn
(
_converse
.
connection
,
'
send
'
).
and
.
callFake
(
function
(
stanza
)
{
sent_stanza
=
stanza
;
sent_stanzas
.
push
(
stanza
.
toLocaleString
());
});
spyOn
(
_converse
.
roster
,
'
create
'
).
and
.
callFake
(
function
()
{
contact
=
create
.
apply
(
_converse
.
roster
,
arguments
);
spyOn
(
contact
,
'
subscribe
'
).
and
.
callThrough
();
return
contact
;
});
stanza
=
$iq
({
'
type
'
:
'
set
'
}).
c
(
'
query
'
,
{
'
xmlns
'
:
'
jabber:iq:roster
'
})
.
c
(
'
item
'
,
{
'
jid
'
:
'
contact@example.org
'
,
'
subscription
'
:
'
none
'
,
'
name
'
:
'
contact@example.org
'
});
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
/*
* <iq type='result' id='set1'/>
*/
stanza
=
$iq
({
'
type
'
:
'
result
'
,
'
id
'
:
IQ_id
});
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
var
contact
,
sent_stanza
,
IQ_id
,
stanza
;
test_utils
.
waitUntilFeatureSupportConfirmed
(
_converse
,
'
vcard-temp
'
)
.
then
(
function
()
{
return
test_utils
.
waitUntil
(
function
()
{
return
_converse
.
xmppstatus
.
get
(
'
fullname
'
);
},
300
);
}).
then
(
function
()
{
/* The process by which a user subscribes to a contact, including
* the interaction between roster items and subscription states.
*/
test_utils
.
openControlBox
(
_converse
);
var
panel
=
_converse
.
chatboxviews
.
get
(
'
controlbox
'
).
contactspanel
;
spyOn
(
panel
,
"
addContactFromForm
"
).
and
.
callThrough
();
spyOn
(
_converse
.
roster
,
"
addAndSubscribe
"
).
and
.
callThrough
();
spyOn
(
_converse
.
roster
,
"
addContact
"
).
and
.
callThrough
();
spyOn
(
_converse
.
roster
,
"
sendContactAddIQ
"
).
and
.
callThrough
();
spyOn
(
_converse
.
api
.
vcard
,
"
get
"
).
and
.
callThrough
();
var
sendIQ
=
_converse
.
connection
.
sendIQ
;
spyOn
(
_converse
.
connection
,
'
sendIQ
'
).
and
.
callFake
(
function
(
iq
,
callback
,
errback
)
{
sent_stanza
=
iq
;
IQ_id
=
sendIQ
.
bind
(
this
)(
iq
,
callback
,
errback
);
});
panel
.
delegateEvents
();
// Rebind all events so that our spy gets called
// A contact should now have been created
expect
(
_converse
.
roster
.
get
(
'
contact@example.org
'
)
instanceof
_converse
.
RosterContact
).
toBeTruthy
();
expect
(
contact
.
get
(
'
jid
'
)).
toBe
(
'
contact@example.org
'
);
expect
(
_converse
.
api
.
vcard
.
get
).
toHaveBeenCalled
();
/* Add a new contact through the UI */
var
form
=
panel
.
el
.
querySelector
(
'
form.add-xmpp-contact
'
);
expect
(
_
.
isNull
(
form
)).
toBeTruthy
();
/* To subscribe to the contact's presence information,
* the user's client MUST send a presence stanza of
* type='subscribe' to the contact:
*
* <presence to='contact@example.org' type='subscribe'/>
*/
// Click the "Add a contact" link.
panel
.
$
(
'
.toggle-xmpp-contact-form
'
).
click
();
test_utils
.
waitUntil
(
function
()
{
return
sent_stanzas
.
length
==
1
;
},
300
).
then
(
function
()
{
expect
(
contact
.
subscribe
).
toHaveBeenCalled
();
expect
(
sent_stanza
.
toLocaleString
()).
toBe
(
// Strophe adds the xmlns attr (although not in spec)
"
<presence to='contact@example.org' type='subscribe' xmlns='jabber:client'>
"
+
"
<nick xmlns='http://jabber.org/protocol/nick'>Max Mustermann</nick>
"
+
"
</presence>
"
);
/* As a result, the user's server MUST initiate a second roster
* push to all of the user's available resources that have
* requested the roster, setting the contact to the pending
* sub-state of the 'none' subscription state; _converse pending
* sub-state is denoted by the inclusion of the ask='subscribe'
* attribute in the roster item:
*
* <iq type='set'>
* <query xmlns='jabber:iq:roster'>
* <item
* jid='contact@example.org'
* subscription='none'
* ask='subscribe'
* name='MyContact'>
* <group>MyBuddies</group>
* </item>
* </query>
* </iq>
*/
spyOn
(
_converse
.
roster
,
"
updateContact
"
).
and
.
callThrough
();
stanza
=
$iq
({
'
type
'
:
'
set
'
,
'
from
'
:
'
dummy@localhost
'
})
.
c
(
'
query
'
,
{
'
xmlns
'
:
'
jabber:iq:roster
'
})
.
c
(
'
item
'
,
{
'
jid
'
:
'
contact@example.org
'
,
'
subscription
'
:
'
none
'
,
'
ask
'
:
'
subscribe
'
,
'
name
'
:
'
contact@example.org
'
});
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
expect
(
_converse
.
roster
.
updateContact
).
toHaveBeenCalled
();
// Check that the user is now properly shown as a pending
// contact in the roster.
test_utils
.
waitUntil
(
function
()
{
return
$
(
'
a:contains("Pending contacts")
'
).
length
;
},
300
).
then
(
function
()
{
// Check that the form appears
form
=
panel
.
el
.
querySelector
(
'
form.add-xmpp-contact
'
);
expect
(
form
.
parentElement
.
offsetHeight
).
not
.
toBe
(
0
);
expect
(
_
.
includes
(
form
.
parentElement
.
classList
,
'
collapsed
'
)).
toBeFalsy
();
// Fill in the form and submit
$
(
form
).
find
(
'
input
'
).
val
(
'
contact@example.org
'
);
$
(
form
).
submit
();
/* In preparation for being able to render the contact in the
* user's client interface and for the server to keep track of the
* subscription, the user's client SHOULD perform a "roster set"
* for the new roster item.
*/
expect
(
panel
.
addContactFromForm
).
toHaveBeenCalled
();
expect
(
_converse
.
roster
.
addAndSubscribe
).
toHaveBeenCalled
();
expect
(
_converse
.
roster
.
addContact
).
toHaveBeenCalled
();
// The form should not be visible anymore (by virtue of its
// parent being collapsed)
expect
(
form
.
parentElement
.
offsetHeight
).
toBe
(
0
);
expect
(
_
.
includes
(
form
.
parentElement
.
classList
,
'
collapsed
'
)).
toBeTrue
;
/* _converse request consists of sending an IQ
* stanza of type='set' containing a <query/> element qualified by
* the 'jabber:iq:roster' namespace, which in turn contains an
* <item/> element that defines the new roster item; the <item/>
* element MUST possess a 'jid' attribute, MAY possess a 'name'
* attribute, MUST NOT possess a 'subscription' attribute, and MAY
* contain one or more <group/> child elements:
*
* <iq type='set' id='set1'>
* <query xmlns='jabber:iq:roster'>
* <item
* jid='contact@example.org'
* name='MyContact'>
* <group>MyBuddies</group>
* </item>
* </query>
* </iq>
*/
expect
(
_converse
.
roster
.
sendContactAddIQ
).
toHaveBeenCalled
();
expect
(
sent_stanza
.
toLocaleString
()).
toBe
(
"
<iq type='set' xmlns='jabber:client' id='
"
+
IQ_id
+
"
'>
"
+
"
<query xmlns='jabber:iq:roster'>
"
+
"
<item jid='contact@example.org' name='contact@example.org'/>
"
+
"
</query>
"
+
"
</iq>
"
);
/* As a result, the user's server (1) MUST initiate a roster push
* for the new roster item to all available resources associated
* with _converse user that have requested the roster, setting the
* 'subscription' attribute to a value of "none"; and (2) MUST
* reply to the sending resource with an IQ result indicating the
* success of the roster set:
*
* <iq type='set'>
* <query xmlns='jabber:iq:roster'>
* <item
* jid='contact@example.org'
* subscription='none'
* name='MyContact'>
* <group>MyBuddies</group>
* </item>
* </query>
* </iq>
*/
var
create
=
_converse
.
roster
.
create
;
var
sent_stanzas
=
[];
spyOn
(
_converse
.
connection
,
'
send
'
).
and
.
callFake
(
function
(
stanza
)
{
sent_stanza
=
stanza
;
sent_stanzas
.
push
(
stanza
.
toLocaleString
());
});
spyOn
(
_converse
.
roster
,
'
create
'
).
and
.
callFake
(
function
()
{
contact
=
create
.
apply
(
_converse
.
roster
,
arguments
);
spyOn
(
contact
,
'
subscribe
'
).
and
.
callThrough
();
return
contact
;
});
stanza
=
$iq
({
'
type
'
:
'
set
'
}).
c
(
'
query
'
,
{
'
xmlns
'
:
'
jabber:iq:roster
'
})
.
c
(
'
item
'
,
{
'
jid
'
:
'
contact@example.org
'
,
'
subscription
'
:
'
none
'
,
'
name
'
:
'
contact@example.org
'
});
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
/*
* <iq type='result' id='set1'/>
*/
stanza
=
$iq
({
'
type
'
:
'
result
'
,
'
id
'
:
IQ_id
});
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
// A contact should now have been created
expect
(
_converse
.
roster
.
get
(
'
contact@example.org
'
)
instanceof
_converse
.
RosterContact
).
toBeTruthy
();
expect
(
contact
.
get
(
'
jid
'
)).
toBe
(
'
contact@example.org
'
);
expect
(
_converse
.
api
.
vcard
.
get
).
toHaveBeenCalled
();
/* To subscribe to the contact's presence information,
* the user's client MUST send a presence stanza of
* type='subscribe' to the contact:
*
* <presence to='contact@example.org' type='subscribe'/>
*/
return
test_utils
.
waitUntil
(
function
()
{
return
sent_stanzas
.
length
==
1
;
},
300
);
}).
then
(
function
()
{
expect
(
contact
.
subscribe
).
toHaveBeenCalled
();
expect
(
sent_stanza
.
toLocaleString
()).
toBe
(
// Strophe adds the xmlns attr (although not in spec)
"
<presence to='contact@example.org' type='subscribe' xmlns='jabber:client'>
"
+
"
<nick xmlns='http://jabber.org/protocol/nick'>Max Mustermann</nick>
"
+
"
</presence>
"
);
/* As a result, the user's server MUST initiate a second roster
* push to all of the user's available resources that have
* requested the roster, setting the contact to the pending
* sub-state of the 'none' subscription state; _converse pending
* sub-state is denoted by the inclusion of the ask='subscribe'
* attribute in the roster item:
*
* <iq type='set'>
* <query xmlns='jabber:iq:roster'>
* <item
* jid='contact@example.org'
* subscription='none'
* ask='subscribe'
* name='MyContact'>
* <group>MyBuddies</group>
* </item>
* </query>
* </iq>
*/
spyOn
(
_converse
.
roster
,
"
updateContact
"
).
and
.
callThrough
();
stanza
=
$iq
({
'
type
'
:
'
set
'
,
'
from
'
:
'
dummy@localhost
'
})
.
c
(
'
query
'
,
{
'
xmlns
'
:
'
jabber:iq:roster
'
})
.
c
(
'
item
'
,
{
'
jid
'
:
'
contact@example.org
'
,
'
subscription
'
:
'
none
'
,
'
ask
'
:
'
subscribe
'
,
'
name
'
:
'
contact@example.org
'
});
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
expect
(
_converse
.
roster
.
updateContact
).
toHaveBeenCalled
();
// Check that the user is now properly shown as a pending
// contact in the roster.
return
test_utils
.
waitUntil
(
function
()
{
return
$
(
'
a:contains("Pending contacts")
'
).
length
;
},
300
);
}).
then
(
function
()
{
var
$header
=
$
(
'
a:contains("Pending contacts")
'
);
expect
(
$header
.
length
).
toBe
(
1
);
expect
(
$header
.
is
(
"
:visible
"
)).
toBeTruthy
();
...
...
@@ -234,13 +241,13 @@
spyOn
(
contact
,
"
ackSubscribe
"
).
and
.
callThrough
();
/* Here we assume the "happy path" that the contact
* approves the subscription request
*
* <presence
* to='user@example.com'
* from='contact@example.org'
* type='subscribed'/>
*/
* approves the subscription request
*
* <presence
* to='user@example.com'
* from='contact@example.org'
* type='subscribed'/>
*/
stanza
=
$pres
({
'
to
'
:
_converse
.
bare_jid
,
'
from
'
:
'
contact@example.org
'
,
...
...
@@ -249,31 +256,31 @@
sent_stanza
=
""
;
// Reset
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
/* Upon receiving the presence stanza of type "subscribed",
* the user SHOULD acknowledge receipt of that
* subscription state notification by sending a presence
* stanza of type "subscribe".
*/
* the user SHOULD acknowledge receipt of that
* subscription state notification by sending a presence
* stanza of type "subscribe".
*/
expect
(
contact
.
ackSubscribe
).
toHaveBeenCalled
();
expect
(
sent_stanza
.
toLocaleString
()).
toBe
(
// Strophe adds the xmlns attr (although not in spec)
"
<presence type='subscribe' to='contact@example.org' xmlns='jabber:client'/>
"
);
/* The user's server MUST initiate a roster push to all of the user's
* available resources that have requested the roster,
* containing an updated roster item for the contact with
* the 'subscription' attribute set to a value of "to";
*
* <iq type='set'>
* <query xmlns='jabber:iq:roster'>
* <item
* jid='contact@example.org'
* subscription='to'
* name='MyContact'>
* <group>MyBuddies</group>
* </item>
* </query>
* </iq>
*/
* available resources that have requested the roster,
* containing an updated roster item for the contact with
* the 'subscription' attribute set to a value of "to";
*
* <iq type='set'>
* <query xmlns='jabber:iq:roster'>
* <item
* jid='contact@example.org'
* subscription='to'
* name='MyContact'>
* <group>MyBuddies</group>
* </item>
* </query>
* </iq>
*/
IQ_id
=
_converse
.
connection
.
getUniqueId
(
'
roster
'
);
stanza
=
$iq
({
'
type
'
:
'
set
'
,
'
id
'
:
IQ_id
})
.
c
(
'
query
'
,
{
'
xmlns
'
:
'
jabber:iq:roster
'
})
...
...
@@ -303,22 +310,22 @@
expect
(
contact
.
get
(
'
chat_status
'
)).
toBe
(
'
offline
'
);
/* <presence
* from='contact@example.org/resource'
* to='user@example.com/resource'/>
*/
* from='contact@example.org/resource'
* to='user@example.com/resource'/>
*/
stanza
=
$pres
({
'
to
'
:
_converse
.
bare_jid
,
'
from
'
:
'
contact@example.org/resource
'
});
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
// Now the contact should also be online.
expect
(
contact
.
get
(
'
chat_status
'
)).
toBe
(
'
online
'
);
/* Section 8.3. Creating a Mutual Subscription
*
* If the contact wants to create a mutual subscription,
* the contact MUST send a subscription request to the
* user.
*
* <presence from='contact@example.org' to='user@example.com' type='subscribe'/>
*/
*
* If the contact wants to create a mutual subscription,
* the contact MUST send a subscription request to the
* user.
*
* <presence from='contact@example.org' to='user@example.com' type='subscribe'/>
*/
spyOn
(
contact
,
'
authorize
'
).
and
.
callThrough
();
spyOn
(
_converse
.
roster
,
'
handleIncomingSubscription
'
).
and
.
callThrough
();
stanza
=
$pres
({
...
...
@@ -329,32 +336,32 @@
expect
(
_converse
.
roster
.
handleIncomingSubscription
).
toHaveBeenCalled
();
/* The user's client MUST send a presence stanza of type
* "subscribed" to the contact in order to approve the
* subscription request.
*
* <presence to='contact@example.org' type='subscribed'/>
*/
* "subscribed" to the contact in order to approve the
* subscription request.
*
* <presence to='contact@example.org' type='subscribed'/>
*/
expect
(
contact
.
authorize
).
toHaveBeenCalled
();
expect
(
sent_stanza
.
toLocaleString
()).
toBe
(
"
<presence to='contact@example.org' type='subscribed' xmlns='jabber:client'/>
"
);
/* As a result, the user's server MUST initiate a
* roster push containing a roster item for the
* contact with the 'subscription' attribute set to
* a value of "both".
*
* <iq type='set'>
* <query xmlns='jabber:iq:roster'>
* <item
* jid='contact@example.org'
* subscription='both'
* name='MyContact'>
* <group>MyBuddies</group>
* </item>
* </query>
* </iq>
*/
* roster push containing a roster item for the
* contact with the 'subscription' attribute set to
* a value of "both".
*
* <iq type='set'>
* <query xmlns='jabber:iq:roster'>
* <item
* jid='contact@example.org'
* subscription='both'
* name='MyContact'>
* <group>MyBuddies</group>
* </item>
* </query>
* </iq>
*/
stanza
=
$iq
({
'
type
'
:
'
set
'
}).
c
(
'
query
'
,
{
'
xmlns
'
:
'
jabber:iq:roster
'
})
.
c
(
'
item
'
,
{
'
jid
'
:
'
contact@example.org
'
,
...
...
@@ -368,7 +375,6 @@
expect
(
$contacts
.
hasClass
(
'
both
'
)).
toBeTruthy
();
done
();
});
});
}));
it
(
"
Alternate Flow: Contact Declines Subscription Request
"
,
...
...
@@ -377,8 +383,8 @@
function
(
done
,
_converse
)
{
/* The process by which a user subscribes to a contact, including
* the interaction between roster items and subscription states.
*/
* the interaction between roster items and subscription states.
*/
var
contact
,
stanza
,
sent_stanza
,
sent_IQ
;
test_utils
.
openControlBox
(
_converse
);
// Add a new roster contact via roster push
...
...
@@ -401,32 +407,32 @@
sent_IQ
=
iq
;
});
/* We now assume the contact declines the subscription
* requests.
*
/
* Upon receiving the presence stanza of type "unsubscribed"
* addressed to the user, the user's server (1) MUST deliver
* that presence stanza to the user and (2) MUST initiate a
* roster push to all of the user's available resources that
* have requested the roster, containing an updated roster
* item for the contact with the 'subscription' attribute
* set to a value of "none" and with no 'ask' attribute:
*
* <presence
* from='contact@example.org'
* to='user@example.com'
* type='unsubscribed'/>
*
* <iq type='set'>
* <query xmlns='jabber:iq:roster'>
* <item
* jid='contact@example.org'
* subscription='none'
* name='MyContact'>
* <group>MyBuddies</group>
* </item>
* </query>
* </iq>
*/
* requests.
*
* Upon receiving the presence stanza of type "unsubscribed"
* addressed to the user, the user's server (1) MUST deliver
* that presence stanza to the user and (2) MUST initiate a
* roster push to all of the user's available resources that
* have requested the roster, containing an updated roster
* item for the contact with the 'subscription' attribute
* set to a value of "none" and with no 'ask' attribute:
*
* <presence
* from='contact@example.org'
* to='user@example.com'
* type='unsubscribed'/>
*
* <iq type='set'>
* <query xmlns='jabber:iq:roster'>
* <item
* jid='contact@example.org'
* subscription='none'
* name='MyContact'>
* <group>MyBuddies</group>
* </item>
* </query>
* </iq>
*/
// FIXME: also add the <iq>
stanza
=
$pres
({
'
to
'
:
_converse
.
bare_jid
,
...
...
@@ -436,18 +442,18 @@
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
/* Upon receiving the presence stanza of type "unsubscribed",
* the user SHOULD acknowledge receipt of that subscription
* state notification through either "affirming" it by
* sending a presence stanza of type "unsubscribe
*/
* the user SHOULD acknowledge receipt of that subscription
* state notification through either "affirming" it by
* sending a presence stanza of type "unsubscribe
*/
expect
(
contact
.
ackUnsubscribe
).
toHaveBeenCalled
();
expect
(
sent_stanza
.
toLocaleString
()).
toBe
(
"
<presence type='unsubscribe' to='contact@example.org' xmlns='jabber:client'/>
"
);
/* _converse.js will then also automatically remove the
* contact from the user's roster.
*/
* contact from the user's roster.
*/
expect
(
sent_IQ
.
toLocaleString
()).
toBe
(
"
<iq type='set' xmlns='jabber:client'>
"
+
"
<query xmlns='jabber:iq:roster'>
"
+
...
...
@@ -486,24 +492,24 @@
expect
(
window
.
confirm
).
toHaveBeenCalled
();
/* Section 8.6 Removing a Roster Item and Cancelling All
* Subscriptions
*
* First the user is removed from the roster
* Because there may be many steps involved in completely
* removing a roster item and cancelling subscriptions in
* both directions, the roster management protocol includes
* a "shortcut" method for doing so. The process may be
* initiated no matter what the current subscription state
* is by sending a roster set containing an item for the
* contact with the 'subscription' attribute set to a value
* of "remove":
*
* <iq type='set' id='remove1'>
* <query xmlns='jabber:iq:roster'>
* <item jid='contact@example.org' subscription='remove'/>
* </query>
* </iq>
*/
* Subscriptions
*
* First the user is removed from the roster
* Because there may be many steps involved in completely
* removing a roster item and cancelling subscriptions in
* both directions, the roster management protocol includes
* a "shortcut" method for doing so. The process may be
* initiated no matter what the current subscription state
* is by sending a roster set containing an item for the
* contact with the 'subscription' attribute set to a value
* of "remove":
*
* <iq type='set' id='remove1'>
* <query xmlns='jabber:iq:roster'>
* <item jid='contact@example.org' subscription='remove'/>
* </query>
* </iq>
*/
expect
(
sent_IQ
.
toLocaleString
()).
toBe
(
"
<iq type='set' xmlns='jabber:client' id='
"
+
IQ_id
+
"
'>
"
+
"
<query xmlns='jabber:iq:roster'>
"
+
...
...
tests/utils.js
View file @
fc941270
...
...
@@ -11,7 +11,27 @@
if
(
typeof
window
.
Promise
===
'
undefined
'
)
{
waitUntilPromise
.
setPromiseImplementation
(
Promise
);
}
utils
.
waitUntil
=
waitUntilPromise
[
'
default
'
];
utils
.
waitUntil
=
waitUntilPromise
.
default
;
utils
.
waitUntilFeatureSupportConfirmed
=
function
(
_converse
,
feature_name
)
{
var
IQ_disco
,
stanza
;
return
utils
.
waitUntil
(
function
()
{
IQ_disco
=
_
.
filter
(
_converse
.
connection
.
IQ_stanzas
,
function
(
iq
)
{
return
iq
.
nodeTree
.
querySelector
(
'
query[xmlns="http://jabber.org/protocol/disco#info"]
'
);
}).
pop
();
return
!
_
.
isUndefined
(
IQ_disco
);
},
300
).
then
(
function
()
{
var
info_IQ_id
=
IQ_disco
.
nodeTree
.
getAttribute
(
'
id
'
);
stanza
=
$iq
({
'
type
'
:
'
result
'
,
'
from
'
:
'
localhost
'
,
'
to
'
:
'
dummy@localhost/resource
'
,
'
id
'
:
info_IQ_id
}).
c
(
'
query
'
,
{
'
xmlns
'
:
'
http://jabber.org/protocol/disco#info
'
})
.
c
(
'
feature
'
,
{
'
var
'
:
feature_name
});
_converse
.
connection
.
_dataRecv
(
utils
.
createRequest
(
stanza
));
});
}
utils
.
createRequest
=
function
(
iq
)
{
iq
=
typeof
iq
.
tree
==
"
function
"
?
iq
.
tree
()
:
iq
;
...
...
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