From 83351fb98f15ee42cbc4912a5b91937ca311cefb Mon Sep 17 00:00:00 2001 From: JC Brand Date: Tue, 18 Oct 2022 10:10:13 +0200 Subject: [PATCH] Add test case for adhoc commands --- karma.conf.js | 3 +- src/plugins/adhoc-views/adhoc-commands.js | 14 +++-- src/plugins/adhoc-views/templates/ad-hoc.js | 15 ++--- src/plugins/adhoc-views/tests/adhoc.js | 69 +++++++++++++++++++++ src/shared/tests/mock.js | 2 +- 5 files changed, 88 insertions(+), 15 deletions(-) create mode 100644 src/plugins/adhoc-views/tests/adhoc.js diff --git a/karma.conf.js b/karma.conf.js index 889cfe9ee..e8ef83b81 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -42,8 +42,9 @@ module.exports = function(config) { { pattern: "src/headless/tests/converse.js", type: 'module' }, { pattern: "src/headless/tests/eventemitter.js", type: 'module' }, { pattern: "src/modals/tests/user-details-modal.js", type: 'module' }, - { pattern: "src/plugins/bookmark-views/tests/bookmarks.js", type: 'module' }, + { pattern: "src/plugins/adhoc-views/tests/adhoc.js", type: 'module' }, { pattern: "src/plugins/bookmark-views/tests/bookmarks-list.js", type: 'module' }, + { pattern: "src/plugins/bookmark-views/tests/bookmarks.js", type: 'module' }, { pattern: "src/plugins/chatview/tests/chatbox.js", type: 'module' }, { pattern: "src/plugins/chatview/tests/corrections.js", type: 'module' }, { pattern: "src/plugins/chatview/tests/emojis.js", type: 'module' }, diff --git a/src/plugins/adhoc-views/adhoc-commands.js b/src/plugins/adhoc-views/adhoc-commands.js index 3ed9c1bc7..5f37ec013 100644 --- a/src/plugins/adhoc-views/adhoc-commands.js +++ b/src/plugins/adhoc-views/adhoc-commands.js @@ -16,6 +16,7 @@ export default class AdHocCommands extends CustomElement { 'alert': { type: String }, 'alert_type': { type: String }, 'nonce': { type: String }, // Used to force re-rendering + 'fetching': { type: Boolean }, // Used to force re-rendering 'showform': { type: String }, 'view': { type: String }, } @@ -24,21 +25,17 @@ export default class AdHocCommands extends CustomElement { constructor () { super(); this.view = 'choose-service'; + this.fetching = false; this.showform = ''; this.commands = []; } render () { - return tpl_adhoc({ - 'alert': this.alert, - 'alert_type': this.alert_type, - 'commands': this.commands, - 'fetchCommands': ev => this.fetchCommands(ev), + return tpl_adhoc(this, { 'hideCommandForm': ev => this.hideCommandForm(ev), 'runCommand': ev => this.runCommand(ev), 'showform': this.showform, 'toggleCommandForm': ev => this.toggleCommandForm(ev), - 'view': this.view, }); } @@ -47,6 +44,8 @@ export default class AdHocCommands extends CustomElement { delete this.alert_type; delete this.alert; + this.fetching = true; + const form_data = new FormData(ev.target); const jid = form_data.get('jid').trim(); let supported; @@ -54,7 +53,10 @@ export default class AdHocCommands extends CustomElement { supported = await api.disco.supports(Strophe.NS.ADHOC, jid) } catch (e) { log.error(e); + } finally { + this.fetching = false; } + if (supported) { try { this.commands = await api.adhoc.getCommands(jid); diff --git a/src/plugins/adhoc-views/templates/ad-hoc.js b/src/plugins/adhoc-views/templates/ad-hoc.js index a6a1c695c..71f0d9e24 100644 --- a/src/plugins/adhoc-views/templates/ad-hoc.js +++ b/src/plugins/adhoc-views/templates/ad-hoc.js @@ -1,10 +1,11 @@ import tpl_command from './ad-hoc-command.js'; +import tpl_spinner from 'templates/spinner.js'; import { __ } from 'i18n'; import { getAutoCompleteList } from '../utils.js'; import { html } from "lit"; -export default (o) => { +export default (el, o) => { const i18n_choose_service = __('On which entity do you want to run commands?'); const i18n_choose_service_instructions = __( 'Certain XMPP services and entities allow privileged users to execute ad-hoc commands on them.'); @@ -13,8 +14,8 @@ export default (o) => { const i18n_jid_placeholder = __('XMPP Address'); const i18n_no_commands_found = __('No commands found'); return html` - ${ o.alert ? html`` : '' } -
+ ${ el.alert ? html`` : '' } +
- + ${ el.fetching ? tpl_spinner() : html`` }
- ${ o.view === 'list-commands' ? html` + ${ el.view === 'list-commands' ? html`
    -
  • ${ o.commands.length ? i18n_commands_found : i18n_no_commands_found }:
  • - ${ o.commands.map(cmd => tpl_command(o, cmd)) } +
  • ${ el.commands.length ? i18n_commands_found : i18n_no_commands_found }:
  • + ${ el.commands.map(cmd => tpl_command(o, cmd)) }
` : '' } diff --git a/src/plugins/adhoc-views/tests/adhoc.js b/src/plugins/adhoc-views/tests/adhoc.js new file mode 100644 index 000000000..08d96d3d7 --- /dev/null +++ b/src/plugins/adhoc-views/tests/adhoc.js @@ -0,0 +1,69 @@ +/*global mock, converse */ + +const { sizzle, u, stx } = converse.env; + +describe("Ad-hoc commands", function () { + + fit("can be queried for via a modal", mock.initConverse([], {}, async (_converse) => { + const { api } = _converse; + const entity_jid = 'muc.montague.lit'; + + const modal = await api.modal.show('converse-user-settings-modal'); + await u.waitUntil(() => u.isVisible(modal)); + modal.querySelector('#commands-tab').click(); + + const adhoc_form = modal.querySelector('converse-adhoc-commands'); + await u.waitUntil(() => u.isVisible(adhoc_form)); + + const input = adhoc_form.querySelector('input[name="jid"]'); + input.value = entity_jid; + + const submit = adhoc_form.querySelector('input[type="submit"]'); + submit.click(); + + await mock.waitUntilDiscoConfirmed(_converse, entity_jid, [], ['http://jabber.org/protocol/commands'], [], 'info'); + + const sel = `iq[to="${entity_jid}"] query[xmlns="http://jabber.org/protocol/disco#items"]`; + const iq = await u.waitUntil(() => _converse.connection.IQ_stanzas.filter(iq => sizzle(sel, iq).length).pop()); + + _converse.connection._dataRecv(mock.createRequest(stx` + + + + + + + + + + `)); + + const heading = await u.waitUntil(() => adhoc_form.querySelector('.list-group-item.active')); + expect(heading.textContent).toBe('Commands found:'); + + const items = adhoc_form.querySelectorAll('.list-group-item:not(.active)'); + expect(items.length).toBe(6); + expect(items[0].textContent.trim()).toBe('List Service Configurations'); + expect(items[1].textContent.trim()).toBe('Configure Service'); + expect(items[2].textContent.trim()).toBe('Reset Service Configuration'); + expect(items[3].textContent.trim()).toBe('Start Service'); + expect(items[4].textContent.trim()).toBe('Stop Service'); + expect(items[5].textContent.trim()).toBe('Restart Service'); + })); +}); diff --git a/src/shared/tests/mock.js b/src/shared/tests/mock.js index 0968c9991..d9d2eb41f 100644 --- a/src/shared/tests/mock.js +++ b/src/shared/tests/mock.js @@ -640,7 +640,7 @@ async function _initConverse (settings) { 'enable_smacks': false, 'i18n': 'en', 'persistent_store': 'localStorage', - 'loglevel': 'warn', + 'loglevel': 'debug', 'no_trimming': true, 'play_sounds': false, 'use_emojione': false,