Commit 025cdbf1 authored by JC Brand's avatar JC Brand

Check for support before allowing message moderation

parent ad77ba60
......@@ -48,7 +48,8 @@
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit';
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
const features = [...mock.default_muc_features, Strophe.NS.MODERATE];
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo', features);
const received_stanza = u.toStanza(`
<message to='${_converse.jid}' from='${muc_jid}/eve' type='groupchat' id='${_converse.connection.getUniqueId()}'>
......@@ -92,7 +93,8 @@
const date = (new Date()).toISOString();
const muc_jid = 'lounge@montague.lit';
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
const features = [...mock.default_muc_features, Strophe.NS.MODERATE];
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo', features);
const retraction_stanza = u.toStanza(`
<message type="groupchat" id='retraction-id-1' from="${muc_jid}/eve" to="${muc_jid}/romeo">
......@@ -321,7 +323,8 @@
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit';
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
const features = [...mock.default_muc_features, Strophe.NS.MODERATE];
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo', features);
const received_stanza = u.toStanza(`
<message to='${_converse.jid}' from='${muc_jid}/eve' type='groupchat' id='${_converse.connection.getUniqueId()}'>
......@@ -363,7 +366,9 @@
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit';
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
const features = [...mock.default_muc_features, Strophe.NS.MODERATE];
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo', features);
const view = _converse.api.chatviews.get(muc_jid);
const occupant = view.model.getOwnOccupant();
expect(occupant.get('role')).toBe('moderator');
......@@ -439,6 +444,31 @@
done();
}));
it("can not be retracted if the MUC doesn't support message moderation",
mock.initConverse(
['rosterGroupsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit';
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
const view = _converse.api.chatviews.get(muc_jid);
const occupant = view.model.getOwnOccupant();
expect(occupant.get('role')).toBe('moderator');
const received_stanza = u.toStanza(`
<message to='${_converse.jid}' from='${muc_jid}/mallory' type='groupchat' id='${_converse.connection.getUniqueId()}'>
<body>Visit this site to get free Bitcoin!</body>
<stanza-id xmlns='urn:xmpp:sid:0' id='stanza-id-1' by='${muc_jid}'/>
</message>
`);
await view.model.onMessage(received_stanza);
await u.waitUntil(() => view.el.querySelector('.chat-msg__content'));
expect(view.el.querySelector('.chat-msg__content .chat-msg__action-retract')).toBe(null);
const result = await view.model.canRetractMessages();
expect(result).toBe(false);
done();
}));
it("can be retracted by a moderator, with the retraction message received before the IQ response",
mock.initConverse(
......@@ -446,7 +476,8 @@
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit';
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
const features = [...mock.default_muc_features, Strophe.NS.MODERATE];
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo', features);
const view = _converse.api.chatviews.get(muc_jid);
const occupant = view.model.getOwnOccupant();
expect(occupant.get('role')).toBe('moderator');
......@@ -514,7 +545,8 @@
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit';
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
const features = [...mock.default_muc_features, Strophe.NS.MODERATE];
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo', features);
const view = _converse.api.chatviews.get(muc_jid);
const occupant = view.model.getOwnOccupant();
expect(occupant.get('role')).toBe('moderator');
......@@ -565,7 +597,8 @@
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit';
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
const features = [...mock.default_muc_features, Strophe.NS.MODERATE];
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo', features);
const view = _converse.api.chatviews.get(muc_jid);
const occupant = view.model.getOwnOccupant();
expect(occupant.get('role')).toBe('moderator');
......@@ -615,7 +648,8 @@
_converse.STANZA_TIMEOUT = 1;
const muc_jid = 'lounge@montague.lit';
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
const features = [...mock.default_muc_features, Strophe.NS.MODERATE];
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo', features);
const view = _converse.api.chatviews.get(muc_jid);
const occupant = view.model.getOwnOccupant();
expect(occupant.get('role')).toBe('moderator');
......@@ -740,7 +774,8 @@
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit';
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
const features = [...mock.default_muc_features, Strophe.NS.MODERATE];
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo', features);
const view = _converse.chatboxviews.get(muc_jid);
const sent_IQs = _converse.connection.IQ_stanzas;
......@@ -816,7 +851,8 @@
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit';
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
const features = [...mock.default_muc_features, Strophe.NS.MODERATE];
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo', features);
const view = _converse.chatboxviews.get(muc_jid);
const sent_IQs = _converse.connection.IQ_stanzas;
......
......@@ -242,15 +242,19 @@ converse.plugins.add('converse-message-view', {
const role = this.model.vcard ? this.model.vcard.get('role') : null;
const roles = role ? role.split(',') : [];
const is_retracted = this.model.get('retracted') || this.model.get('moderated') === 'retracted';
const is_groupchat_message = this.model.get('type') === 'groupchat';
const is_own_message = this.model.get('sender') === 'me';
const chatbox = this.model.collection.chatbox;
const retractable= is_groupchat_message ? await chatbox.canRetractMessages() : is_own_message;
const msg = u.stringToElement(tpl_message(
Object.assign(
this.model.toJSON(), {
__,
is_groupchat_message,
is_retracted,
'extra_classes': this.getExtraMessageClasses(),
'is_groupchat_message': this.model.get('type') === 'groupchat',
retractable,
'is_me_message': this.model.isMeCommand(),
'extra_classes': this.getExtraMessageClasses(),
'label_show': __('Show more'),
'occupant': this.model.occupant,
'pretty_time': time.format(_converse.time_format),
......
......@@ -707,6 +707,11 @@ converse.plugins.add('converse-muc', {
return _converse.ChatBox.prototype.close.call(this);
},
canRetractMessages () {
const self = this.getOwnOccupant();
return self && self.isModerator() && _converse.api.disco.supports(Strophe.NS.MODERATE, this.get('jid'));
},
sendUnavailablePresence (exit_msg) {
const presence = $pres({
type: "unavailable",
......
......@@ -41,8 +41,7 @@
{[ if (o.editable) { ]}
<button class="chat-msg__action chat-msg__action-edit fa fa-pencil-alt" title="{{{o.__('Edit this message')}}}"></button>
{[ } ]}
<!-- FIXME -->
{[ if ((o.sender === 'me' || o.is_groupchat_message) && true) { ]}
{[ if (o.retractable) { ]}
<button class="chat-msg__action chat-msg__action-retract fa fa-trash-alt" title="{{{o.__('Retract this message')}}}"></button>
{[ } ]}
</div>
......
......@@ -69,6 +69,20 @@
};
const mock = {};
mock.default_muc_features = [
'http://jabber.org/protocol/muc',
'jabber:iq:register',
Strophe.NS.SID,
Strophe.NS.MAM,
'muc_passwordprotected',
'muc_hidden',
'muc_temporary',
'muc_open',
'muc_unmoderated',
'muc_anonymous'
];
mock.view_mode = 'overlayed';
// Names from http://www.fakenamegenerator.com/
......
......@@ -167,17 +167,7 @@
'type': 'text'
}).up();
features = features.length ? features : [
'http://jabber.org/protocol/muc',
'jabber:iq:register',
Strophe.NS.SID,
Strophe.NS.MAM,
'muc_passwordprotected',
'muc_hidden',
'muc_temporary',
'muc_open',
'muc_unmoderated',
'muc_anonymous']
features = features.length ? features : mock.default_muc_features;
features.forEach(f => features_stanza.c('feature', {'var': f}).up());
features_stanza.c('x', { 'xmlns':'jabber:x:data', 'type':'result'})
.c('field', {'var':'FORM_TYPE', 'type':'hidden'})
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment