3 use MediaWiki\Auth\AuthManager
;
4 use MediaWiki\Config\ServiceOptions
;
5 use MediaWiki\MediaWikiServices
;
6 use MediaWiki\Preferences\DefaultPreferencesFactory
;
7 use Wikimedia\TestingAccessWrapper
;
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.
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.
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
31 class DefaultPreferencesFactoryTest
extends \MediaWikiTestCase
{
33 /** @var IContextSource */
39 public function setUp() {
41 $this->context
= new RequestContext();
42 $this->context
->setTitle( Title
::newFromText( self
::class ) );
44 $services = MediaWikiServices
::getInstance();
46 $this->setMwGlobals( 'wgParser', $services->getParserFactory()->create() );
47 $this->config
= $services->getMainConfig();
51 * Get a basic PreferencesFactory for testing with.
52 * @return DefaultPreferencesFactory
54 protected function getPreferencesFactory() {
55 return new DefaultPreferencesFactory(
56 new ServiceOptions( DefaultPreferencesFactory
::$constructorOptions, $this->config
),
58 AuthManager
::singleton(),
59 MediaWikiServices
::getInstance()->getLinkRenderer()
64 * @covers MediaWiki\Preferences\DefaultPreferencesFactory::getForm()
66 public function testGetForm() {
67 $this->setTemporaryHook( 'GetPreferences', null );
69 $testUser = $this->getTestUser();
70 $form = $this->getPreferencesFactory()->getForm( $testUser->getUser(), $this->context
);
71 $this->assertInstanceOf( PreferencesFormOOUI
::class, $form );
72 $this->assertCount( 5, $form->getPreferenceSections() );
76 * CSS classes for emailauthentication preference field when there's no email.
77 * @see https://phabricator.wikimedia.org/T36302
78 * @covers MediaWiki\Preferences\DefaultPreferencesFactory::profilePreferences()
79 * @dataProvider emailAuthenticationProvider
81 public function testEmailAuthentication( $user, $cssClass ) {
82 $prefs = $this->getPreferencesFactory()->getFormDescriptor( $user, $this->context
);
83 $this->assertArrayHasKey( 'cssclass', $prefs['emailauthentication'] );
84 $this->assertEquals( $cssClass, $prefs['emailauthentication']['cssclass'] );
88 * @covers MediaWiki\Preferences\DefaultPreferencesFactory::renderingPreferences()
90 public function testShowRollbackConfIsHiddenForUsersWithoutRollbackRights() {
91 $userMock = $this->getMockBuilder( User
::class )
92 ->disableOriginalConstructor()
94 $userMock->method( 'isAllowed' )
95 ->willReturn( false );
96 $userMock->method( 'getEffectiveGroups' )
98 $userMock->method( 'getGroupMemberships' )
100 $userMock->method( 'getOptions' )
101 ->willReturn( [ 'test' => 'yes' ] );
103 $prefs = $this->getPreferencesFactory()->getFormDescriptor( $userMock, $this->context
);
104 $this->assertArrayNotHasKey( 'showrollbackconfirmation', $prefs );
108 * @covers MediaWiki\Preferences\DefaultPreferencesFactory::renderingPreferences()
110 public function testShowRollbackConfIsShownForUsersWithRollbackRights() {
111 $userMock = $this->getMockBuilder( User
::class )
112 ->disableOriginalConstructor()
114 $userMock->method( 'isAllowed' )
115 ->willReturn( true );
116 $userMock->method( 'getEffectiveGroups' )
118 $userMock->method( 'getGroupMemberships' )
120 $userMock->method( 'getOptions' )
121 ->willReturn( [ 'test' => 'yes' ] );
123 $prefs = $this->getPreferencesFactory()->getFormDescriptor( $userMock, $this->context
);
124 $this->assertArrayHasKey( 'showrollbackconfirmation', $prefs );
126 'rendering/advancedrendering',
127 $prefs['showrollbackconfirmation']['section']
131 public function emailAuthenticationProvider() {
132 $userNoEmail = new User
;
133 $userEmailUnauthed = new User
;
134 $userEmailUnauthed->setEmail( 'noauth@example.org' );
135 $userEmailAuthed = new User
;
136 $userEmailAuthed->setEmail( 'noauth@example.org' );
137 $userEmailAuthed->setEmailAuthenticationTimestamp( wfTimestamp() );
139 [ $userNoEmail, 'mw-email-none' ],
140 [ $userEmailUnauthed, 'mw-email-not-authenticated' ],
141 [ $userEmailAuthed, 'mw-email-authenticated' ],
146 * Test that PreferencesFormPreSave hook has correct data:
147 * - user Object is passed
148 * - oldUserOptions contains previous user options (before save)
149 * - formData and User object have set up new properties
151 * @see https://phabricator.wikimedia.org/T169365
152 * @covers MediaWiki\Preferences\DefaultPreferencesFactory::submitForm()
154 public function testPreferencesFormPreSaveHookHasCorrectData() {
163 $configMock = new HashConfig( [
166 $form = $this->getMockBuilder( PreferencesFormOOUI
::class )
167 ->disableOriginalConstructor()
170 $userMock = $this->getMockBuilder( User
::class )
171 ->disableOriginalConstructor()
173 $userMock->method( 'getOptions' )
174 ->willReturn( $oldOptions );
175 $userMock->method( 'isAllowedAny' )
176 ->willReturn( true );
177 $userMock->method( 'isAllowed' )
178 ->willReturn( true );
180 $userMock->expects( $this->exactly( 2 ) )
181 ->method( 'setOption' )
183 [ $this->equalTo( 'test' ), $this->equalTo( $newOptions[ 'test' ] ) ],
184 [ $this->equalTo( 'option' ), $this->equalTo( $newOptions[ 'option' ] ) ]
187 $form->expects( $this->any() )
188 ->method( 'getModifiedUser' )
189 ->willReturn( $userMock );
191 $form->expects( $this->any() )
192 ->method( 'getContext' )
193 ->willReturn( $this->context
);
195 $form->expects( $this->any() )
196 ->method( 'getConfig' )
197 ->willReturn( $configMock );
199 $this->setTemporaryHook( 'PreferencesFormPreSave',
200 function ( $formData, $form, $user, &$result, $oldUserOptions )
201 use ( $newOptions, $oldOptions, $userMock ) {
202 $this->assertSame( $userMock, $user );
203 foreach ( $newOptions as $option => $value ) {
204 $this->assertSame( $value, $formData[ $option ] );
206 foreach ( $oldOptions as $option => $value ) {
207 $this->assertSame( $value, $oldUserOptions[ $option ] );
209 $this->assertEquals( true, $result );
213 /** @var DefaultPreferencesFactory $factory */
214 $factory = TestingAccessWrapper
::newFromObject( $this->getPreferencesFactory() );
215 $factory->saveFormData( $newOptions, $form, [] );
219 * The rclimit preference should accept non-integer input and filter it to become an integer.
221 * @covers \MediaWiki\Preferences\DefaultPreferencesFactory::saveFormData
223 public function testIntvalFilter() {
224 // Test a string with leading zeros (i.e. not octal) and spaces.
225 $this->context
->getRequest()->setVal( 'wprclimit', ' 0012 ' );
227 $form = $this->getPreferencesFactory()->getForm( $user, $this->context
);
230 $this->assertEquals( 12, $user->getOption( 'rclimit' ) );