3 use MediaWiki\Auth\AuthManager
;
4 use MediaWiki\MediaWikiServices
;
5 use MediaWiki\Preferences\DefaultPreferencesFactory
;
6 use Wikimedia\TestingAccessWrapper
;
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.
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.
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
30 class DefaultPreferencesFactoryTest
extends \MediaWikiTestCase
{
32 /** @var IContextSource */
38 public function setUp() {
40 $this->context
= new RequestContext();
41 $this->context
->setTitle( Title
::newFromText( self
::class ) );
43 $services = MediaWikiServices
::getInstance();
45 $this->setMwGlobals( 'wgParser', $services->getParserFactory()->create() );
46 $this->config
= $services->getMainConfig();
50 * Get a basic PreferencesFactory for testing with.
51 * @return DefaultPreferencesFactory
53 protected function getPreferencesFactory() {
54 return new DefaultPreferencesFactory(
57 AuthManager
::singleton(),
58 MediaWikiServices
::getInstance()->getLinkRenderer()
63 * @covers MediaWiki\Preferences\DefaultPreferencesFactory::getForm()
65 public function testGetForm() {
66 $this->setTemporaryHook( 'GetPreferences', null );
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() );
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
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'] );
87 * @covers MediaWiki\Preferences\DefaultPreferencesFactory::renderingPreferences()
89 public function testShowRollbackConfIsHiddenForUsersWithoutRollbackRights() {
90 $userMock = $this->getMockBuilder( User
::class )
91 ->disableOriginalConstructor()
93 $userMock->method( 'isAllowed' )
94 ->willReturn( false );
95 $userMock->method( 'getEffectiveGroups' )
97 $userMock->method( 'getGroupMemberships' )
99 $userMock->method( 'getOptions' )
100 ->willReturn( [ 'test' => 'yes' ] );
102 $prefs = $this->getPreferencesFactory()->getFormDescriptor( $userMock, $this->context
);
103 $this->assertArrayNotHasKey( 'showrollbackconfirmation', $prefs );
107 * @covers MediaWiki\Preferences\DefaultPreferencesFactory::renderingPreferences()
109 public function testShowRollbackConfIsShownForUsersWithRollbackRights() {
110 $userMock = $this->getMockBuilder( User
::class )
111 ->disableOriginalConstructor()
113 $userMock->method( 'isAllowed' )
114 ->willReturn( true );
115 $userMock->method( 'getEffectiveGroups' )
117 $userMock->method( 'getGroupMemberships' )
119 $userMock->method( 'getOptions' )
120 ->willReturn( [ 'test' => 'yes' ] );
122 $prefs = $this->getPreferencesFactory()->getFormDescriptor( $userMock, $this->context
);
123 $this->assertArrayHasKey( 'showrollbackconfirmation', $prefs );
125 'rendering/advancedrendering',
126 $prefs['showrollbackconfirmation']['section']
130 public function emailAuthenticationProvider() {
131 $userNoEmail = new User
;
132 $userEmailUnauthed = new User
;
133 $userEmailUnauthed->setEmail( 'noauth@example.org' );
134 $userEmailAuthed = new User
;
135 $userEmailAuthed->setEmail( 'noauth@example.org' );
136 $userEmailAuthed->setEmailAuthenticationTimestamp( wfTimestamp() );
138 [ $userNoEmail, 'mw-email-none' ],
139 [ $userEmailUnauthed, 'mw-email-not-authenticated' ],
140 [ $userEmailAuthed, 'mw-email-authenticated' ],
145 * Test that PreferencesFormPreSave hook has correct data:
146 * - user Object is passed
147 * - oldUserOptions contains previous user options (before save)
148 * - formData and User object have set up new properties
150 * @see https://phabricator.wikimedia.org/T169365
151 * @covers MediaWiki\Preferences\DefaultPreferencesFactory::submitForm()
153 public function testPreferencesFormPreSaveHookHasCorrectData() {
162 $configMock = new HashConfig( [
165 $form = $this->getMockBuilder( PreferencesFormLegacy
::class )
166 ->disableOriginalConstructor()
169 $userMock = $this->getMockBuilder( User
::class )
170 ->disableOriginalConstructor()
172 $userMock->method( 'getOptions' )
173 ->willReturn( $oldOptions );
174 $userMock->method( 'isAllowedAny' )
175 ->willReturn( true );
176 $userMock->method( 'isAllowed' )
177 ->willReturn( true );
179 $userMock->expects( $this->exactly( 2 ) )
180 ->method( 'setOption' )
182 [ $this->equalTo( 'test' ), $this->equalTo( $newOptions[ 'test' ] ) ],
183 [ $this->equalTo( 'option' ), $this->equalTo( $newOptions[ 'option' ] ) ]
186 $form->expects( $this->any() )
187 ->method( 'getModifiedUser' )
188 ->willReturn( $userMock );
190 $form->expects( $this->any() )
191 ->method( 'getContext' )
192 ->willReturn( $this->context
);
194 $form->expects( $this->any() )
195 ->method( 'getConfig' )
196 ->willReturn( $configMock );
198 $this->setTemporaryHook( 'PreferencesFormPreSave',
199 function ( $formData, $form, $user, &$result, $oldUserOptions )
200 use ( $newOptions, $oldOptions, $userMock ) {
201 $this->assertSame( $userMock, $user );
202 foreach ( $newOptions as $option => $value ) {
203 $this->assertSame( $value, $formData[ $option ] );
205 foreach ( $oldOptions as $option => $value ) {
206 $this->assertSame( $value, $oldUserOptions[ $option ] );
208 $this->assertEquals( true, $result );
212 /** @var DefaultPreferencesFactory $factory */
213 $factory = TestingAccessWrapper
::newFromObject( $this->getPreferencesFactory() );
214 $factory->saveFormData( $newOptions, $form, [] );
218 * The rclimit preference should accept non-integer input and filter it to become an integer.
220 * @covers \MediaWiki\Preferences\DefaultPreferencesFactory::saveFormData
222 public function testIntvalFilter() {
223 // Test a string with leading zeros (i.e. not octal) and spaces.
224 $this->context
->getRequest()->setVal( 'wprclimit', ' 0012 ' );
226 $form = $this->getPreferencesFactory()->getForm( $user, $this->context
);
229 $this->assertEquals( 12, $user->getOption( 'rclimit' ) );