2022-01-28 13:25:57 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @covers HTMLFormField
|
|
|
|
|
*/
|
|
|
|
|
class HTMLFormFieldTest extends PHPUnit\Framework\TestCase {
|
|
|
|
|
|
|
|
|
|
use MediaWikiCoversValidator;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @covers HTMLFormField::isHidden
|
|
|
|
|
* @covers HTMLFormField::isDisabled
|
|
|
|
|
* @covers HTMLFormField::checkStateRecurse
|
2022-01-20 03:18:41 +00:00
|
|
|
* @covers HTMLFormField::validateCondState
|
2022-01-28 13:25:57 +00:00
|
|
|
* @covers HTMLFormField::getNearestFieldByName
|
|
|
|
|
* @dataProvider provideCondState
|
|
|
|
|
*/
|
2022-02-01 02:12:45 +00:00
|
|
|
public function testCondState( $fieldInfo, $requestData, $callback, $exception = null ) {
|
2022-01-28 13:25:57 +00:00
|
|
|
if ( $exception ) {
|
|
|
|
|
$this->expectException( MWException::class );
|
|
|
|
|
$this->expectExceptionMessageMatches( $exception );
|
|
|
|
|
}
|
2022-02-01 02:12:45 +00:00
|
|
|
$request = new FauxRequest( $requestData, true );
|
|
|
|
|
$context = new DerivativeContext( RequestContext::getMain() );
|
|
|
|
|
$context->setRequest( $request );
|
2022-01-28 13:25:57 +00:00
|
|
|
$form = HTMLForm::factory( 'ooui', wfArrayPlus2d( $fieldInfo, [
|
|
|
|
|
'check1' => [ 'type' => 'check' ],
|
|
|
|
|
'check2' => [ 'type' => 'check', 'invert' => true ],
|
2022-02-01 02:12:45 +00:00
|
|
|
'select1' => [ 'type' => 'select', 'options' => [ 'a' => 'a', 'b' => 'b', 'c' => 'c' ], 'default' => 'b' ],
|
2022-01-28 13:25:57 +00:00
|
|
|
'text1' => [ 'type' => 'text' ],
|
2022-02-01 02:12:45 +00:00
|
|
|
] ), $context );
|
2022-01-28 13:25:57 +00:00
|
|
|
$form->setTitle( Title::newFromText( 'Main Page' ) )->setSubmitCallback( static function () {
|
|
|
|
|
return true;
|
|
|
|
|
} )->prepareForm();
|
|
|
|
|
$status = $form->trySubmit();
|
2022-02-01 02:12:45 +00:00
|
|
|
$this->assertTrue( $status );
|
2022-01-28 13:25:57 +00:00
|
|
|
|
2022-02-01 02:12:45 +00:00
|
|
|
$callback( $form, $form->mFieldData );
|
2022-01-28 13:25:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function provideCondState() {
|
|
|
|
|
yield 'Field hidden if "check" field is checked' => [
|
|
|
|
|
'fieldInfo' => [
|
|
|
|
|
'text1' => [ 'hide-if' => [ '===', 'check1', '1' ] ],
|
|
|
|
|
],
|
2022-02-01 02:12:45 +00:00
|
|
|
'requestData' => [
|
|
|
|
|
'wpcheck1' => '1',
|
2022-01-28 13:25:57 +00:00
|
|
|
],
|
|
|
|
|
'callback' => function ( $form, $fieldData ) {
|
|
|
|
|
$this->assertTrue( $form->getField( 'text1' )->isHidden( $fieldData ) );
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
yield 'Field hidden if "check" field is not checked' => [
|
|
|
|
|
'fieldInfo' => [
|
|
|
|
|
'text1' => [ 'hide-if' => [ '===', 'check1', '' ] ],
|
|
|
|
|
],
|
2022-02-01 02:12:45 +00:00
|
|
|
'requestData' => [],
|
2022-01-28 13:25:57 +00:00
|
|
|
'callback' => function ( $form, $fieldData ) {
|
|
|
|
|
$this->assertTrue( $form->getField( 'text1' )->isHidden( $fieldData ) );
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
yield 'Field not hidden if "check" field is not checked' => [
|
|
|
|
|
'fieldInfo' => [
|
|
|
|
|
'text1' => [ 'hide-if' => [ '===', 'check1', '1' ] ],
|
|
|
|
|
],
|
2022-02-01 02:12:45 +00:00
|
|
|
'requestData' => [],
|
2022-01-28 13:25:57 +00:00
|
|
|
'callback' => function ( $form, $fieldData ) {
|
|
|
|
|
$this->assertFalse( $form->getField( 'text1' )->isHidden( $fieldData ) );
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
yield 'Field hidden if "check" field (invert) is checked' => [
|
|
|
|
|
'fieldInfo' => [
|
2022-02-01 02:12:45 +00:00
|
|
|
'text1' => [ 'hide-if' => [ '===', 'check2', '1' ] ],
|
2022-01-28 13:25:57 +00:00
|
|
|
],
|
2022-02-01 02:12:45 +00:00
|
|
|
'requestData' => [
|
|
|
|
|
'wpcheck2' => '1',
|
2022-01-28 13:25:57 +00:00
|
|
|
],
|
|
|
|
|
'callback' => function ( $form, $fieldData ) {
|
|
|
|
|
$this->assertTrue( $form->getField( 'text1' )->isHidden( $fieldData ) );
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
yield 'Field hidden if "check" field (invert) is not checked' => [
|
|
|
|
|
'fieldInfo' => [
|
2022-02-01 07:13:09 +00:00
|
|
|
'text1' => [ 'hide-if' => [ '!==', 'check2', '1' ] ],
|
2022-01-28 13:25:57 +00:00
|
|
|
],
|
2022-02-01 02:12:45 +00:00
|
|
|
'requestData' => [],
|
2022-01-28 13:25:57 +00:00
|
|
|
'callback' => function ( $form, $fieldData ) {
|
|
|
|
|
$this->assertTrue( $form->getField( 'text1' )->isHidden( $fieldData ) );
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
yield 'Field not hidden if "check" field (invert) is checked' => [
|
|
|
|
|
'fieldInfo' => [
|
2022-02-01 02:12:45 +00:00
|
|
|
'text1' => [ 'hide-if' => [ '!==', 'check2', '1' ] ],
|
2022-01-28 13:25:57 +00:00
|
|
|
],
|
2022-02-01 02:12:45 +00:00
|
|
|
'requestData' => [
|
|
|
|
|
'wpcheck2' => '1',
|
2022-01-28 13:25:57 +00:00
|
|
|
],
|
|
|
|
|
'callback' => function ( $form, $fieldData ) {
|
|
|
|
|
$this->assertFalse( $form->getField( 'text1' )->isHidden( $fieldData ) );
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
yield 'Field hidden if "select" field has value' => [
|
|
|
|
|
'fieldInfo' => [
|
|
|
|
|
'text1' => [ 'hide-if' => [ '===', 'select1', 'a' ] ],
|
|
|
|
|
],
|
2022-02-01 02:12:45 +00:00
|
|
|
'requestData' => [
|
|
|
|
|
'wpselect1' => 'a',
|
2022-01-28 13:25:57 +00:00
|
|
|
],
|
|
|
|
|
'callback' => function ( $form, $fieldData ) {
|
|
|
|
|
$this->assertTrue( $form->getField( 'text1' )->isHidden( $fieldData ) );
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
yield 'Field hidden if "text" field has value' => [
|
|
|
|
|
'fieldInfo' => [
|
|
|
|
|
'select1' => [ 'hide-if' => [ '===', 'text1', 'hello' ] ],
|
|
|
|
|
],
|
2022-02-01 02:12:45 +00:00
|
|
|
'requestData' => [
|
|
|
|
|
'wptext1' => 'hello',
|
2022-01-28 13:25:57 +00:00
|
|
|
],
|
|
|
|
|
'callback' => function ( $form, $fieldData ) {
|
|
|
|
|
$this->assertTrue( $form->getField( 'select1' )->isHidden( $fieldData ) );
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
yield 'Field hidden using AND conditions' => [
|
|
|
|
|
'fieldInfo' => [
|
|
|
|
|
'text1' => [ 'hide-if' => [ 'AND',
|
|
|
|
|
[ '===', 'check1', '1' ],
|
|
|
|
|
[ '===', 'select1', 'a' ]
|
|
|
|
|
] ],
|
|
|
|
|
],
|
2022-02-01 02:12:45 +00:00
|
|
|
'requestData' => [
|
|
|
|
|
'wpcheck1' => '1',
|
|
|
|
|
'wpselect1' => 'a',
|
2022-01-28 13:25:57 +00:00
|
|
|
],
|
|
|
|
|
'callback' => function ( $form, $fieldData ) {
|
|
|
|
|
$this->assertTrue( $form->getField( 'text1' )->isHidden( $fieldData ) );
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
yield 'Field hidden using OR conditions' => [
|
|
|
|
|
'fieldInfo' => [
|
|
|
|
|
'text1' => [ 'hide-if' => [ 'OR',
|
|
|
|
|
[ '===', 'check1', '1' ],
|
|
|
|
|
[ '===', 'select1', 'a' ]
|
|
|
|
|
] ],
|
|
|
|
|
],
|
2022-02-01 02:12:45 +00:00
|
|
|
'requestData' => [
|
|
|
|
|
'wpcheck1' => '1',
|
2022-01-28 13:25:57 +00:00
|
|
|
],
|
|
|
|
|
'callback' => function ( $form, $fieldData ) {
|
|
|
|
|
$this->assertTrue( $form->getField( 'text1' )->isHidden( $fieldData ) );
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
yield 'Field hidden using NAND conditions' => [
|
|
|
|
|
'fieldInfo' => [
|
|
|
|
|
'text1' => [ 'hide-if' => [ 'NAND',
|
|
|
|
|
[ '===', 'check1', '1' ],
|
|
|
|
|
[ '===', 'select1', 'a' ]
|
|
|
|
|
] ],
|
|
|
|
|
],
|
2022-02-01 02:12:45 +00:00
|
|
|
'requestData' => [
|
|
|
|
|
'wpcheck1' => '1',
|
2022-01-28 13:25:57 +00:00
|
|
|
],
|
|
|
|
|
'callback' => function ( $form, $fieldData ) {
|
|
|
|
|
$this->assertTrue( $form->getField( 'text1' )->isHidden( $fieldData ) );
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
yield 'Field hidden using NOR conditions' => [
|
|
|
|
|
'fieldInfo' => [
|
|
|
|
|
'text1' => [ 'hide-if' => [ 'NOR',
|
|
|
|
|
[ '===', 'check1', '1' ],
|
|
|
|
|
[ '===', 'select1', 'a' ]
|
|
|
|
|
] ],
|
|
|
|
|
],
|
2022-02-01 02:12:45 +00:00
|
|
|
'requestData' => [],
|
2022-01-28 13:25:57 +00:00
|
|
|
'callback' => function ( $form, $fieldData ) {
|
|
|
|
|
$this->assertTrue( $form->getField( 'text1' )->isHidden( $fieldData ) );
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
yield 'Field hidden using complex conditions' => [
|
|
|
|
|
'fieldInfo' => [
|
|
|
|
|
'text1' => [ 'hide-if' => [ 'OR',
|
|
|
|
|
[ 'NOT', [ 'AND',
|
|
|
|
|
[ '===', 'check1', '1' ],
|
|
|
|
|
[ '===', 'check2', '1' ]
|
|
|
|
|
] ],
|
|
|
|
|
[ '===', 'select1', 'a' ]
|
|
|
|
|
] ],
|
|
|
|
|
],
|
2022-02-01 02:12:45 +00:00
|
|
|
'requestData' => [],
|
2022-01-28 13:25:57 +00:00
|
|
|
'callback' => function ( $form, $fieldData ) {
|
|
|
|
|
$this->assertTrue( $form->getField( 'text1' )->isHidden( $fieldData ) );
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
yield 'Invalid conditional specification (unsupported)' => [
|
|
|
|
|
'fieldInfo' => [
|
|
|
|
|
'text1' => [ 'hide-if' => [ '>', 'test1', '10' ] ],
|
|
|
|
|
],
|
2022-02-01 02:12:45 +00:00
|
|
|
'requestData' => [],
|
2022-01-28 13:25:57 +00:00
|
|
|
'callback' => null,
|
|
|
|
|
'exception' => '/Unknown operation/',
|
|
|
|
|
];
|
|
|
|
|
yield 'Invalid conditional specification (NOT)' => [
|
|
|
|
|
'fieldInfo' => [
|
|
|
|
|
'text1' => [ 'hide-if' => [ 'NOT', '===', 'check1', '1' ] ],
|
|
|
|
|
],
|
2022-02-01 02:12:45 +00:00
|
|
|
'requestData' => [],
|
2022-01-28 13:25:57 +00:00
|
|
|
'callback' => null,
|
|
|
|
|
'exception' => '/NOT takes exactly one parameter/',
|
|
|
|
|
];
|
|
|
|
|
yield 'Invalid conditional specification (AND/OR/NAND/NOR)' => [
|
|
|
|
|
'fieldInfo' => [
|
|
|
|
|
'text1' => [ 'hide-if' => [ 'AND', '===', 'check1', '1' ] ],
|
|
|
|
|
],
|
2022-02-01 02:12:45 +00:00
|
|
|
'requestData' => [],
|
2022-01-28 13:25:57 +00:00
|
|
|
'callback' => null,
|
|
|
|
|
'exception' => '/Expected array, found string/',
|
|
|
|
|
];
|
2022-02-01 02:12:45 +00:00
|
|
|
yield 'Invalid conditional specification (===/!==) 1' => [
|
2022-01-28 13:25:57 +00:00
|
|
|
'fieldInfo' => [
|
|
|
|
|
'text1' => [ 'hide-if' => [ '===', 'check1' ] ],
|
|
|
|
|
],
|
2022-02-01 02:12:45 +00:00
|
|
|
'requestData' => [],
|
2022-01-28 13:25:57 +00:00
|
|
|
'callback' => null,
|
|
|
|
|
'exception' => '/=== takes exactly two parameters/',
|
|
|
|
|
];
|
2022-02-01 02:12:45 +00:00
|
|
|
yield 'Invalid conditional specification (===/!==) 2' => [
|
2022-01-28 13:25:57 +00:00
|
|
|
'fieldInfo' => [
|
|
|
|
|
'text1' => [ 'hide-if' => [ '===', [ '===', 'check1', '1' ], '1' ] ],
|
|
|
|
|
],
|
2022-02-01 02:12:45 +00:00
|
|
|
'requestData' => [],
|
2022-01-28 13:25:57 +00:00
|
|
|
'callback' => null,
|
|
|
|
|
'exception' => '/Parameters for === must be strings/',
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
yield 'Field disabled if "check" field is checked' => [
|
|
|
|
|
'fieldInfo' => [
|
|
|
|
|
'text1' => [ 'disable-if' => [ '===', 'check1', '1' ] ],
|
|
|
|
|
],
|
2022-02-01 02:12:45 +00:00
|
|
|
'requestData' => [
|
|
|
|
|
'wpcheck1' => '1',
|
2022-01-28 13:25:57 +00:00
|
|
|
],
|
|
|
|
|
'callback' => function ( $form, $fieldData ) {
|
|
|
|
|
$this->assertTrue( $form->getField( 'text1' )->isDisabled( $fieldData ) );
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
yield 'Field disabled if hidden' => [
|
|
|
|
|
'fieldInfo' => [
|
|
|
|
|
'text1' => [ 'hide-if' => [ '===', 'check1', '1' ] ],
|
|
|
|
|
],
|
2022-02-01 02:12:45 +00:00
|
|
|
'requestData' => [
|
|
|
|
|
'wpcheck1' => '1',
|
2022-01-28 13:25:57 +00:00
|
|
|
],
|
|
|
|
|
'callback' => function ( $form, $fieldData ) {
|
|
|
|
|
$this->assertTrue( $form->getField( 'text1' )->isDisabled( $fieldData ) );
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
}
|