aboutsummaryrefslogtreecommitdiffstats
path: root/tests/phpunit/unit/includes/htmlform/HTMLCheckMatrixTest.php
blob: b8a3f46ef38d742580f7cf7e522641cd06c0bf6b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<?php

use MediaWiki\HTMLForm\Field\HTMLCheckMatrix;
use MediaWiki\HTMLForm\HTMLForm;
use MediaWiki\HTMLForm\HTMLFormField;
use MediaWiki\HTMLForm\HTMLFormFieldRequiredOptionsException;
use MediaWiki\Message\Message;

/**
 * @covers \HTMLCheckMatrix
 */
class HTMLCheckMatrixTest extends MediaWikiUnitTestCase {
	private $defaultOptions = [
		'rows' => [ 'r1', 'r2' ],
		'columns' => [ 'c1', 'c2' ],
		'fieldname' => 'test',
	];

	protected function setUp(): void {
		parent::setUp();
		$htmlForm = $this->createMock( HTMLForm::class );
		$htmlForm->method( 'msg' )->willReturnCallback( 'wfMessage' );
		$this->defaultOptions['parent'] = $htmlForm;
	}

	public function testPlainInstantiation() {
		$this->expectException( HTMLFormFieldRequiredOptionsException::class );
		new HTMLCheckMatrix( [] );
	}

	public function testInstantiationWithMinimumRequiredParameters() {
		new HTMLCheckMatrix( $this->defaultOptions );
		$this->assertTrue( true ); // form instantiation must throw exception on failure
	}

	public function testValidateCallsUserDefinedValidationCallback() {
		$called = false;
		$field = new HTMLCheckMatrix( $this->defaultOptions + [
			'validation-callback' => static function () use ( &$called ) {
				$called = true;

				return false;
			},
		] );
		$this->assertFalse( $this->validate( $field, [] ) );
		$this->assertTrue( $called );
	}

	/**
	 * @dataProvider provideValidate
	 */
	public function testValidate( $expected, $submitted ) {
		$field = new HTMLCheckMatrix( $this->defaultOptions );
		$this->assertSame( $expected, $this->validate( $field, $submitted ) );
	}

	public static function provideValidate() {
		// $expected, $submitted
		yield [ false, null ];
		yield [ false, true ];
		yield [ false, 'abc' ];
		yield [ false, (object)[] ];
		yield [ true, [] ];
		yield [ true, [ 'c1-r1' ] ];
		yield [ true, [ 'c1-r1', 'c1-r2', 'c2-r1', 'c2-r2' ] ];
	}

	public function testValidateAllowsOnlyKnownTags() {
		$field = new HTMLCheckMatrix( $this->defaultOptions );
		$this->assertInstanceOf( Message::class, $this->validate( $field, [ 'foo' ] ) );
	}

	/**
	 * This form object actually has no visibility into what happens later on, but essentially
	 * if the data submitted by the user passes validate the following is run:
	 * foreach ( $field->filterDataForSubmit( $data ) as $k => $v ) {
	 *     $userOptionsManager->setOption( $user, $k, $v );
	 * }
	 */
	public function testValuesForcedOnRemainOn() {
		$field = new HTMLCheckMatrix( $this->defaultOptions + [
				'force-options-on' => [ 'c2-r1' ],
			] );
		$expected = [
			'c1-r1' => false,
			'c1-r2' => false,
			'c2-r1' => true,
			'c2-r2' => false,
		];
		$this->assertEquals( $expected, $field->filterDataForSubmit( [] ) );
	}

	public function testValuesForcedOffRemainOff() {
		$field = new HTMLCheckMatrix( $this->defaultOptions + [
				'force-options-off' => [ 'c1-r2', 'c2-r2' ],
			] );
		$expected = [
			'c1-r1' => true,
			'c1-r2' => false,
			'c2-r1' => true,
			'c2-r2' => false,
		];
		// array_keys on the result simulates submitting all fields checked
		$this->assertEquals( $expected, $field->filterDataForSubmit( array_keys( $expected ) ) );
	}

	protected function validate( HTMLFormField $field, $submitted ) {
		return $field->validate(
			$submitted,
			[ $this->defaultOptions['fieldname'] => $submitted ]
		);
	}

}