diff --git a/CHANGES.md b/CHANGES.md
index 6fecb219c..ff054a503 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -8,6 +8,8 @@
- Remove the `converse-carbons` plugin and make carbons part of the `converse-chat` plugin.
- Remove the `message_carbons` configuration setting. Carbons are now always enabled.
- Move the `converse-oauth` plugin to the [community-plugins](https://github.com/conversejs/community-plugins)
+- Don't apply message corrections when the MUC occupant-id doesn't match.
+- Update `nick` attribute on ChatRoom when user nickname changes
- #2936: Fix documentation about enable_smacks option, which is true by default.
## 9.1.1 (2022-05-05)
diff --git a/src/headless/plugins/muc/muc.js b/src/headless/plugins/muc/muc.js
index 144113e29..51f1fe608 100644
--- a/src/headless/plugins/muc/muc.js
+++ b/src/headless/plugins/muc/muc.js
@@ -1727,6 +1727,10 @@ const ChatRoomMixin = {
'resource': Strophe.getResourceFromJid(jid) || occupant?.attributes?.resource
}
+ if (data.is_me && data.states.includes(converse.MUC_NICK_CHANGED_CODE)) {
+ this.save('nick', data.nick);
+ }
+
if (occupant) {
occupant.save(attributes);
} else {
diff --git a/src/headless/plugins/muc/parsers.js b/src/headless/plugins/muc/parsers.js
index 352d779c2..6fc52fe60 100644
--- a/src/headless/plugins/muc/parsers.js
+++ b/src/headless/plugins/muc/parsers.js
@@ -343,6 +343,7 @@ export function parseMUCPresence (stanza, chatbox) {
const from = stanza.getAttribute('from');
const type = stanza.getAttribute('type');
const data = {
+ 'is_me': !!stanza.querySelector("status[code='110']"),
'from': from,
'occupant_id': getOccupantID(stanza, chatbox),
'nick': Strophe.getResourceFromJid(from),
@@ -351,6 +352,7 @@ export function parseMUCPresence (stanza, chatbox) {
'hats': [],
'show': type !== 'unavailable' ? 'online' : 'offline'
};
+
Array.from(stanza.children).forEach(child => {
if (child.matches('status')) {
data.status = child.textContent || null;
diff --git a/src/plugins/muc-views/tests/nickname.js b/src/plugins/muc-views/tests/nickname.js
index 152f1ed5e..574e2a8c0 100644
--- a/src/plugins/muc-views/tests/nickname.js
+++ b/src/plugins/muc-views/tests/nickname.js
@@ -1,15 +1,20 @@
/*global mock, converse */
-const { $pres, $iq, Strophe, sizzle, u } = converse.env;
+const { $pres, $iq, Strophe, sizzle, u } = converse.env;
describe("A MUC", function () {
it("allows you to change your nickname via a modal",
mock.initConverse([], {'view_mode': 'fullscreen'}, async function (_converse) {
+ const { stanza } = converse.env;
const muc_jid = 'lounge@montague.lit';
const nick = 'romeo';
- await mock.openAndEnterChatRoom(_converse, muc_jid, nick);
+ const model = await mock.openAndEnterChatRoom(_converse, muc_jid, nick);
+
+ expect(model.get('nick')).toBe(nick);
+ expect(model.occupants.length).toBe(1);
+ expect(model.occupants.at(0).get('nick')).toBe(nick);
const view = _converse.chatboxviews.get(muc_jid);
const dropdown_item = view.querySelector(".open-nickname-modal");
@@ -31,6 +36,45 @@ describe("A MUC", function () {
const sent_stanza = sent_stanzas.pop()
expect(Strophe.serialize(sent_stanza).toLocaleString()).toBe(
``);
+
+ // Two presence stanzas are received from the MUC service
+ _converse.connection._dataRecv(mock.createRequest(
+ stanza`
+
+
+
+
+
+
+ `
+ ));
+
+ expect(model.get('nick')).toBe(newnick);
+
+ _converse.connection._dataRecv(mock.createRequest(
+ stanza`
+
+
+
+
+
+ `
+ ));
+
+ await u.waitUntil(() => model.occupants.at(0).get('nick') === newnick);
+ expect(model.occupants.length).toBe(1);
}));
it("informs users if their nicknames have been changed.",
@@ -71,7 +115,7 @@ describe("A MUC", function () {
*
*
*/
- const __ = _converse.__;
+ const { __ } = _converse;
await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'oldnick');
const view = _converse.chatboxviews.get('lounge@montague.lit');
@@ -130,8 +174,9 @@ describe("A MUC", function () {
__(_converse.muc.new_nickname_messages["303"], "newnick")
);
occupants = view.querySelector('.occupant-list');
- expect(occupants.childElementCount).toBe(1);
- expect(sizzle('.occupant-nick:first', occupants).pop().textContent.trim()).toBe("newnick");
+ await u.waitUntil(() => sizzle('.occupant-nick:first', occupants).pop().textContent.trim() === "newnick");
+ expect(view.model.occupants.length).toBe(1);
+ expect(view.model.get('nick')).toBe("newnick");
}));
describe("when being entered", function () {
@@ -423,4 +468,3 @@ describe("A MUC", function () {
}));
});
});
-