'use strict'; const addBlockForm = require( 'ext.checkUser/investigate/blockform.js' ); QUnit.module( 'ext.checkUser.investigate.blockform', QUnit.newMwEnvironment() ); function setUpDocumentForTest( targets ) { // eslint-disable-next-line no-jquery/no-global-selector const $qunitFixture = $( '#qunit-fixture' ); // Set the javascript config used by blockform.js to get the targets and // excluded targets in the current check. mw.config.set( 'wgCheckUserInvestigateTargets', targets ); mw.config.set( 'wgCheckUserInvestigateExcludeTargets', [] ); // Create the barebones HTML structure added by SpecialInvestigate::addBlockForm const node = document.createElement( 'div' ); node.className = 'ext-checkuser-investigate-subtitle-fieldset'; // Add the accounts and ips block button, including adding infusion data (which is // hardcoded in the test because there isn't an easier way to generate this // in a QUnit context). // First adds the accounts block button. const $accountsBlockButton = new OO.ui.ButtonWidget( { label: 'checkuser-investigate-subtitle-block-button-label', classes: [ 'ext-checkuser-investigate-subtitle-block-button', 'ext-checkuser-investigate-subtitle-block-accounts-button' ] } ).$element; $accountsBlockButton.attr( 'data-ooui', '{"_":"OO.ui.ButtonWidget","rel":["nofollow"],"label":"Block accounts","flags":' + '["primary","progressive"],"classes":["ext-checkuser-investigate-subtitle-block-' + 'button","ext-checkuser-investigate-subtitle-block-accounts-button"]}' ); node.appendChild( $accountsBlockButton[ 0 ] ); // Next add the IPs block button const $ipsBlockButton = new OO.ui.ButtonWidget( { label: 'checkuser-investigate-subtitle-block-button-label', classes: [ 'ext-checkuser-investigate-subtitle-block-button', 'ext-checkuser-investigate-subtitle-block-ips-button' ] } ).$element; $ipsBlockButton.attr( 'data-ooui', '{"_":"OO.ui.ButtonWidget","rel":["nofollow"],"label":"Block IPs","flags":' + '["primary","progressive"],"classes":["ext-checkuser-investigate-subtitle-' + 'block-button","ext-checkuser-investigate-subtitle-block-ips-button"]}' ); node.appendChild( $ipsBlockButton[ 0 ] ); // Add a placeholder widget which gets replaced with the targets widget. const placeholderWidget = document.createElement( 'div' ); placeholderWidget.className = 'ext-checkuser-investigate-subtitle-placeholder-widget'; node.appendChild( placeholderWidget ); // Add the barebones HTML structure to the QUnit fixture element. $qunitFixture.html( node ); return $( node ); } QUnit.test( 'Test visibility of block form elements on DOM load, after block click, and after cancel click', ( assert ) => { // We need the test to wait a small amount of time for the click events to finish. const done = assert.async(); // Set the HTML that is added by Special:Investigate. const $actualHtmlElement = setUpDocumentForTest( [ 'Test' ] ); // Call the function addBlockForm(); // Assert the state when the DOM is loaded first. const cases = require( './cases/blockFormWidgetVisibility.json' ); cases.forEach( ( caseItem ) => { const $elementForCase = $actualHtmlElement.find( caseItem.cssClass ); assert.true( !!$elementForCase.length, caseItem.msg + ' exists on DOM load' ); assert.strictEqual( // eslint-disable-next-line no-jquery/no-class-state !$elementForCase.hasClass( 'oo-ui-element-hidden' ), caseItem.visibleOnLoad, caseItem.msg + ' visibility state on DOM load' ); } ); // Click the block button $( '.ext-checkuser-investigate-subtitle-block-button a', $actualHtmlElement )[ 0 ].click(); setTimeout( () => { // Assert the state after the block button is clicked. cases.forEach( ( caseItem ) => { const $elementForCase = $actualHtmlElement.find( caseItem.cssClass ); assert.true( !!$elementForCase.length, caseItem.msg + ' exists after block button click' ); assert.strictEqual( // eslint-disable-next-line no-jquery/no-class-state !$elementForCase.hasClass( 'oo-ui-element-hidden' ), caseItem.visibleAfterBlockClick, caseItem.msg + ' visibility state after block button click' ); } ); // Click the cancel button $( '.ext-checkuser-investigate-subtitle-cancel-button a', $actualHtmlElement )[ 0 ].click(); setTimeout( () => { // Assert the state after the cancel button is clicked. cases.forEach( ( caseItem ) => { const $elementForCase = $actualHtmlElement.find( caseItem.cssClass ); assert.true( !!$elementForCase.length, caseItem.msg + ' exists after cancel button click' ); assert.strictEqual( // eslint-disable-next-line no-jquery/no-class-state !$elementForCase.hasClass( 'oo-ui-element-hidden' ), caseItem.visibleAfterCancelClick, caseItem.msg + ' visibility state after cancel button click' ); } ); // QUnit tests are now done, so we can call done. done(); } ); } ); } ); function performBlockFormSubmitTest( assert, cssClass, $actualHtmlElement, $qunitFixture, expectedTargets, done ) { // Listen for any submits of the hidden form and prevent them to avoid opening // a new tab when running the tests. // At the same time, if this event is triggered, then indicate that the test passed. let formWasSubmitted; $( $qunitFixture ).on( 'submit', '.ext-checkuser-investigate-hidden-block-form', ( event ) => { event.preventDefault(); formWasSubmitted = true; return false; } ); // Click the appropriate block button $( cssClass + ' a', $actualHtmlElement )[ 0 ].click(); setTimeout( () => { // Click the continue button $( '.ext-checkuser-investigate-subtitle-continue-button a', $actualHtmlElement )[ 0 ].click(); setTimeout( () => { // Assert that the form element was correctly added const $formElement = $( '.ext-checkuser-investigate-hidden-block-form', $qunitFixture ); assert.true( !!$formElement.length, 'Form exists in the DOM after continue button was clicked' ); assert.strictEqual( $formElement.attr( 'action' ), new mw.Title( 'Special:InvestigateBlock' ).getUrl(), 'Form sends data to Special:InvestigateBlock' ); // Assert that the targets are as expected. const $targetsInput = $formElement.find( 'input[name="wpTargets"]' ); assert.true( !!$targetsInput.length, 'Targets input exists in the DOM after continue button was clicked' ); assert.strictEqual( $targetsInput.val(), expectedTargets.join( '\n' ), 'Targets input value is set to the targets entered in the widget' ); // Assert that the form was actually submitted. assert.true( formWasSubmitted, 'Form was submitted when continue button was clicked' ); // Clean up the form element from the DOM to avoid affecting other tests. $formElement.remove(); // QUnit tests are now done, so we can call done. done(); } ); } ); } // performBlockFormSubmitTest resolves the done async callback, but eslint doesn't detect this. // eslint-disable-next-line qunit/resolve-async QUnit.test( 'Test blocking accounts', ( assert ) => { // We need the test to wait a small amount of time for the click events to finish. const done = assert.async(); // Set the HTML that is added by Special:Investigate. const $actualHtmlElement = setUpDocumentForTest( [ 'Test', '1.2.3.4', 'Test2', '4.5.6.0/24' ] ); // Call the function, specifying the QUnit fixture as the document root // to avoid the form being kept in the DOM for other JavaScript tests. // eslint-disable-next-line no-jquery/no-global-selector const $qunitFixture = $( '#qunit-fixture' ); addBlockForm( $qunitFixture ); performBlockFormSubmitTest( assert, '.ext-checkuser-investigate-subtitle-block-accounts-button', $actualHtmlElement, $qunitFixture, [ 'Test', 'Test2' ], done ); } ); // performBlockFormSubmitTest resolves the done async callback, but eslint doesn't detect this. // eslint-disable-next-line qunit/resolve-async QUnit.test( 'Test blocking IPs', ( assert ) => { // We need the test to wait a small amount of time for the click events to finish. const done = assert.async(); // Set the HTML that is added by Special:Investigate. const $actualHtmlElement = setUpDocumentForTest( [ 'Test', '1.2.3.4', 'Test2', '4.5.6.0/24' ] ); // Call the function, specifying the QUnit fixture as the document root // to avoid the form being kept in the DOM for other JavaScript tests. // eslint-disable-next-line no-jquery/no-global-selector const $qunitFixture = $( '#qunit-fixture' ); addBlockForm( $qunitFixture ); performBlockFormSubmitTest( assert, '.ext-checkuser-investigate-subtitle-block-ips-button', $actualHtmlElement, $qunitFixture, [ '1.2.3.4', '4.5.6.0/24' ], done ); } );