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