muc-views: Present challenge to destroy confirmation

And also allow the user to specify the JID to where the conversation has
moved to.
This commit is contained in:
JC Brand 2020-04-15 09:13:50 +02:00
parent 16c58a966a
commit c9084e4ed5
2 changed files with 115 additions and 50 deletions

View File

@ -3836,27 +3836,43 @@
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit';
const new_muc_jid = 'foyer@montague.lit';
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
const view = _converse.api.chatviews.get(muc_jid);
spyOn(_converse.api, 'confirm').and.callFake(() => Promise.resolve(true));
const textarea = view.el.querySelector('.chat-textarea');
textarea.value = '/destroy bored';
let view = _converse.api.chatviews.get(muc_jid);
spyOn(_converse.api, 'confirm').and.callThrough();
let textarea = view.el.querySelector('.chat-textarea');
textarea.value = '/destroy';
view.onFormSubmitted(new Event('submit'));
let modal = await u.waitUntil(() => document.querySelector('.modal-dialog'));
await u.waitUntil(() => u.isVisible(modal));
const sent_IQs = _converse.connection.IQ_stanzas;
const sent_IQ = await u.waitUntil(() => sent_IQs.filter(iq => iq.querySelector('destroy')).pop());
let challenge_el = modal.querySelector('[name="challenge"]');
challenge_el.value = muc_jid+'e';
const reason_el = modal.querySelector('[name="reason"]');
reason_el.value = 'Moved to a new location';
const newjid_el = modal.querySelector('[name="newjid"]');
newjid_el.value = new_muc_jid;
let submit = modal.querySelector('[type="submit"]');
submit.click();
expect(u.isVisible(modal)).toBeTruthy();
expect(u.hasClass('error', challenge_el)).toBeTruthy();
challenge_el.value = muc_jid;
submit.click();
let sent_IQs = _converse.connection.IQ_stanzas;
let sent_IQ = await u.waitUntil(() => sent_IQs.filter(iq => iq.querySelector('destroy')).pop());
expect(Strophe.serialize(sent_IQ)).toBe(
`<iq id="${sent_IQ.getAttribute('id')}" to="lounge@montague.lit" type="set" xmlns="jabber:client">`+
`<iq id="${sent_IQ.getAttribute('id')}" to="${muc_jid}" type="set" xmlns="jabber:client">`+
`<query xmlns="http://jabber.org/protocol/muc#owner">`+
`<destroy>`+
`<destroy jid="${new_muc_jid}">`+
`<reason>`+
`bored`+
`Moved to a new location`+
`</reason>`+
`</destroy>`+
`</query>`+
`</iq>`);
const result_stanza = $iq({
let result_stanza = $iq({
'type': 'result',
'id': sent_IQ.getAttribute('id'),
'from': view.model.get('jid'),
@ -3868,6 +3884,41 @@
await u.waitUntil(() => (view.model.session.get('connection_status') === converse.ROOMSTATUS.DISCONNECTED));
await u.waitUntil(() => _converse.chatboxes.length === 1);
expect(_converse.api.trigger).toHaveBeenCalledWith('chatBoxClosed', jasmine.any(Object));
// Try again without reason or new JID
_converse.connection.IQ_stanzas = [];
sent_IQs = _converse.connection.IQ_stanzas;
await test_utils.openAndEnterChatRoom(_converse, new_muc_jid, 'romeo');
view = _converse.api.chatviews.get(new_muc_jid);
textarea = view.el.querySelector('.chat-textarea');
textarea.value = '/destroy';
view.onFormSubmitted(new Event('submit'));
modal = await u.waitUntil(() => document.querySelector('.modal-dialog'));
await u.waitUntil(() => u.isVisible(modal));
challenge_el = modal.querySelector('[name="challenge"]');
challenge_el.value = new_muc_jid;
submit = modal.querySelector('[type="submit"]');
submit.click();
sent_IQ = await u.waitUntil(() => sent_IQs.filter(iq => iq.querySelector('destroy')).pop());
expect(Strophe.serialize(sent_IQ)).toBe(
`<iq id="${sent_IQ.getAttribute('id')}" to="${new_muc_jid}" type="set" xmlns="jabber:client">`+
`<query xmlns="http://jabber.org/protocol/muc#owner">`+
`<destroy/>`+
`</query>`+
`</iq>`);
result_stanza = $iq({
'type': 'result',
'id': sent_IQ.getAttribute('id'),
'from': view.model.get('jid'),
'to': _converse.connection.jid
});
expect(_converse.chatboxes.length).toBe(2);
_converse.connection._dataRecv(test_utils.createRequest(result_stanza));
await u.waitUntil(() => (view.model.session.get('connection_status') === converse.ROOMSTATUS.DISCONNECTED));
await u.waitUntil(() => _converse.chatboxes.length === 1);
done();
}));
});

View File

