1<?php
2/**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
17 *
18 * @file
19 */
20
21use MediaWiki\Preferences\IntvalFilter;
22use MediaWiki\Preferences\MultiUsernameFilter;
23use MediaWiki\Preferences\TimezoneFilter;
24
25/**
26 * @group Preferences
27 */
28class FiltersTest extends \MediaWikiUnitTestCase {
29	/**
30	 * @covers MediaWiki\Preferences\IntvalFilter::filterFromForm()
31	 * @covers MediaWiki\Preferences\IntvalFilter::filterForForm()
32	 */
33	public function testIntvalFilter() {
34		$filter = new IntvalFilter();
35		self::assertSame( 0, $filter->filterFromForm( '0' ) );
36		self::assertSame( 3, $filter->filterFromForm( '3' ) );
37		self::assertSame( '123', $filter->filterForForm( '123' ) );
38	}
39
40	/**
41	 * @covers MediaWiki\Preferences\TimezoneFilter::filterFromForm()
42	 * @dataProvider provideTimezoneFilter
43	 *
44	 * @param string $input
45	 * @param string $expected
46	 */
47	public function testTimezoneFilter( $input, $expected ) {
48		$filter = new TimezoneFilter();
49		$result = $filter->filterFromForm( $input );
50		self::assertEquals( $expected, $result );
51	}
52
53	public function provideTimezoneFilter() {
54		return [
55			[ 'ZoneInfo', 'Offset|0' ],
56			[ 'ZoneInfo|bogus', 'Offset|0' ],
57			[ 'System', 'System' ],
58			[ '2:30', 'Offset|150' ],
59		];
60	}
61
62	/**
63	 * @covers MediaWiki\Preferences\MultiUsernameFilter::filterFromForm()
64	 * @dataProvider provideMultiUsernameFilterFrom
65	 *
66	 * @param string $input
67	 * @param string|null $expected
68	 */
69	public function testMultiUsernameFilterFrom( $input, $expected ) {
70		$filter = $this->makeMultiUsernameFilter();
71		$result = $filter->filterFromForm( $input );
72		self::assertSame( $expected, $result );
73	}
74
75	public function provideMultiUsernameFilterFrom() {
76		return [
77			[ '', null ],
78			[ "\n\n\n", null ],
79			[ 'Foo', '1' ],
80			[ "\n\n\nFoo\nBar\n", "1\n2" ],
81			[ "Baz\nInvalid\nFoo", "3\n1" ],
82			[ "Invalid", null ],
83			[ "Invalid\n\n\nInvalid\n", null ],
84		];
85	}
86
87	/**
88	 * @covers MediaWiki\Preferences\MultiUsernameFilter::filterForForm()
89	 * @dataProvider provideMultiUsernameFilterFor
90	 *
91	 * @param string $input
92	 * @param string $expected
93	 */
94	public function testMultiUsernameFilterFor( $input, $expected ) {
95		$filter = $this->makeMultiUsernameFilter();
96		$result = $filter->filterForForm( $input );
97		self::assertSame( $expected, $result );
98	}
99
100	public function provideMultiUsernameFilterFor() {
101		return [
102			[ '', '' ],
103			[ "\n", '' ],
104			[ '1', 'Foo' ],
105			[ "\n1\n\n2\377\n", "Foo\nBar" ],
106			[ "666\n667", '' ],
107		];
108	}
109
110	private function makeMultiUsernameFilter() {
111		$userMapping = [
112			'Foo' => 1,
113			'Bar' => 2,
114			'Baz' => 3,
115		];
116		$flipped = array_flip( $userMapping );
117		$idLookup = $this->getMockBuilder( CentralIdLookup::class )
118			->disableOriginalConstructor()
119			->onlyMethods( [ 'centralIdsFromNames', 'namesFromCentralIds' ] )
120			->getMockForAbstractClass();
121
122		$idLookup->method( 'centralIdsFromNames' )
123			->will( self::returnCallback( static function ( $names ) use ( $userMapping ) {
124				$ids = [];
125				foreach ( $names as $name ) {
126					$ids[] = $userMapping[$name] ?? null;
127				}
128				return array_filter( $ids, 'is_numeric' );
129			} ) );
130		$idLookup->method( 'namesFromCentralIds' )
131			->will( self::returnCallback( static function ( $ids ) use ( $flipped ) {
132				$names = [];
133				foreach ( $ids as $id ) {
134					$names[] = $flipped[$id] ?? null;
135				}
136				return array_filter( $names, 'is_string' );
137			} ) );
138
139		return new MultiUsernameFilter( $idLookup );
140	}
141}
142