Merge "Add SPARQL client to core"
[lhc/web/wiklou.git] / tests / phpunit / includes / preferences / DefaultPreferencesFactoryTest.php
1 <?php
2
3 use MediaWiki\Auth\AuthManager;
4 use MediaWiki\MediaWikiServices;
5 use MediaWiki\Preferences\DefaultPreferencesFactory;
6 use Wikimedia\ObjectFactory;
7 use Wikimedia\TestingAccessWrapper;
8
9 /**
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 * http://www.gnu.org/copyleft/gpl.html
24 *
25 * @file
26 */
27
28 /**
29 * @group Preferences
30 */
31 class DefaultPreferencesFactoryTest extends MediaWikiTestCase {
32
33 /** @var IContextSource */
34 protected $context;
35
36 /** @var Config */
37 protected $config;
38
39 public function setUp() {
40 parent::setUp();
41 global $wgParserConf;
42 $this->context = new RequestContext();
43 $this->context->setTitle( Title::newFromText( self::class ) );
44 $this->setMwGlobals( 'wgParser',
45 ObjectFactory::constructClassInstance( $wgParserConf['class'], [ $wgParserConf ] )
46 );
47 $this->config = MediaWikiServices::getInstance()->getMainConfig();
48 }
49
50 /**
51 * Get a basic PreferencesFactory for testing with.
52 * @return DefaultPreferencesFactory
53 */
54 protected function getPreferencesFactory() {
55 return new DefaultPreferencesFactory(
56 $this->config,
57 new Language(),
58 AuthManager::singleton(),
59 MediaWikiServices::getInstance()->getLinkRenderer()
60 );
61 }
62
63 /**
64 * @covers MediaWiki\Preferences\DefaultPreferencesFactory::getForm()
65 */
66 public function testGetForm() {
67 $testUser = $this->getTestUser();
68 $form = $this->getPreferencesFactory()->getForm( $testUser->getUser(), $this->context );
69 $this->assertInstanceOf( PreferencesForm::class, $form );
70 $this->assertCount( 5, $form->getPreferenceSections() );
71 }
72
73 /**
74 * CSS classes for emailauthentication preference field when there's no email.
75 * @see https://phabricator.wikimedia.org/T36302
76 * @covers MediaWiki\Preferences\DefaultPreferencesFactory::profilePreferences()
77 * @dataProvider emailAuthenticationProvider
78 */
79 public function testEmailAuthentication( $user, $cssClass ) {
80 $prefs = $this->getPreferencesFactory()->getFormDescriptor( $user, $this->context );
81 $this->assertArrayHasKey( 'cssclass', $prefs['emailauthentication'] );
82 $this->assertEquals( $cssClass, $prefs['emailauthentication']['cssclass'] );
83 }
84
85 public function emailAuthenticationProvider() {
86 $userNoEmail = new User;
87 $userEmailUnauthed = new User;
88 $userEmailUnauthed->setEmail( 'noauth@example.org' );
89 $userEmailAuthed = new User;
90 $userEmailAuthed->setEmail( 'noauth@example.org' );
91 $userEmailAuthed->setEmailAuthenticationTimestamp( wfTimestamp() );
92 return [
93 [ $userNoEmail, 'mw-email-none' ],
94 [ $userEmailUnauthed, 'mw-email-not-authenticated' ],
95 [ $userEmailAuthed, 'mw-email-authenticated' ],
96 ];
97 }
98
99 /**
100 * Test that PreferencesFormPreSave hook has correct data:
101 * - user Object is passed
102 * - oldUserOptions contains previous user options (before save)
103 * - formData and User object have set up new properties
104 *
105 * @see https://phabricator.wikimedia.org/T169365
106 * @covers MediaWiki\Preferences\DefaultPreferencesFactory::submitForm()
107 */
108 public function testPreferencesFormPreSaveHookHasCorrectData() {
109 $oldOptions = [
110 'test' => 'abc',
111 'option' => 'old'
112 ];
113 $newOptions = [
114 'test' => 'abc',
115 'option' => 'new'
116 ];
117 $configMock = new HashConfig( [
118 'HiddenPrefs' => []
119 ] );
120 $form = $this->getMockBuilder( PreferencesForm::class )
121 ->disableOriginalConstructor()
122 ->getMock();
123
124 $userMock = $this->getMockBuilder( User::class )
125 ->disableOriginalConstructor()
126 ->getMock();
127 $userMock->method( 'getOptions' )
128 ->willReturn( $oldOptions );
129 $userMock->method( 'isAllowedAny' )
130 ->willReturn( true );
131 $userMock->method( 'isAllowed' )
132 ->willReturn( true );
133
134 $userMock->expects( $this->exactly( 2 ) )
135 ->method( 'setOption' )
136 ->withConsecutive(
137 [ $this->equalTo( 'test' ), $this->equalTo( $newOptions[ 'test' ] ) ],
138 [ $this->equalTo( 'option' ), $this->equalTo( $newOptions[ 'option' ] ) ]
139 );
140
141 $form->expects( $this->any() )
142 ->method( 'getModifiedUser' )
143 ->willReturn( $userMock );
144
145 $form->expects( $this->any() )
146 ->method( 'getContext' )
147 ->willReturn( $this->context );
148
149 $form->expects( $this->any() )
150 ->method( 'getConfig' )
151 ->willReturn( $configMock );
152
153 $this->setTemporaryHook( 'PreferencesFormPreSave',
154 function ( $formData, $form, $user, &$result, $oldUserOptions )
155 use ( $newOptions, $oldOptions, $userMock ) {
156 $this->assertSame( $userMock, $user );
157 foreach ( $newOptions as $option => $value ) {
158 $this->assertSame( $value, $formData[ $option ] );
159 }
160 foreach ( $oldOptions as $option => $value ) {
161 $this->assertSame( $value, $oldUserOptions[ $option ] );
162 }
163 $this->assertEquals( true, $result );
164 }
165 );
166
167 $factory = TestingAccessWrapper::newFromObject( $this->getPreferencesFactory() );
168 $factory->saveFormData( $newOptions, $form );
169 }
170
171 /**
172 * The rclimit preference should accept non-integer input and filter it to become an integer.
173 */
174 public function testIntvalFilter() {
175 // Test a string with leading zeros (i.e. not octal) and spaces.
176 $this->context->getRequest()->setVal( 'wprclimit', ' 0012 ' );
177 $user = new User;
178 $form = $this->getPreferencesFactory()->getForm( $user, $this->context );
179 $form->show();
180 $form->trySubmit();
181 $this->assertEquals( 12, $user->getOption( 'rclimit' ) );
182 }
183 }