@ -1014,19 +1014,14 @@ converse.plugins.add('converse-muc-views', {
if (_converse.show_retraction_warning) {
messages[1] = retraction_warning;
}
const result = await api.confirm(__('Confirm'), messages);
if (result) {
this.retractOwnMessage(message);
}
!!(await api.confirm(__('Confirm'), messages)) && this.retractOwnMessage(message);
} else if (await message.mayBeModerated()) {
if (message.get('sender') === 'me') {
let messages = [__('Are you sure you want to retract this message?')];
if (_converse.show_retraction_warning) {
messages = [messages[0], retraction_warning, messages[1]]
}
if (await api.confirm(__('Confirm'), messages)) {
this.retractOtherMessage(message);
}
!!(await api.confirm(__('Confirm'), messages)) && this.retractOtherMessage(message);
} else {
let messages = [
__('You are about to retract this message.'),
@ -1040,9 +1035,7 @@ converse.plugins.add('converse-muc-views', {
messages,
__('Optional reason')
);
if (reason !== false) {
this.retractOtherMessage(message, reason);
}
(reason !== false) && this.retractOtherMessage(message, reason);
}
} else {
const err_msg = __(`Sorry, you're not allowed to retract this message`);
@ -1158,31 +1151,6 @@ converse.plugins.add('converse-muc-views', {
});
}
const conn_status = this.model.session.get('connection_status');
if (conn_status === converse.ROOMSTATUS.ENTERED) {
const allowed_commands = this.getAllowedCommands();
if (allowed_commands.includes('modtools')) {
buttons.push({
'i18n_text': __('Moderate'),
'i18n_title': __('Moderate this groupchat'),
'handler': () => this.showModeratorToolsModal(),
'a_class': 'moderate-chatroom-button',
'icon_class': 'fa-user-cog',
'name': 'moderate'
});
}
if (allowed_commands.includes('destroy')) {
buttons.push({
'i18n_text': __('Destroy'),
'i18n_title': __('Remove this groupchat'),
'handler': ev => this.destroy(ev),
'a_class': 'destroy-chatroom-button',
'icon_class': 'fa-trash',
'name': 'destroy'
});
}
}
if (this.model.invitesAllowed()) {
buttons.push({
'i18n_text': __('Invite'),
@ -1208,6 +1176,32 @@ converse.plugins.add('converse-muc-views', {
});
}
const conn_status = this.model.session.get('connection_status');
if (conn_status === converse.ROOMSTATUS.ENTERED) {
const allowed_commands = this.getAllowedCommands();
if (allowed_commands.includes('modtools')) {
buttons.push({
'i18n_text': __('Moderate'),
'i18n_title': __('Moderate this groupchat'),
'handler': () => this.showModeratorToolsModal(),
'a_class': 'moderate-chatroom-button',
'icon_class': 'fa-user-cog',
'name': 'moderate'
});
}
if (allowed_commands.includes('destroy')) {
buttons.push({
'i18n_text': __('Destroy'),
'i18n_title': __('Remove this groupchat'),
'handler': ev => this.destroy(ev),
'a_class': 'destroy-chatroom-button',
'icon_class': 'fa-trash',
'name': 'destroy'
});
}
}
if (!api.settings.get("singleton")) {
buttons.push({
'i18n_text': __('Leave'),
@ -1532,10 +1526,30 @@ converse.plugins.add('converse-muc-views', {
}
},
async destroy (reason, new_jid) {
const message = [__('Are you sure you want to destroy this groupchat?')];
if (await api.confirm(__('Confirm'), message)) {
return this.model.sendDestroyIQ(reason, new_jid).then(() => this.close())
async destroy () {
const messages = [__('Are you sure you want to destroy this groupchat?')];
let fields = [{
'name': 'challenge',
'label': __('Please enter the XMPP address of this groupchat to confirm'),
'challenge': this.model.get('jid'),
'placeholder': __('name@example.org'),
'required': true
}, {
'name': 'reason',
'label': __('Optional reason for destroying this groupchat'),
'placeholder': __('Reason')
}, {
'name': 'newjid',
'label': __('Optional XMPP address for a new groupchat that replaces this one'),
'placeholder': __('replacement@example.org')
}];
try {
fields = await api.confirm(__('Confirm'), messages, fields);
const reason = fields.filter(f => f.name === 'reason').pop()?.value;
const newjid = fields.filter(f => f.name === 'newjid').pop()?.value;
return this.model.sendDestroyIQ(reason, newjid).then(() => this.close())
} catch (e) {
log.error(e);
}
},
@ -1583,7 +1597,7 @@ converse.plugins.add('converse-muc-views', {
if (!this.verifyAffiliations(['owner'])) {
break;
}
this.destroy(args).catch(e => this.onCommandError(e));
this.destroy().catch(e => this.onCommandError(e));
break;
}
case 'help': {