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
ae7b29cb
Commit
ae7b29cb
authored
Oct 23, 2020
by
JC Brand
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move correections tests into a separate file
parent
8c1e886a
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
625 additions
and
612 deletions
+625
-612
karma.conf.js
karma.conf.js
+1
-0
spec/corrections.js
spec/corrections.js
+624
-0
spec/messages.js
spec/messages.js
+0
-344
spec/muc_messages.js
spec/muc_messages.js
+0
-268
No files found.
karma.conf.js
View file @
ae7b29cb
...
...
@@ -46,6 +46,7 @@ module.exports = function(config) {
{
pattern
:
"
spec/chatbox.js
"
,
type
:
'
module
'
},
{
pattern
:
"
spec/user-details-modal.js
"
,
type
:
'
module
'
},
{
pattern
:
"
spec/messages.js
"
,
type
:
'
module
'
},
{
pattern
:
"
spec/corrections.js
"
,
type
:
'
module
'
},
{
pattern
:
"
spec/receipts.js
"
,
type
:
'
module
'
},
{
pattern
:
"
spec/muc_messages.js
"
,
type
:
'
module
'
},
{
pattern
:
"
spec/mentions.js
"
,
type
:
'
module
'
},
...
...
spec/corrections.js
0 → 100644
View file @
ae7b29cb
/*global mock, converse */
const
{
Promise
,
$msg
,
$pres
,
Strophe
,
sizzle
}
=
converse
.
env
;
const
u
=
converse
.
env
.
utils
;
describe
(
"
A Chat Message
"
,
function
()
{
it
(
"
can be sent as a correction by using the up arrow
"
,
mock
.
initConverse
(
[
'
rosterGroupsFetched
'
,
'
chatBoxesFetched
'
],
{},
async
function
(
done
,
_converse
)
{
await
mock
.
waitForRoster
(
_converse
,
'
current
'
,
1
);
await
mock
.
openControlBox
(
_converse
);
const
contact_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@montague.lit
'
;
await
mock
.
openChatBoxFor
(
_converse
,
contact_jid
)
const
view
=
_converse
.
api
.
chatviews
.
get
(
contact_jid
);
const
textarea
=
view
.
el
.
querySelector
(
'
textarea.chat-textarea
'
);
expect
(
textarea
.
value
).
toBe
(
''
);
view
.
onKeyDown
({
target
:
textarea
,
keyCode
:
38
// Up arrow
});
expect
(
textarea
.
value
).
toBe
(
''
);
textarea
.
value
=
'
But soft, what light through yonder airlock breaks?
'
;
view
.
onKeyDown
({
target
:
textarea
,
preventDefault
:
function
preventDefault
()
{},
keyCode
:
13
// Enter
});
await
new
Promise
(
resolve
=>
view
.
model
.
messages
.
once
(
'
rendered
'
,
resolve
));
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
view
.
el
.
querySelector
(
'
.chat-msg__text
'
).
textContent
)
.
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
const
first_msg
=
view
.
model
.
messages
.
findWhere
({
'
message
'
:
'
But soft, what light through yonder airlock breaks?
'
});
expect
(
textarea
.
value
).
toBe
(
''
);
view
.
onKeyDown
({
target
:
textarea
,
keyCode
:
38
// Up arrow
});
expect
(
textarea
.
value
).
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBe
(
true
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
await
u
.
waitUntil
(()
=>
u
.
hasClass
(
'
correcting
'
,
view
.
el
.
querySelector
(
'
.chat-msg
'
)),
500
);
spyOn
(
_converse
.
connection
,
'
send
'
);
textarea
.
value
=
'
But soft, what light through yonder window breaks?
'
;
view
.
onKeyDown
({
target
:
textarea
,
preventDefault
:
function
preventDefault
()
{},
keyCode
:
13
// Enter
});
expect
(
_converse
.
connection
.
send
).
toHaveBeenCalled
();
await
new
Promise
(
resolve
=>
view
.
model
.
messages
.
once
(
'
rendered
'
,
resolve
));
const
msg
=
_converse
.
connection
.
send
.
calls
.
all
()[
0
].
args
[
0
];
expect
(
msg
.
toLocaleString
())
.
toBe
(
`<message from="romeo@montague.lit/orchard" id="
${
msg
.
nodeTree
.
getAttribute
(
"
id
"
)}
" `
+
`to="mercutio@montague.lit" type="chat" `
+
`xmlns="jabber:client">`
+
`<body>But soft, what light through yonder window breaks?</body>`
+
`<active xmlns="http://jabber.org/protocol/chatstates"/>`
+
`<request xmlns="urn:xmpp:receipts"/>`
+
`<replace id="
${
first_msg
.
get
(
"
msgid
"
)}
" xmlns="urn:xmpp:message-correct:0"/>`
+
`<origin-id id="
${
msg
.
nodeTree
.
querySelector
(
'
origin-id
'
).
getAttribute
(
"
id
"
)}
" xmlns="urn:xmpp:sid:0"/>`
+
`</message>`
);
expect
(
view
.
model
.
messages
.
models
.
length
).
toBe
(
1
);
const
corrected_message
=
view
.
model
.
messages
.
at
(
0
);
expect
(
corrected_message
.
get
(
'
msgid
'
)).
toBe
(
first_msg
.
get
(
'
msgid
'
));
expect
(
corrected_message
.
get
(
'
correcting
'
)).
toBe
(
false
);
const
older_versions
=
corrected_message
.
get
(
'
older_versions
'
);
const
keys
=
Object
.
keys
(
older_versions
);
expect
(
keys
.
length
).
toBe
(
1
);
expect
(
older_versions
[
keys
[
0
]]).
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
await
u
.
waitUntil
(()
=>
(
u
.
hasClass
(
'
correcting
'
,
view
.
el
.
querySelector
(
'
.chat-msg
'
))
===
false
),
500
);
// Test that pressing the down arrow cancels message correction
expect
(
textarea
.
value
).
toBe
(
''
);
view
.
onKeyDown
({
target
:
textarea
,
keyCode
:
38
// Up arrow
});
expect
(
textarea
.
value
).
toBe
(
'
But soft, what light through yonder window breaks?
'
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBe
(
true
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
await
u
.
waitUntil
(()
=>
u
.
hasClass
(
'
correcting
'
,
view
.
el
.
querySelector
(
'
.chat-msg
'
)),
500
);
expect
(
textarea
.
value
).
toBe
(
'
But soft, what light through yonder window breaks?
'
);
view
.
onKeyDown
({
target
:
textarea
,
keyCode
:
40
// Down arrow
});
expect
(
textarea
.
value
).
toBe
(
''
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBe
(
false
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
await
u
.
waitUntil
(()
=>
(
u
.
hasClass
(
'
correcting
'
,
view
.
el
.
querySelector
(
'
.chat-msg
'
))
===
false
),
500
);
textarea
.
value
=
'
It is the east, and Juliet is the one.
'
;
view
.
onKeyDown
({
target
:
textarea
,
preventDefault
:
function
preventDefault
()
{},
keyCode
:
13
// Enter
});
await
new
Promise
(
resolve
=>
view
.
model
.
messages
.
once
(
'
rendered
'
,
resolve
));
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
2
);
textarea
.
value
=
'
Arise, fair sun, and kill the envious moon
'
;
view
.
onKeyDown
({
target
:
textarea
,
preventDefault
:
function
preventDefault
()
{},
keyCode
:
13
// Enter
});
await
new
Promise
(
resolve
=>
view
.
model
.
messages
.
once
(
'
rendered
'
,
resolve
));
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
3
);
view
.
onKeyDown
({
target
:
textarea
,
keyCode
:
38
// Up arrow
});
expect
(
textarea
.
value
).
toBe
(
'
Arise, fair sun, and kill the envious moon
'
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBeFalsy
();
expect
(
view
.
model
.
messages
.
at
(
1
).
get
(
'
correcting
'
)).
toBeFalsy
();
expect
(
view
.
model
.
messages
.
at
(
2
).
get
(
'
correcting
'
)).
toBe
(
true
);
await
u
.
waitUntil
(()
=>
u
.
hasClass
(
'
correcting
'
,
sizzle
(
'
.chat-msg:last
'
,
view
.
el
).
pop
()),
500
);
textarea
.
selectionEnd
=
0
;
// Happens by pressing up,
// but for some reason not in tests, so we set it manually.
view
.
onKeyDown
({
target
:
textarea
,
keyCode
:
38
// Up arrow
});
expect
(
textarea
.
value
).
toBe
(
'
It is the east, and Juliet is the one.
'
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBeFalsy
();
expect
(
view
.
model
.
messages
.
at
(
1
).
get
(
'
correcting
'
)).
toBe
(
true
);
expect
(
view
.
model
.
messages
.
at
(
2
).
get
(
'
correcting
'
)).
toBeFalsy
();
await
u
.
waitUntil
(()
=>
u
.
hasClass
(
'
correcting
'
,
sizzle
(
'
.chat-msg
'
,
view
.
el
)[
1
]),
500
);
textarea
.
value
=
'
It is the east, and Juliet is the sun.
'
;
view
.
onKeyDown
({
target
:
textarea
,
preventDefault
:
function
preventDefault
()
{},
keyCode
:
13
// Enter
});
await
new
Promise
(
resolve
=>
view
.
model
.
messages
.
once
(
'
rendered
'
,
resolve
));
await
u
.
waitUntil
(()
=>
textarea
.
value
===
''
);
const
messages
=
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
);
expect
(
messages
.
length
).
toBe
(
3
);
expect
(
messages
[
0
].
querySelector
(
'
.chat-msg__text
'
).
textContent
)
.
toBe
(
'
But soft, what light through yonder window breaks?
'
);
expect
(
messages
[
1
].
querySelector
(
'
.chat-msg__text
'
).
textContent
)
.
toBe
(
'
It is the east, and Juliet is the sun.
'
);
expect
(
messages
[
2
].
querySelector
(
'
.chat-msg__text
'
).
textContent
)
.
toBe
(
'
Arise, fair sun, and kill the envious moon
'
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBeFalsy
();
expect
(
view
.
model
.
messages
.
at
(
1
).
get
(
'
correcting
'
)).
toBeFalsy
();
expect
(
view
.
model
.
messages
.
at
(
2
).
get
(
'
correcting
'
)).
toBeFalsy
();
done
();
}));
it
(
"
can be sent as a correction by clicking the pencil icon
"
,
mock
.
initConverse
(
[
'
rosterGroupsFetched
'
,
'
chatBoxesFetched
'
],
{},
async
function
(
done
,
_converse
)
{
await
mock
.
waitForRoster
(
_converse
,
'
current
'
,
1
);
await
mock
.
openControlBox
(
_converse
);
const
contact_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@montague.lit
'
;
await
mock
.
openChatBoxFor
(
_converse
,
contact_jid
);
const
view
=
_converse
.
api
.
chatviews
.
get
(
contact_jid
);
const
textarea
=
view
.
el
.
querySelector
(
'
textarea.chat-textarea
'
);
textarea
.
value
=
'
But soft, what light through yonder airlock breaks?
'
;
view
.
onKeyDown
({
target
:
textarea
,
preventDefault
:
function
preventDefault
()
{},
keyCode
:
13
// Enter
});
await
new
Promise
(
resolve
=>
view
.
model
.
messages
.
once
(
'
rendered
'
,
resolve
));
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
view
.
el
.
querySelector
(
'
.chat-msg__text
'
).
textContent
)
.
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
expect
(
textarea
.
value
).
toBe
(
''
);
const
first_msg
=
view
.
model
.
messages
.
findWhere
({
'
message
'
:
'
But soft, what light through yonder airlock breaks?
'
});
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
.chat-msg .chat-msg__action
'
).
length
===
2
);
let
action
=
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg__action
'
);
expect
(
action
.
textContent
.
trim
()).
toBe
(
'
Edit
'
);
action
.
style
.
opacity
=
1
;
action
.
click
();
expect
(
textarea
.
value
).
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBe
(
true
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
await
u
.
waitUntil
(()
=>
u
.
hasClass
(
'
correcting
'
,
view
.
el
.
querySelector
(
'
.chat-msg
'
)));
spyOn
(
_converse
.
connection
,
'
send
'
);
textarea
.
value
=
'
But soft, what light through yonder window breaks?
'
;
view
.
onKeyDown
({
target
:
textarea
,
preventDefault
:
function
preventDefault
()
{},
keyCode
:
13
// Enter
});
expect
(
_converse
.
connection
.
send
).
toHaveBeenCalled
();
const
msg
=
_converse
.
connection
.
send
.
calls
.
all
()[
0
].
args
[
0
];
expect
(
msg
.
toLocaleString
())
.
toBe
(
`<message from="romeo@montague.lit/orchard" id="
${
msg
.
nodeTree
.
getAttribute
(
"
id
"
)}
" `
+
`to="mercutio@montague.lit" type="chat" `
+
`xmlns="jabber:client">`
+
`<body>But soft, what light through yonder window breaks?</body>`
+
`<active xmlns="http://jabber.org/protocol/chatstates"/>`
+
`<request xmlns="urn:xmpp:receipts"/>`
+
`<replace id="
${
first_msg
.
get
(
"
msgid
"
)}
" xmlns="urn:xmpp:message-correct:0"/>`
+
`<origin-id id="
${
msg
.
nodeTree
.
querySelector
(
'
origin-id
'
).
getAttribute
(
"
id
"
)}
" xmlns="urn:xmpp:sid:0"/>`
+
`</message>`
);
expect
(
view
.
model
.
messages
.
models
.
length
).
toBe
(
1
);
const
corrected_message
=
view
.
model
.
messages
.
at
(
0
);
expect
(
corrected_message
.
get
(
'
msgid
'
)).
toBe
(
first_msg
.
get
(
'
msgid
'
));
expect
(
corrected_message
.
get
(
'
correcting
'
)).
toBe
(
false
);
const
older_versions
=
corrected_message
.
get
(
'
older_versions
'
);
const
keys
=
Object
.
keys
(
older_versions
);
expect
(
keys
.
length
).
toBe
(
1
);
expect
(
older_versions
[
keys
[
0
]]).
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
await
u
.
waitUntil
(()
=>
u
.
hasClass
(
'
correcting
'
,
view
.
el
.
querySelector
(
'
.chat-msg
'
))
===
false
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
// Test that clicking the pencil icon a second time cancels editing.
action
=
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg__action
'
);
action
.
style
.
opacity
=
1
;
action
.
click
();
expect
(
textarea
.
value
).
toBe
(
'
But soft, what light through yonder window breaks?
'
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBe
(
true
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
await
u
.
waitUntil
(()
=>
u
.
hasClass
(
'
correcting
'
,
view
.
el
.
querySelector
(
'
.chat-msg
'
))
===
true
);
action
=
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg__action
'
);
action
.
style
.
opacity
=
1
;
action
.
click
();
expect
(
textarea
.
value
).
toBe
(
''
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBe
(
false
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
await
u
.
waitUntil
(()
=>
(
u
.
hasClass
(
'
correcting
'
,
view
.
el
.
querySelector
(
'
.chat-msg
'
))
===
false
),
500
);
// Test that messages from other users don't have the pencil icon
_converse
.
handleMessageStanza
(
$msg
({
'
from
'
:
contact_jid
,
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
chat
'
,
'
id
'
:
u
.
getUniqueId
()
}).
c
(
'
body
'
).
t
(
'
Hello
'
).
up
()
.
c
(
'
active
'
,
{
'
xmlns
'
:
'
http://jabber.org/protocol/chatstates
'
}).
tree
()
);
await
new
Promise
(
resolve
=>
view
.
model
.
messages
.
once
(
'
rendered
'
,
resolve
));
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg .chat-msg__action
'
).
length
).
toBe
(
2
);
// Test confirmation dialog
spyOn
(
window
,
'
confirm
'
).
and
.
returnValue
(
true
);
textarea
.
value
=
'
But soft, what light through yonder airlock breaks?
'
;
action
=
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg__action
'
);
action
.
style
.
opacity
=
1
;
action
.
click
();
expect
(
window
.
confirm
).
toHaveBeenCalledWith
(
'
You have an unsent message which will be lost if you continue. Are you sure?
'
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBe
(
true
);
expect
(
textarea
.
value
).
toBe
(
'
But soft, what light through yonder window breaks?
'
);
textarea
.
value
=
'
But soft, what light through yonder airlock breaks?
'
action
.
click
();
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBe
(
false
);
expect
(
window
.
confirm
.
calls
.
count
()).
toBe
(
2
);
expect
(
window
.
confirm
.
calls
.
argsFor
(
0
)).
toEqual
(
[
'
You have an unsent message which will be lost if you continue. Are you sure?
'
]);
expect
(
window
.
confirm
.
calls
.
argsFor
(
1
)).
toEqual
(
[
'
You have an unsent message which will be lost if you continue. Are you sure?
'
]);
done
();
}));
describe
(
"
when received from someone else
"
,
function
()
{
it
(
"
can be replaced with a correction
"
,
mock
.
initConverse
(
[
'
rosterGroupsFetched
'
,
'
chatBoxesFetched
'
],
{},
async
function
(
done
,
_converse
)
{
await
mock
.
waitForRoster
(
_converse
,
'
current
'
,
1
);
await
mock
.
openControlBox
(
_converse
);
const
sender_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@montague.lit
'
;
const
msg_id
=
u
.
getUniqueId
();
const
view
=
await
mock
.
openChatBoxFor
(
_converse
,
sender_jid
);
_converse
.
handleMessageStanza
(
$msg
({
'
from
'
:
sender_jid
,
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
chat
'
,
'
id
'
:
msg_id
,
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder airlock breaks?
'
).
tree
());
await
new
Promise
(
resolve
=>
view
.
model
.
messages
.
once
(
'
rendered
'
,
resolve
));
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
view
.
el
.
querySelector
(
'
.chat-msg__text
'
).
textContent
)
.
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
_converse
.
handleMessageStanza
(
$msg
({
'
from
'
:
sender_jid
,
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
chat
'
,
'
id
'
:
u
.
getUniqueId
(),
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder chimney breaks?
'
).
up
()
.
c
(
'
replace
'
,
{
'
id
'
:
msg_id
,
'
xmlns
'
:
'
urn:xmpp:message-correct:0
'
}).
tree
());
await
new
Promise
(
resolve
=>
view
.
model
.
messages
.
once
(
'
rendered
'
,
resolve
));
expect
(
view
.
el
.
querySelector
(
'
.chat-msg__text
'
).
textContent
)
.
toBe
(
'
But soft, what light through yonder chimney breaks?
'
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg__content .fa-edit
'
).
length
).
toBe
(
1
);
expect
(
view
.
model
.
messages
.
models
.
length
).
toBe
(
1
);
_converse
.
handleMessageStanza
(
$msg
({
'
from
'
:
sender_jid
,
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
chat
'
,
'
id
'
:
u
.
getUniqueId
(),
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder window breaks?
'
).
up
()
.
c
(
'
replace
'
,
{
'
id
'
:
msg_id
,
'
xmlns
'
:
'
urn:xmpp:message-correct:0
'
}).
tree
());
await
new
Promise
(
resolve
=>
view
.
model
.
messages
.
once
(
'
rendered
'
,
resolve
));
expect
(
view
.
el
.
querySelector
(
'
.chat-msg__text
'
).
textContent
)
.
toBe
(
'
But soft, what light through yonder window breaks?
'
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg__content .fa-edit
'
).
length
).
toBe
(
1
);
view
.
el
.
querySelector
(
'
.chat-msg__content .fa-edit
'
).
click
();
const
modal
=
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelector
(
'
converse-chat-message
'
).
message_versions_modal
);
await
u
.
waitUntil
(()
=>
u
.
isVisible
(
modal
.
el
),
1000
);
const
older_msgs
=
modal
.
el
.
querySelectorAll
(
'
.older-msg
'
);
expect
(
older_msgs
.
length
).
toBe
(
2
);
expect
(
older_msgs
[
0
].
childNodes
[
0
].
nodeName
).
toBe
(
'
TIME
'
);
expect
(
older_msgs
[
0
].
childNodes
[
2
].
textContent
).
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
expect
(
view
.
model
.
messages
.
models
.
length
).
toBe
(
1
);
done
();
}));
});
});
describe
(
"
A Groupchat Message
"
,
function
()
{
it
(
"
can be replaced with a correction
"
,
mock
.
initConverse
(
[
'
rosterGroupsFetched
'
],
{},
async
function
(
done
,
_converse
)
{
const
muc_jid
=
'
lounge@montague.lit
'
;
await
mock
.
openAndEnterChatRoom
(
_converse
,
muc_jid
,
'
romeo
'
);
const
view
=
_converse
.
api
.
chatviews
.
get
(
muc_jid
);
const
stanza
=
$pres
({
to
:
'
romeo@montague.lit/_converse.js-29092160
'
,
from
:
'
coven@chat.shakespeare.lit/newguy
'
})
.
c
(
'
x
'
,
{
xmlns
:
Strophe
.
NS
.
MUC_USER
})
.
c
(
'
item
'
,
{
'
affiliation
'
:
'
none
'
,
'
jid
'
:
'
newguy@montague.lit/_converse.js-290929789
'
,
'
role
'
:
'
participant
'
}).
tree
();
_converse
.
connection
.
_dataRecv
(
mock
.
createRequest
(
stanza
));
const
msg_id
=
u
.
getUniqueId
();
await
view
.
model
.
handleMessageStanza
(
$msg
({
'
from
'
:
'
lounge@montague.lit/newguy
'
,
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
groupchat
'
,
'
id
'
:
msg_id
,
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder airlock breaks?
'
).
tree
());
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
view
.
el
.
querySelector
(
'
.chat-msg__text
'
).
textContent
)
.
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
await
view
.
model
.
handleMessageStanza
(
$msg
({
'
from
'
:
'
lounge@montague.lit/newguy
'
,
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
groupchat
'
,
'
id
'
:
u
.
getUniqueId
(),
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder chimney breaks?
'
).
up
()
.
c
(
'
replace
'
,
{
'
id
'
:
msg_id
,
'
xmlns
'
:
'
urn:xmpp:message-correct:0
'
}).
tree
());
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelector
(
'
.chat-msg__text
'
).
textContent
===
'
But soft, what light through yonder chimney breaks?
'
,
500
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelector
(
'
.chat-msg__content .fa-edit
'
));
await
view
.
model
.
handleMessageStanza
(
$msg
({
'
from
'
:
'
lounge@montague.lit/newguy
'
,
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
groupchat
'
,
'
id
'
:
u
.
getUniqueId
(),
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder window breaks?
'
).
up
()
.
c
(
'
replace
'
,
{
'
id
'
:
msg_id
,
'
xmlns
'
:
'
urn:xmpp:message-correct:0
'
}).
tree
());
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelector
(
'
.chat-msg__text
'
).
textContent
===
'
But soft, what light through yonder window breaks?
'
,
500
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg__content .fa-edit
'
).
length
).
toBe
(
1
);
const
edit
=
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelector
(
'
.chat-msg__content .fa-edit
'
));
edit
.
click
();
const
modal
=
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelector
(
'
converse-chat-message
'
).
message_versions_modal
);
await
u
.
waitUntil
(()
=>
u
.
isVisible
(
modal
.
el
),
1000
);
const
older_msgs
=
modal
.
el
.
querySelectorAll
(
'
.older-msg
'
);
expect
(
older_msgs
.
length
).
toBe
(
2
);
expect
(
older_msgs
[
0
].
childNodes
[
2
].
textContent
).
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
expect
(
older_msgs
[
0
].
childNodes
[
0
].
nodeName
).
toBe
(
'
TIME
'
);
expect
(
older_msgs
[
1
].
childNodes
[
0
].
nodeName
).
toBe
(
'
TIME
'
);
expect
(
older_msgs
[
1
].
childNodes
[
2
].
textContent
).
toBe
(
'
But soft, what light through yonder chimney breaks?
'
);
done
();
}));
it
(
"
keeps the same position in history after a correction
"
,
mock
.
initConverse
(
[
'
rosterGroupsFetched
'
],
{},
async
function
(
done
,
_converse
)
{
const
muc_jid
=
'
lounge@montague.lit
'
;
await
mock
.
openAndEnterChatRoom
(
_converse
,
muc_jid
,
'
romeo
'
);
const
view
=
_converse
.
api
.
chatviews
.
get
(
muc_jid
);
const
stanza
=
$pres
({
to
:
'
romeo@montague.lit/_converse.js-29092160
'
,
from
:
'
coven@chat.shakespeare.lit/newguy
'
})
.
c
(
'
x
'
,
{
xmlns
:
Strophe
.
NS
.
MUC_USER
})
.
c
(
'
item
'
,
{
'
affiliation
'
:
'
none
'
,
'
jid
'
:
'
newguy@montague.lit/_converse.js-290929789
'
,
'
role
'
:
'
participant
'
}).
tree
();
_converse
.
connection
.
_dataRecv
(
mock
.
createRequest
(
stanza
));
const
msg_id
=
u
.
getUniqueId
();
// Receiving the first message
await
view
.
model
.
handleMessageStanza
(
$msg
({
'
from
'
:
'
lounge@montague.lit/newguy
'
,
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
groupchat
'
,
'
id
'
:
msg_id
,
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder airlock breaks?
'
).
tree
());
// Receiving own message to check order against
await
view
.
model
.
handleMessageStanza
(
$msg
({
'
from
'
:
'
lounge@montague.lit/romeo
'
,
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
groupchat
'
,
'
id
'
:
msg_id
,
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder airlock breaks?
'
).
tree
());
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
===
2
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
2
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg__text
'
)[
0
].
textContent
)
.
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg__text
'
)[
1
].
textContent
)
.
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
// First message correction
await
view
.
model
.
handleMessageStanza
(
$msg
({
'
from
'
:
'
lounge@montague.lit/newguy
'
,
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
groupchat
'
,
'
id
'
:
u
.
getUniqueId
(),
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder chimney breaks?
'
).
up
()
.
c
(
'
replace
'
,
{
'
id
'
:
msg_id
,
'
xmlns
'
:
'
urn:xmpp:message-correct:0
'
}).
tree
());
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelector
(
'
.chat-msg__text
'
).
textContent
===
'
But soft, what light through yonder chimney breaks?
'
,
500
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
2
);
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelector
(
'
.chat-msg__content .fa-edit
'
));
// Second message correction
await
view
.
model
.
handleMessageStanza
(
$msg
({
'
from
'
:
'
lounge@montague.lit/newguy
'
,
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
groupchat
'
,
'
id
'
:
u
.
getUniqueId
(),
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder window breaks?
'
).
up
()
.
c
(
'
replace
'
,
{
'
id
'
:
msg_id
,
'
xmlns
'
:
'
urn:xmpp:message-correct:0
'
}).
tree
());
// Second own message
await
view
.
model
.
handleMessageStanza
(
$msg
({
'
from
'
:
'
lounge@montague.lit/romeo
'
,
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
groupchat
'
,
'
id
'
:
u
.
getUniqueId
(),
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder window breaks?
'
).
tree
());
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
.chat-msg__text
'
)[
0
].
textContent
===
'
But soft, what light through yonder window breaks?
'
,
500
);
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
.chat-msg__text
'
).
length
===
3
);
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
.chat-msg__text
'
)[
2
].
textContent
===
'
But soft, what light through yonder window breaks?
'
,
500
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
3
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg__content .fa-edit
'
).
length
).
toBe
(
1
);
const
edit
=
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelector
(
'
.chat-msg__content .fa-edit
'
));
edit
.
click
();
const
modal
=
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
converse-chat-message
'
)[
0
].
message_versions_modal
);
await
u
.
waitUntil
(()
=>
u
.
isVisible
(
modal
.
el
),
1000
);
const
older_msgs
=
modal
.
el
.
querySelectorAll
(
'
.older-msg
'
);
expect
(
older_msgs
.
length
).
toBe
(
2
);
expect
(
older_msgs
[
0
].
childNodes
[
2
].
textContent
).
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
expect
(
older_msgs
[
0
].
childNodes
[
0
].
nodeName
).
toBe
(
'
TIME
'
);
expect
(
older_msgs
[
1
].
childNodes
[
0
].
nodeName
).
toBe
(
'
TIME
'
);
expect
(
older_msgs
[
1
].
childNodes
[
2
].
textContent
).
toBe
(
'
But soft, what light through yonder chimney breaks?
'
);
done
();
}));
it
(
"
can be sent as a correction by using the up arrow
"
,
mock
.
initConverse
(
[
'
rosterGroupsFetched
'
],
{},
async
function
(
done
,
_converse
)
{
const
muc_jid
=
'
lounge@montague.lit
'
;
await
mock
.
openAndEnterChatRoom
(
_converse
,
muc_jid
,
'
romeo
'
);
const
view
=
_converse
.
api
.
chatviews
.
get
(
muc_jid
);
const
textarea
=
view
.
el
.
querySelector
(
'
textarea.chat-textarea
'
);
expect
(
textarea
.
value
).
toBe
(
''
);
view
.
onKeyDown
({
target
:
textarea
,
keyCode
:
38
// Up arrow
});
expect
(
textarea
.
value
).
toBe
(
''
);
textarea
.
value
=
'
But soft, what light through yonder airlock breaks?
'
;
view
.
onKeyDown
({
target
:
textarea
,
preventDefault
:
function
preventDefault
()
{},
keyCode
:
13
// Enter
});
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
===
1
);
expect
(
view
.
el
.
querySelector
(
'
.chat-msg__text
'
).
textContent
)
.
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
const
first_msg
=
view
.
model
.
messages
.
findWhere
({
'
message
'
:
'
But soft, what light through yonder airlock breaks?
'
});
expect
(
textarea
.
value
).
toBe
(
''
);
view
.
onKeyDown
({
target
:
textarea
,
keyCode
:
38
// Up arrow
});
expect
(
textarea
.
value
).
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBe
(
true
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
await
u
.
waitUntil
(()
=>
u
.
hasClass
(
'
correcting
'
,
view
.
el
.
querySelector
(
'
.chat-msg
'
)));
spyOn
(
_converse
.
connection
,
'
send
'
);
textarea
.
value
=
'
But soft, what light through yonder window breaks?
'
;
view
.
onKeyDown
({
target
:
textarea
,
preventDefault
:
function
preventDefault
()
{},
keyCode
:
13
// Enter
});
expect
(
_converse
.
connection
.
send
).
toHaveBeenCalled
();
await
new
Promise
(
resolve
=>
view
.
model
.
messages
.
once
(
'
rendered
'
,
resolve
));
const
msg
=
_converse
.
connection
.
send
.
calls
.
all
()[
0
].
args
[
0
];
expect
(
msg
.
toLocaleString
())
.
toBe
(
`<message from="romeo@montague.lit/orchard" id="
${
msg
.
nodeTree
.
getAttribute
(
"
id
"
)}
" `
+
`to="lounge@montague.lit" type="groupchat" `
+
`xmlns="jabber:client">`
+
`<body>But soft, what light through yonder window breaks?</body>`
+
`<active xmlns="http://jabber.org/protocol/chatstates"/>`
+
`<replace id="
${
first_msg
.
get
(
"
msgid
"
)}
" xmlns="urn:xmpp:message-correct:0"/>`
+
`<origin-id id="
${
msg
.
nodeTree
.
querySelector
(
'
origin-id
'
).
getAttribute
(
"
id
"
)}
" xmlns="urn:xmpp:sid:0"/>`
+
`</message>`
);
expect
(
view
.
model
.
messages
.
models
.
length
).
toBe
(
1
);
const
corrected_message
=
view
.
model
.
messages
.
at
(
0
);
expect
(
corrected_message
.
get
(
'
msgid
'
)).
toBe
(
first_msg
.
get
(
'
msgid
'
));
expect
(
corrected_message
.
get
(
'
correcting
'
)).
toBe
(
false
);
const
older_versions
=
corrected_message
.
get
(
'
older_versions
'
);
const
keys
=
Object
.
keys
(
older_versions
);
expect
(
keys
.
length
).
toBe
(
1
);
expect
(
older_versions
[
keys
[
0
]]).
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
u
.
hasClass
(
'
correcting
'
,
view
.
el
.
querySelector
(
'
.chat-msg
'
))).
toBe
(
false
);
// Check that messages from other users are skipped
await
view
.
model
.
handleMessageStanza
(
$msg
({
'
from
'
:
muc_jid
+
'
/someone-else
'
,
'
id
'
:
u
.
getUniqueId
(),
'
to
'
:
'
romeo@montague.lit
'
,
'
type
'
:
'
groupchat
'
}).
c
(
'
body
'
).
t
(
'
Hello world
'
).
tree
());
await
new
Promise
(
resolve
=>
view
.
model
.
messages
.
once
(
'
rendered
'
,
resolve
));
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
2
);
// Test that pressing the down arrow cancels message correction
expect
(
textarea
.
value
).
toBe
(
''
);
view
.
onKeyDown
({
target
:
textarea
,
keyCode
:
38
// Up arrow
});
expect
(
textarea
.
value
).
toBe
(
'
But soft, what light through yonder window breaks?
'
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBe
(
true
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
2
);
await
u
.
waitUntil
(()
=>
u
.
hasClass
(
'
correcting
'
,
view
.
el
.
querySelector
(
'
.chat-msg
'
)),
500
);
expect
(
textarea
.
value
).
toBe
(
'
But soft, what light through yonder window breaks?
'
);
view
.
onKeyDown
({
target
:
textarea
,
keyCode
:
40
// Down arrow
});
expect
(
textarea
.
value
).
toBe
(
''
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBe
(
false
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
2
);
await
u
.
waitUntil
(()
=>
!
u
.
hasClass
(
'
correcting
'
,
view
.
el
.
querySelector
(
'
.chat-msg
'
)),
500
);
done
();
}));
});
spec/messages.js
View file @
ae7b29cb
...
...
@@ -78,289 +78,6 @@ describe("A Chat Message", function () {
done
();
}));
it
(
"
can be sent as a correction by clicking the pencil icon
"
,
mock
.
initConverse
(
[
'
rosterGroupsFetched
'
,
'
chatBoxesFetched
'
],
{},
async
function
(
done
,
_converse
)
{
await
mock
.
waitForRoster
(
_converse
,
'
current
'
,
1
);
await
mock
.
openControlBox
(
_converse
);
const
contact_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@montague.lit
'
;
await
mock
.
openChatBoxFor
(
_converse
,
contact_jid
);
const
view
=
_converse
.
api
.
chatviews
.
get
(
contact_jid
);
const
textarea
=
view
.
el
.
querySelector
(
'
textarea.chat-textarea
'
);
textarea
.
value
=
'
But soft, what light through yonder airlock breaks?
'
;
view
.
onKeyDown
({
target
:
textarea
,
preventDefault
:
function
preventDefault
()
{},
keyCode
:
13
// Enter
});
await
new
Promise
(
resolve
=>
view
.
model
.
messages
.
once
(
'
rendered
'
,
resolve
));
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
view
.
el
.
querySelector
(
'
.chat-msg__text
'
).
textContent
)
.
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
expect
(
textarea
.
value
).
toBe
(
''
);
const
first_msg
=
view
.
model
.
messages
.
findWhere
({
'
message
'
:
'
But soft, what light through yonder airlock breaks?
'
});
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
.chat-msg .chat-msg__action
'
).
length
===
2
);
let
action
=
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg__action
'
);
expect
(
action
.
textContent
.
trim
()).
toBe
(
'
Edit
'
);
action
.
style
.
opacity
=
1
;
action
.
click
();
expect
(
textarea
.
value
).
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBe
(
true
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
await
u
.
waitUntil
(()
=>
u
.
hasClass
(
'
correcting
'
,
view
.
el
.
querySelector
(
'
.chat-msg
'
)));
spyOn
(
_converse
.
connection
,
'
send
'
);
textarea
.
value
=
'
But soft, what light through yonder window breaks?
'
;
view
.
onKeyDown
({
target
:
textarea
,
preventDefault
:
function
preventDefault
()
{},
keyCode
:
13
// Enter
});
expect
(
_converse
.
connection
.
send
).
toHaveBeenCalled
();
const
msg
=
_converse
.
connection
.
send
.
calls
.
all
()[
0
].
args
[
0
];
expect
(
msg
.
toLocaleString
())
.
toBe
(
`<message from="romeo@montague.lit/orchard" id="
${
msg
.
nodeTree
.
getAttribute
(
"
id
"
)}
" `
+
`to="mercutio@montague.lit" type="chat" `
+
`xmlns="jabber:client">`
+
`<body>But soft, what light through yonder window breaks?</body>`
+
`<active xmlns="http://jabber.org/protocol/chatstates"/>`
+
`<request xmlns="urn:xmpp:receipts"/>`
+
`<replace id="
${
first_msg
.
get
(
"
msgid
"
)}
" xmlns="urn:xmpp:message-correct:0"/>`
+
`<origin-id id="
${
msg
.
nodeTree
.
querySelector
(
'
origin-id
'
).
getAttribute
(
"
id
"
)}
" xmlns="urn:xmpp:sid:0"/>`
+
`</message>`
);
expect
(
view
.
model
.
messages
.
models
.
length
).
toBe
(
1
);
const
corrected_message
=
view
.
model
.
messages
.
at
(
0
);
expect
(
corrected_message
.
get
(
'
msgid
'
)).
toBe
(
first_msg
.
get
(
'
msgid
'
));
expect
(
corrected_message
.
get
(
'
correcting
'
)).
toBe
(
false
);
const
older_versions
=
corrected_message
.
get
(
'
older_versions
'
);
const
keys
=
Object
.
keys
(
older_versions
);
expect
(
keys
.
length
).
toBe
(
1
);
expect
(
older_versions
[
keys
[
0
]]).
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
await
u
.
waitUntil
(()
=>
u
.
hasClass
(
'
correcting
'
,
view
.
el
.
querySelector
(
'
.chat-msg
'
))
===
false
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
// Test that clicking the pencil icon a second time cancels editing.
action
=
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg__action
'
);
action
.
style
.
opacity
=
1
;
action
.
click
();
expect
(
textarea
.
value
).
toBe
(
'
But soft, what light through yonder window breaks?
'
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBe
(
true
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
await
u
.
waitUntil
(()
=>
u
.
hasClass
(
'
correcting
'
,
view
.
el
.
querySelector
(
'
.chat-msg
'
))
===
true
);
action
=
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg__action
'
);
action
.
style
.
opacity
=
1
;
action
.
click
();
expect
(
textarea
.
value
).
toBe
(
''
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBe
(
false
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
await
u
.
waitUntil
(()
=>
(
u
.
hasClass
(
'
correcting
'
,
view
.
el
.
querySelector
(
'
.chat-msg
'
))
===
false
),
500
);
// Test that messages from other users don't have the pencil icon
_converse
.
handleMessageStanza
(
$msg
({
'
from
'
:
contact_jid
,
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
chat
'
,
'
id
'
:
u
.
getUniqueId
()
}).
c
(
'
body
'
).
t
(
'
Hello
'
).
up
()
.
c
(
'
active
'
,
{
'
xmlns
'
:
'
http://jabber.org/protocol/chatstates
'
}).
tree
()
);
await
new
Promise
(
resolve
=>
view
.
model
.
messages
.
once
(
'
rendered
'
,
resolve
));
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg .chat-msg__action
'
).
length
).
toBe
(
2
);
// Test confirmation dialog
spyOn
(
window
,
'
confirm
'
).
and
.
returnValue
(
true
);
textarea
.
value
=
'
But soft, what light through yonder airlock breaks?
'
;
action
=
view
.
el
.
querySelector
(
'
.chat-msg .chat-msg__action
'
);
action
.
style
.
opacity
=
1
;
action
.
click
();
expect
(
window
.
confirm
).
toHaveBeenCalledWith
(
'
You have an unsent message which will be lost if you continue. Are you sure?
'
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBe
(
true
);
expect
(
textarea
.
value
).
toBe
(
'
But soft, what light through yonder window breaks?
'
);
textarea
.
value
=
'
But soft, what light through yonder airlock breaks?
'
action
.
click
();
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBe
(
false
);
expect
(
window
.
confirm
.
calls
.
count
()).
toBe
(
2
);
expect
(
window
.
confirm
.
calls
.
argsFor
(
0
)).
toEqual
(
[
'
You have an unsent message which will be lost if you continue. Are you sure?
'
]);
expect
(
window
.
confirm
.
calls
.
argsFor
(
1
)).
toEqual
(
[
'
You have an unsent message which will be lost if you continue. Are you sure?
'
]);
done
();
}));
it
(
"
can be sent as a correction by using the up arrow
"
,
mock
.
initConverse
(
[
'
rosterGroupsFetched
'
,
'
chatBoxesFetched
'
],
{},
async
function
(
done
,
_converse
)
{
await
mock
.
waitForRoster
(
_converse
,
'
current
'
,
1
);
await
mock
.
openControlBox
(
_converse
);
const
contact_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@montague.lit
'
;
await
mock
.
openChatBoxFor
(
_converse
,
contact_jid
)
const
view
=
_converse
.
api
.
chatviews
.
get
(
contact_jid
);
const
textarea
=
view
.
el
.
querySelector
(
'
textarea.chat-textarea
'
);
expect
(
textarea
.
value
).
toBe
(
''
);
view
.
onKeyDown
({
target
:
textarea
,
keyCode
:
38
// Up arrow
});
expect
(
textarea
.
value
).
toBe
(
''
);
textarea
.
value
=
'
But soft, what light through yonder airlock breaks?
'
;
view
.
onKeyDown
({
target
:
textarea
,
preventDefault
:
function
preventDefault
()
{},
keyCode
:
13
// Enter
});
await
new
Promise
(
resolve
=>
view
.
model
.
messages
.
once
(
'
rendered
'
,
resolve
));
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
view
.
el
.
querySelector
(
'
.chat-msg__text
'
).
textContent
)
.
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
const
first_msg
=
view
.
model
.
messages
.
findWhere
({
'
message
'
:
'
But soft, what light through yonder airlock breaks?
'
});
expect
(
textarea
.
value
).
toBe
(
''
);
view
.
onKeyDown
({
target
:
textarea
,
keyCode
:
38
// Up arrow
});
expect
(
textarea
.
value
).
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBe
(
true
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
await
u
.
waitUntil
(()
=>
u
.
hasClass
(
'
correcting
'
,
view
.
el
.
querySelector
(
'
.chat-msg
'
)),
500
);
spyOn
(
_converse
.
connection
,
'
send
'
);
textarea
.
value
=
'
But soft, what light through yonder window breaks?
'
;
view
.
onKeyDown
({
target
:
textarea
,
preventDefault
:
function
preventDefault
()
{},
keyCode
:
13
// Enter
});
expect
(
_converse
.
connection
.
send
).
toHaveBeenCalled
();
await
new
Promise
(
resolve
=>
view
.
model
.
messages
.
once
(
'
rendered
'
,
resolve
));
const
msg
=
_converse
.
connection
.
send
.
calls
.
all
()[
0
].
args
[
0
];
expect
(
msg
.
toLocaleString
())
.
toBe
(
`<message from="romeo@montague.lit/orchard" id="
${
msg
.
nodeTree
.
getAttribute
(
"
id
"
)}
" `
+
`to="mercutio@montague.lit" type="chat" `
+
`xmlns="jabber:client">`
+
`<body>But soft, what light through yonder window breaks?</body>`
+
`<active xmlns="http://jabber.org/protocol/chatstates"/>`
+
`<request xmlns="urn:xmpp:receipts"/>`
+
`<replace id="
${
first_msg
.
get
(
"
msgid
"
)}
" xmlns="urn:xmpp:message-correct:0"/>`
+
`<origin-id id="
${
msg
.
nodeTree
.
querySelector
(
'
origin-id
'
).
getAttribute
(
"
id
"
)}
" xmlns="urn:xmpp:sid:0"/>`
+
`</message>`
);
expect
(
view
.
model
.
messages
.
models
.
length
).
toBe
(
1
);
const
corrected_message
=
view
.
model
.
messages
.
at
(
0
);
expect
(
corrected_message
.
get
(
'
msgid
'
)).
toBe
(
first_msg
.
get
(
'
msgid
'
));
expect
(
corrected_message
.
get
(
'
correcting
'
)).
toBe
(
false
);
const
older_versions
=
corrected_message
.
get
(
'
older_versions
'
);
const
keys
=
Object
.
keys
(
older_versions
);
expect
(
keys
.
length
).
toBe
(
1
);
expect
(
older_versions
[
keys
[
0
]]).
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
await
u
.
waitUntil
(()
=>
(
u
.
hasClass
(
'
correcting
'
,
view
.
el
.
querySelector
(
'
.chat-msg
'
))
===
false
),
500
);
// Test that pressing the down arrow cancels message correction
expect
(
textarea
.
value
).
toBe
(
''
);
view
.
onKeyDown
({
target
:
textarea
,
keyCode
:
38
// Up arrow
});
expect
(
textarea
.
value
).
toBe
(
'
But soft, what light through yonder window breaks?
'
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBe
(
true
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
await
u
.
waitUntil
(()
=>
u
.
hasClass
(
'
correcting
'
,
view
.
el
.
querySelector
(
'
.chat-msg
'
)),
500
);
expect
(
textarea
.
value
).
toBe
(
'
But soft, what light through yonder window breaks?
'
);
view
.
onKeyDown
({
target
:
textarea
,
keyCode
:
40
// Down arrow
});
expect
(
textarea
.
value
).
toBe
(
''
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBe
(
false
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
await
u
.
waitUntil
(()
=>
(
u
.
hasClass
(
'
correcting
'
,
view
.
el
.
querySelector
(
'
.chat-msg
'
))
===
false
),
500
);
textarea
.
value
=
'
It is the east, and Juliet is the one.
'
;
view
.
onKeyDown
({
target
:
textarea
,
preventDefault
:
function
preventDefault
()
{},
keyCode
:
13
// Enter
});
await
new
Promise
(
resolve
=>
view
.
model
.
messages
.
once
(
'
rendered
'
,
resolve
));
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
2
);
textarea
.
value
=
'
Arise, fair sun, and kill the envious moon
'
;
view
.
onKeyDown
({
target
:
textarea
,
preventDefault
:
function
preventDefault
()
{},
keyCode
:
13
// Enter
});
await
new
Promise
(
resolve
=>
view
.
model
.
messages
.
once
(
'
rendered
'
,
resolve
));
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
3
);
view
.
onKeyDown
({
target
:
textarea
,
keyCode
:
38
// Up arrow
});
expect
(
textarea
.
value
).
toBe
(
'
Arise, fair sun, and kill the envious moon
'
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBeFalsy
();
expect
(
view
.
model
.
messages
.
at
(
1
).
get
(
'
correcting
'
)).
toBeFalsy
();
expect
(
view
.
model
.
messages
.
at
(
2
).
get
(
'
correcting
'
)).
toBe
(
true
);
await
u
.
waitUntil
(()
=>
u
.
hasClass
(
'
correcting
'
,
sizzle
(
'
.chat-msg:last
'
,
view
.
el
).
pop
()),
500
);
textarea
.
selectionEnd
=
0
;
// Happens by pressing up,
// but for some reason not in tests, so we set it manually.
view
.
onKeyDown
({
target
:
textarea
,
keyCode
:
38
// Up arrow
});
expect
(
textarea
.
value
).
toBe
(
'
It is the east, and Juliet is the one.
'
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBeFalsy
();
expect
(
view
.
model
.
messages
.
at
(
1
).
get
(
'
correcting
'
)).
toBe
(
true
);
expect
(
view
.
model
.
messages
.
at
(
2
).
get
(
'
correcting
'
)).
toBeFalsy
();
await
u
.
waitUntil
(()
=>
u
.
hasClass
(
'
correcting
'
,
sizzle
(
'
.chat-msg
'
,
view
.
el
)[
1
]),
500
);
textarea
.
value
=
'
It is the east, and Juliet is the sun.
'
;
view
.
onKeyDown
({
target
:
textarea
,
preventDefault
:
function
preventDefault
()
{},
keyCode
:
13
// Enter
});
await
new
Promise
(
resolve
=>
view
.
model
.
messages
.
once
(
'
rendered
'
,
resolve
));
await
u
.
waitUntil
(()
=>
textarea
.
value
===
''
);
const
messages
=
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
);
expect
(
messages
.
length
).
toBe
(
3
);
expect
(
messages
[
0
].
querySelector
(
'
.chat-msg__text
'
).
textContent
)
.
toBe
(
'
But soft, what light through yonder window breaks?
'
);
expect
(
messages
[
1
].
querySelector
(
'
.chat-msg__text
'
).
textContent
)
.
toBe
(
'
It is the east, and Juliet is the sun.
'
);
expect
(
messages
[
2
].
querySelector
(
'
.chat-msg__text
'
).
textContent
)
.
toBe
(
'
Arise, fair sun, and kill the envious moon
'
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBeFalsy
();
expect
(
view
.
model
.
messages
.
at
(
1
).
get
(
'
correcting
'
)).
toBeFalsy
();
expect
(
view
.
model
.
messages
.
at
(
2
).
get
(
'
correcting
'
)).
toBeFalsy
();
done
();
}));
it
(
"
can be received out of order, and will still be displayed in the right order
"
,
mock
.
initConverse
(
[
'
rosterGroupsFetched
'
],
{},
...
...
@@ -1307,67 +1024,6 @@ describe("A Chat Message", function () {
}));
it
(
"
can be replaced with a correction
"
,
mock
.
initConverse
(
[
'
rosterGroupsFetched
'
,
'
chatBoxesFetched
'
],
{},
async
function
(
done
,
_converse
)
{
await
mock
.
waitForRoster
(
_converse
,
'
current
'
,
1
);
await
mock
.
openControlBox
(
_converse
);
const
sender_jid
=
mock
.
cur_names
[
0
].
replace
(
/ /g
,
'
.
'
).
toLowerCase
()
+
'
@montague.lit
'
;
const
msg_id
=
u
.
getUniqueId
();
const
view
=
await
mock
.
openChatBoxFor
(
_converse
,
sender_jid
);
_converse
.
handleMessageStanza
(
$msg
({
'
from
'
:
sender_jid
,
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
chat
'
,
'
id
'
:
msg_id
,
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder airlock breaks?
'
).
tree
());
await
new
Promise
(
resolve
=>
view
.
model
.
messages
.
once
(
'
rendered
'
,
resolve
));
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
view
.
el
.
querySelector
(
'
.chat-msg__text
'
).
textContent
)
.
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
_converse
.
handleMessageStanza
(
$msg
({
'
from
'
:
sender_jid
,
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
chat
'
,
'
id
'
:
u
.
getUniqueId
(),
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder chimney breaks?
'
).
up
()
.
c
(
'
replace
'
,
{
'
id
'
:
msg_id
,
'
xmlns
'
:
'
urn:xmpp:message-correct:0
'
}).
tree
());
await
new
Promise
(
resolve
=>
view
.
model
.
messages
.
once
(
'
rendered
'
,
resolve
));
expect
(
view
.
el
.
querySelector
(
'
.chat-msg__text
'
).
textContent
)
.
toBe
(
'
But soft, what light through yonder chimney breaks?
'
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg__content .fa-edit
'
).
length
).
toBe
(
1
);
expect
(
view
.
model
.
messages
.
models
.
length
).
toBe
(
1
);
_converse
.
handleMessageStanza
(
$msg
({
'
from
'
:
sender_jid
,
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
chat
'
,
'
id
'
:
u
.
getUniqueId
(),
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder window breaks?
'
).
up
()
.
c
(
'
replace
'
,
{
'
id
'
:
msg_id
,
'
xmlns
'
:
'
urn:xmpp:message-correct:0
'
}).
tree
());
await
new
Promise
(
resolve
=>
view
.
model
.
messages
.
once
(
'
rendered
'
,
resolve
));
expect
(
view
.
el
.
querySelector
(
'
.chat-msg__text
'
).
textContent
)
.
toBe
(
'
But soft, what light through yonder window breaks?
'
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg__content .fa-edit
'
).
length
).
toBe
(
1
);
view
.
el
.
querySelector
(
'
.chat-msg__content .fa-edit
'
).
click
();
const
modal
=
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelector
(
'
converse-chat-message
'
).
message_versions_modal
);
await
u
.
waitUntil
(()
=>
u
.
isVisible
(
modal
.
el
),
1000
);
const
older_msgs
=
modal
.
el
.
querySelectorAll
(
'
.older-msg
'
);
expect
(
older_msgs
.
length
).
toBe
(
2
);
expect
(
older_msgs
[
0
].
childNodes
[
0
].
nodeName
).
toBe
(
'
TIME
'
);
expect
(
older_msgs
[
0
].
childNodes
[
2
].
textContent
).
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
expect
(
view
.
model
.
messages
.
models
.
length
).
toBe
(
1
);
done
();
}));
describe
(
"
when a chatbox is opened for someone who is not in the roster
"
,
function
()
{
it
(
"
the VCard for that user is fetched and the chatbox updated with the results
"
,
...
...
spec/muc_messages.js
View file @
ae7b29cb
...
...
@@ -523,274 +523,6 @@ describe("A Groupchat Message", function () {
done
();
}));
it
(
"
can be replaced with a correction
"
,
mock
.
initConverse
(
[
'
rosterGroupsFetched
'
],
{},
async
function
(
done
,
_converse
)
{
const
muc_jid
=
'
lounge@montague.lit
'
;
await
mock
.
openAndEnterChatRoom
(
_converse
,
muc_jid
,
'
romeo
'
);
const
view
=
_converse
.
api
.
chatviews
.
get
(
muc_jid
);
const
stanza
=
$pres
({
to
:
'
romeo@montague.lit/_converse.js-29092160
'
,
from
:
'
coven@chat.shakespeare.lit/newguy
'
})
.
c
(
'
x
'
,
{
xmlns
:
Strophe
.
NS
.
MUC_USER
})
.
c
(
'
item
'
,
{
'
affiliation
'
:
'
none
'
,
'
jid
'
:
'
newguy@montague.lit/_converse.js-290929789
'
,
'
role
'
:
'
participant
'
}).
tree
();
_converse
.
connection
.
_dataRecv
(
mock
.
createRequest
(
stanza
));
const
msg_id
=
u
.
getUniqueId
();
await
view
.
model
.
handleMessageStanza
(
$msg
({
'
from
'
:
'
lounge@montague.lit/newguy
'
,
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
groupchat
'
,
'
id
'
:
msg_id
,
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder airlock breaks?
'
).
tree
());
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
view
.
el
.
querySelector
(
'
.chat-msg__text
'
).
textContent
)
.
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
await
view
.
model
.
handleMessageStanza
(
$msg
({
'
from
'
:
'
lounge@montague.lit/newguy
'
,
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
groupchat
'
,
'
id
'
:
u
.
getUniqueId
(),
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder chimney breaks?
'
).
up
()
.
c
(
'
replace
'
,
{
'
id
'
:
msg_id
,
'
xmlns
'
:
'
urn:xmpp:message-correct:0
'
}).
tree
());
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelector
(
'
.chat-msg__text
'
).
textContent
===
'
But soft, what light through yonder chimney breaks?
'
,
500
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelector
(
'
.chat-msg__content .fa-edit
'
));
await
view
.
model
.
handleMessageStanza
(
$msg
({
'
from
'
:
'
lounge@montague.lit/newguy
'
,
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
groupchat
'
,
'
id
'
:
u
.
getUniqueId
(),
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder window breaks?
'
).
up
()
.
c
(
'
replace
'
,
{
'
id
'
:
msg_id
,
'
xmlns
'
:
'
urn:xmpp:message-correct:0
'
}).
tree
());
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelector
(
'
.chat-msg__text
'
).
textContent
===
'
But soft, what light through yonder window breaks?
'
,
500
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg__content .fa-edit
'
).
length
).
toBe
(
1
);
const
edit
=
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelector
(
'
.chat-msg__content .fa-edit
'
));
edit
.
click
();
const
modal
=
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelector
(
'
converse-chat-message
'
).
message_versions_modal
);
await
u
.
waitUntil
(()
=>
u
.
isVisible
(
modal
.
el
),
1000
);
const
older_msgs
=
modal
.
el
.
querySelectorAll
(
'
.older-msg
'
);
expect
(
older_msgs
.
length
).
toBe
(
2
);
expect
(
older_msgs
[
0
].
childNodes
[
2
].
textContent
).
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
expect
(
older_msgs
[
0
].
childNodes
[
0
].
nodeName
).
toBe
(
'
TIME
'
);
expect
(
older_msgs
[
1
].
childNodes
[
0
].
nodeName
).
toBe
(
'
TIME
'
);
expect
(
older_msgs
[
1
].
childNodes
[
2
].
textContent
).
toBe
(
'
But soft, what light through yonder chimney breaks?
'
);
done
();
}));
it
(
"
keeps the same position in history after a correction
"
,
mock
.
initConverse
(
[
'
rosterGroupsFetched
'
],
{},
async
function
(
done
,
_converse
)
{
const
muc_jid
=
'
lounge@montague.lit
'
;
await
mock
.
openAndEnterChatRoom
(
_converse
,
muc_jid
,
'
romeo
'
);
const
view
=
_converse
.
api
.
chatviews
.
get
(
muc_jid
);
const
stanza
=
$pres
({
to
:
'
romeo@montague.lit/_converse.js-29092160
'
,
from
:
'
coven@chat.shakespeare.lit/newguy
'
})
.
c
(
'
x
'
,
{
xmlns
:
Strophe
.
NS
.
MUC_USER
})
.
c
(
'
item
'
,
{
'
affiliation
'
:
'
none
'
,
'
jid
'
:
'
newguy@montague.lit/_converse.js-290929789
'
,
'
role
'
:
'
participant
'
}).
tree
();
_converse
.
connection
.
_dataRecv
(
mock
.
createRequest
(
stanza
));
const
msg_id
=
u
.
getUniqueId
();
// Receiving the first message
await
view
.
model
.
handleMessageStanza
(
$msg
({
'
from
'
:
'
lounge@montague.lit/newguy
'
,
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
groupchat
'
,
'
id
'
:
msg_id
,
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder airlock breaks?
'
).
tree
());
// Receiving own message to check order against
await
view
.
model
.
handleMessageStanza
(
$msg
({
'
from
'
:
'
lounge@montague.lit/romeo
'
,
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
groupchat
'
,
'
id
'
:
msg_id
,
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder airlock breaks?
'
).
tree
());
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
===
2
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
2
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg__text
'
)[
0
].
textContent
)
.
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg__text
'
)[
1
].
textContent
)
.
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
// First message correction
await
view
.
model
.
handleMessageStanza
(
$msg
({
'
from
'
:
'
lounge@montague.lit/newguy
'
,
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
groupchat
'
,
'
id
'
:
u
.
getUniqueId
(),
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder chimney breaks?
'
).
up
()
.
c
(
'
replace
'
,
{
'
id
'
:
msg_id
,
'
xmlns
'
:
'
urn:xmpp:message-correct:0
'
}).
tree
());
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelector
(
'
.chat-msg__text
'
).
textContent
===
'
But soft, what light through yonder chimney breaks?
'
,
500
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
2
);
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelector
(
'
.chat-msg__content .fa-edit
'
));
// Second message correction
await
view
.
model
.
handleMessageStanza
(
$msg
({
'
from
'
:
'
lounge@montague.lit/newguy
'
,
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
groupchat
'
,
'
id
'
:
u
.
getUniqueId
(),
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder window breaks?
'
).
up
()
.
c
(
'
replace
'
,
{
'
id
'
:
msg_id
,
'
xmlns
'
:
'
urn:xmpp:message-correct:0
'
}).
tree
());
// Second own message
await
view
.
model
.
handleMessageStanza
(
$msg
({
'
from
'
:
'
lounge@montague.lit/romeo
'
,
'
to
'
:
_converse
.
connection
.
jid
,
'
type
'
:
'
groupchat
'
,
'
id
'
:
u
.
getUniqueId
(),
}).
c
(
'
body
'
).
t
(
'
But soft, what light through yonder window breaks?
'
).
tree
());
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
.chat-msg__text
'
)[
0
].
textContent
===
'
But soft, what light through yonder window breaks?
'
,
500
);
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
.chat-msg__text
'
).
length
===
3
);
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
.chat-msg__text
'
)[
2
].
textContent
===
'
But soft, what light through yonder window breaks?
'
,
500
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
3
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg__content .fa-edit
'
).
length
).
toBe
(
1
);
const
edit
=
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelector
(
'
.chat-msg__content .fa-edit
'
));
edit
.
click
();
const
modal
=
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
converse-chat-message
'
)[
0
].
message_versions_modal
);
await
u
.
waitUntil
(()
=>
u
.
isVisible
(
modal
.
el
),
1000
);
const
older_msgs
=
modal
.
el
.
querySelectorAll
(
'
.older-msg
'
);
expect
(
older_msgs
.
length
).
toBe
(
2
);
expect
(
older_msgs
[
0
].
childNodes
[
2
].
textContent
).
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
expect
(
older_msgs
[
0
].
childNodes
[
0
].
nodeName
).
toBe
(
'
TIME
'
);
expect
(
older_msgs
[
1
].
childNodes
[
0
].
nodeName
).
toBe
(
'
TIME
'
);
expect
(
older_msgs
[
1
].
childNodes
[
2
].
textContent
).
toBe
(
'
But soft, what light through yonder chimney breaks?
'
);
done
();
}));
it
(
"
can be sent as a correction by using the up arrow
"
,
mock
.
initConverse
(
[
'
rosterGroupsFetched
'
],
{},
async
function
(
done
,
_converse
)
{
const
muc_jid
=
'
lounge@montague.lit
'
;
await
mock
.
openAndEnterChatRoom
(
_converse
,
muc_jid
,
'
romeo
'
);
const
view
=
_converse
.
api
.
chatviews
.
get
(
muc_jid
);
const
textarea
=
view
.
el
.
querySelector
(
'
textarea.chat-textarea
'
);
expect
(
textarea
.
value
).
toBe
(
''
);
view
.
onKeyDown
({
target
:
textarea
,
keyCode
:
38
// Up arrow
});
expect
(
textarea
.
value
).
toBe
(
''
);
textarea
.
value
=
'
But soft, what light through yonder airlock breaks?
'
;
view
.
onKeyDown
({
target
:
textarea
,
preventDefault
:
function
preventDefault
()
{},
keyCode
:
13
// Enter
});
await
u
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
===
1
);
expect
(
view
.
el
.
querySelector
(
'
.chat-msg__text
'
).
textContent
)
.
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
const
first_msg
=
view
.
model
.
messages
.
findWhere
({
'
message
'
:
'
But soft, what light through yonder airlock breaks?
'
});
expect
(
textarea
.
value
).
toBe
(
''
);
view
.
onKeyDown
({
target
:
textarea
,
keyCode
:
38
// Up arrow
});
expect
(
textarea
.
value
).
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBe
(
true
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
await
u
.
waitUntil
(()
=>
u
.
hasClass
(
'
correcting
'
,
view
.
el
.
querySelector
(
'
.chat-msg
'
)));
spyOn
(
_converse
.
connection
,
'
send
'
);
textarea
.
value
=
'
But soft, what light through yonder window breaks?
'
;
view
.
onKeyDown
({
target
:
textarea
,
preventDefault
:
function
preventDefault
()
{},
keyCode
:
13
// Enter
});
expect
(
_converse
.
connection
.
send
).
toHaveBeenCalled
();
await
new
Promise
(
resolve
=>
view
.
model
.
messages
.
once
(
'
rendered
'
,
resolve
));
const
msg
=
_converse
.
connection
.
send
.
calls
.
all
()[
0
].
args
[
0
];
expect
(
msg
.
toLocaleString
())
.
toBe
(
`<message from="romeo@montague.lit/orchard" id="
${
msg
.
nodeTree
.
getAttribute
(
"
id
"
)}
" `
+
`to="lounge@montague.lit" type="groupchat" `
+
`xmlns="jabber:client">`
+
`<body>But soft, what light through yonder window breaks?</body>`
+
`<active xmlns="http://jabber.org/protocol/chatstates"/>`
+
`<replace id="
${
first_msg
.
get
(
"
msgid
"
)}
" xmlns="urn:xmpp:message-correct:0"/>`
+
`<origin-id id="
${
msg
.
nodeTree
.
querySelector
(
'
origin-id
'
).
getAttribute
(
"
id
"
)}
" xmlns="urn:xmpp:sid:0"/>`
+
`</message>`
);
expect
(
view
.
model
.
messages
.
models
.
length
).
toBe
(
1
);
const
corrected_message
=
view
.
model
.
messages
.
at
(
0
);
expect
(
corrected_message
.
get
(
'
msgid
'
)).
toBe
(
first_msg
.
get
(
'
msgid
'
));
expect
(
corrected_message
.
get
(
'
correcting
'
)).
toBe
(
false
);
const
older_versions
=
corrected_message
.
get
(
'
older_versions
'
);
const
keys
=
Object
.
keys
(
older_versions
);
expect
(
keys
.
length
).
toBe
(
1
);
expect
(
older_versions
[
keys
[
0
]]).
toBe
(
'
But soft, what light through yonder airlock breaks?
'
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
u
.
hasClass
(
'
correcting
'
,
view
.
el
.
querySelector
(
'
.chat-msg
'
))).
toBe
(
false
);
// Check that messages from other users are skipped
await
view
.
model
.
handleMessageStanza
(
$msg
({
'
from
'
:
muc_jid
+
'
/someone-else
'
,
'
id
'
:
u
.
getUniqueId
(),
'
to
'
:
'
romeo@montague.lit
'
,
'
type
'
:
'
groupchat
'
}).
c
(
'
body
'
).
t
(
'
Hello world
'
).
tree
());
await
new
Promise
(
resolve
=>
view
.
model
.
messages
.
once
(
'
rendered
'
,
resolve
));
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
2
);
// Test that pressing the down arrow cancels message correction
expect
(
textarea
.
value
).
toBe
(
''
);
view
.
onKeyDown
({
target
:
textarea
,
keyCode
:
38
// Up arrow
});
expect
(
textarea
.
value
).
toBe
(
'
But soft, what light through yonder window breaks?
'
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBe
(
true
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
2
);
await
u
.
waitUntil
(()
=>
u
.
hasClass
(
'
correcting
'
,
view
.
el
.
querySelector
(
'
.chat-msg
'
)),
500
);
expect
(
textarea
.
value
).
toBe
(
'
But soft, what light through yonder window breaks?
'
);
view
.
onKeyDown
({
target
:
textarea
,
keyCode
:
40
// Down arrow
});
expect
(
textarea
.
value
).
toBe
(
''
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
correcting
'
)).
toBe
(
false
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
2
);
await
u
.
waitUntil
(()
=>
!
u
.
hasClass
(
'
correcting
'
,
view
.
el
.
querySelector
(
'
.chat-msg
'
)),
500
);
done
();
}));
it
(
"
will be shown as received upon MUC reflection
"
,
mock
.
initConverse
(
[
'
rosterGroupsFetched
'
],
{},
...
...
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