Merge "docs: Fix typo"
[mediawiki.git] / tests / phpunit / includes / language / LanguageConverterTest.php
blobea00b0c1f7b7edf59e59d247eab5fc66f874e8d0
1 <?php
3 use MediaWiki\Context\RequestContext;
4 use MediaWiki\Language\Language;
5 use MediaWiki\Linker\LinkTarget;
6 use MediaWiki\MainConfigNames;
7 use MediaWiki\Page\PageReference;
8 use MediaWiki\Page\PageReferenceValue;
9 use MediaWiki\Title\Title;
10 use MediaWiki\Title\TitleValue;
11 use MediaWiki\User\Options\UserOptionsLookup;
12 use MediaWiki\User\User;
14 /**
15 * @group Language
16 * @covers \MediaWiki\Language\LanguageConverter
18 class LanguageConverterTest extends MediaWikiLangTestCase {
20 /** @var Language */
21 protected $lang;
23 /** @var DummyConverter */
24 protected $lc;
26 private function setContextUser( User $user ) {
27 // LanguageConverter::getPreferredVariant() reads the user from
28 // RequestContext::getMain(), so set it occordingly
29 RequestContext::getMain()->setUser( $user );
32 protected function setUp(): void {
33 parent::setUp();
34 $this->overrideConfigValues( [
35 MainConfigNames::LanguageCode => 'en',
36 MainConfigNames::DefaultLanguageVariant => false,
37 ] );
38 $this->setContentLang( 'tg' );
39 $this->setContextUser( new User );
41 $this->lang = $this->createNoOpMock( Language::class, [ 'factory', 'getNsText', 'ucfirst' ] );
42 $this->lang->method( 'getNsText' )->with( NS_MEDIAWIKI )->willReturn( 'MediaWiki' );
43 $this->lang->method( 'ucfirst' )->willReturnCallback( 'ucfirst' );
44 $this->lc = new DummyConverter( $this->lang );
47 protected function tearDown(): void {
48 unset( $this->lc );
49 unset( $this->lang );
51 parent::tearDown();
54 public function testGetPreferredVariantDefaults() {
55 $this->assertEquals( 'tg', $this->lc->getPreferredVariant() );
58 /**
59 * @dataProvider provideGetPreferredVariant
61 public function testGetPreferredVariant( $requestVal, $expected ) {
62 $request = RequestContext::getMain()->getRequest();
63 $request->setVal( 'variant', $requestVal );
65 $this->assertEquals( $expected, $this->lc->getPreferredVariant() );
68 public static function provideGetPreferredVariant() {
69 yield 'normal (tg-latn)' => [ 'tg-latn', 'tg-latn' ];
70 yield 'deprecated (bat-smg)' => [ 'bat-smg', 'sgs' ];
71 yield 'BCP47 (en-simple)' => [ 'en-simple', 'simple' ];
74 /**
75 * @dataProvider provideGetPreferredVariantHeaders
77 public function testGetPreferredVariantHeaders( $headerVal, $expected ) {
78 $request = RequestContext::getMain()->getRequest();
79 $request->setHeader( 'Accept-Language', $headerVal );
81 $this->assertEquals( $expected, $this->lc->getPreferredVariant() );
84 public static function provideGetPreferredVariantHeaders() {
85 yield 'normal (tg-latn)' => [ 'tg-latn', 'tg-latn' ];
86 yield 'BCP47 (en-simple)' => [ 'en-simple', 'simple' ];
87 yield 'with weight #1' => [ 'tg;q=1', 'tg' ];
88 yield 'with weight #2' => [ 'tg-latn;q=1', 'tg-latn' ];
89 yield 'with multi' => [ 'en, tg-latn;q=1', 'tg-latn' ];
92 /**
93 * @dataProvider provideGetPreferredVariantUserOption
95 public function testGetPreferredVariantUserOption( $optionVal, $expected, $foreignLang ) {
96 $optionName = 'variant';
97 if ( $foreignLang ) {
98 $this->setContentLang( 'en' );
99 $optionName = 'variant-tg';
102 $user = new User;
103 $user->load(); // from 'defaults'
104 $user->mId = 1;
105 $user->mDataLoaded = true;
107 $userOptionsLookup = $this->createMock( UserOptionsLookup::class );
108 $userOptionsLookup->method( 'getOption' )
109 ->with( $user, $optionName )
110 ->willReturn( $optionVal );
111 $this->setService( 'UserOptionsLookup', $userOptionsLookup );
113 $this->setContextUser( $user );
115 $this->assertEquals( $expected, $this->lc->getPreferredVariant() );
118 public static function provideGetPreferredVariantUserOption() {
119 yield 'normal (tg-latn)' => [ 'tg-latn', 'tg-latn', false ];
120 yield 'deprecated (bat-smg)' => [ 'bat-smg', 'sgs', false ];
121 yield 'BCP47 (en-simple)' => [ 'en-simple', 'simple', false ];
122 yield 'for foreign language, normal (tg-latn)' => [ 'tg-latn', 'tg-latn', true ];
123 yield 'for foreign language, deprecated (bat-smg)' => [ 'bat-smg', 'sgs', true ];
124 yield 'for foreign language, BCP47 (en-simple)' => [ 'en-simple', 'simple', true ];
127 public function testGetPreferredVariantHeaderUserVsUrl() {
128 $request = RequestContext::getMain()->getRequest();
130 $this->setContentLang( 'tg-latn' );
131 $request->setVal( 'variant', 'tg' );
133 $user = User::newFromId( "admin" );
134 $user->setId( 1 );
135 $user->mFrom = 'defaults';
136 // The user's data is ignored because the variant is set in the URL.
137 $userOptionsLookup = $this->createMock( UserOptionsLookup::class );
138 $userOptionsLookup->method( 'getOption' )
139 ->with( $user, 'variant' )
140 ->willReturn( 'tg-latn' );
141 $this->setService( 'UserOptionsLookup', $userOptionsLookup );
143 $this->setContextUser( $user );
145 $this->assertEquals( 'tg', $this->lc->getPreferredVariant() );
149 * @dataProvider provideGetPreferredVariant
151 public function testGetPreferredVariantDefaultLanguageVariant( $globalVal, $expected ) {
152 $this->overrideConfigValue( MainConfigNames::DefaultLanguageVariant, $globalVal );
153 $this->assertEquals( $expected, $this->lc->getPreferredVariant() );
156 public function testGetPreferredVariantDefaultLanguageVsUrlVariant() {
157 $request = RequestContext::getMain()->getRequest();
159 $this->setContentLang( 'tg-latn' );
160 $this->overrideConfigValue( MainConfigNames::DefaultLanguageVariant, 'tg' );
161 $request->setVal( 'variant', null );
162 $this->assertEquals( 'tg', $this->lc->getPreferredVariant() );
166 * Test exhausting pcre.backtrack_limit
168 public function testAutoConvertT124404() {
169 $testString = str_repeat( 'xxx xxx xxx', 1000 );
170 $testString .= "\n<big id='в'></big>";
171 $this->setIniSetting( 'pcre.backtrack_limit', 200 );
172 $result = $this->lc->autoConvert( $testString, 'tg-latn' );
173 // The в in the id attribute should not get converted to a v
174 $this->assertStringNotContainsString(
175 'v',
176 $result,
177 "в converted to v despite being in attribue"
182 * @dataProvider provideTitlesToConvert
183 * @param LinkTarget|PageReference|callable $title title to convert
184 * @param string $expected
186 public function testConvertTitle( $title, string $expected ): void {
187 if ( is_callable( $title ) ) {
188 $title = $title();
190 $actual = $this->lc->convertTitle( $title );
191 $this->assertSame( $expected, $actual );
194 public static function provideTitlesToConvert(): array {
195 return [
196 'Title FromText default' => [
197 Title::makeTitle( NS_MAIN, 'Dummy_title' ),
198 'Dummy title',
200 'Title FromText with NS' => [
201 Title::makeTitle( NS_FILE, 'Dummy_title' ),
202 'Акс:Dummy title',
204 'Title MainPage default' => [
205 static function () {
206 // Don't call this until services have been set up
207 return Title::newMainPage();
209 'Саҳифаи аслӣ',
211 'Title MainPage with MessageLocalizer' => [
212 static function () {
213 // Don't call this until services have been set up
214 return Title::newMainPage( new MockMessageLocalizer() );
216 'Саҳифаи аслӣ',
218 'TitleValue' => [
219 new TitleValue( NS_FILE, 'Dummy page' ),
220 'Акс:Dummy page',
222 'PageReference' => [
223 new PageReferenceValue( NS_FILE, 'Dummy page', PageReference::LOCAL ),
224 'Акс:Dummy page',