MediaWiki  1.23.13
MediaWikiTitleCodecTest.php
Go to the documentation of this file.
1 <?php
31 
32  public function setUp() {
33  parent::setUp();
34 
35  $this->setMwGlobals( array(
36  'wgLanguageCode' => 'en',
37  'wgContLang' => Language::factory( 'en' ),
38  // User language
39  'wgLang' => Language::factory( 'en' ),
40  'wgAllowUserJs' => false,
41  'wgDefaultLanguageVariant' => false,
42  'wgLocalInterwikis' => array( 'localtestiw' ),
43 
44  // NOTE: this is why global state is evil.
45  // TODO: refactor access to the interwiki codes so it can be injected.
46  'wgHooks' => array(
47  'InterwikiLoadPrefix' => array(
48  function ( $prefix, &$data ) {
49  if ( $prefix === 'localtestiw' ) {
50  $data = array( 'iw_url' => 'localtestiw' );
51  } elseif ( $prefix === 'remotetestiw' ) {
52  $data = array( 'iw_url' => 'remotetestiw' );
53  }
54  return false;
55  }
56  )
57  )
58  ) );
59  }
60 
67  private function getGenderCache() {
68  $genderCache = $this->getMockBuilder( 'GenderCache' )
69  ->disableOriginalConstructor()
70  ->getMock();
71 
72  $genderCache->expects( $this->any() )
73  ->method( 'getGenderOf' )
74  ->will( $this->returnCallback( function( $userName ) {
75  return preg_match( '/^[^- _]+a( |_|$)/u', $userName ) ? 'female' : 'male';
76  } ) );
77 
78  return $genderCache;
79  }
80 
81  protected function makeCodec( $lang ) {
82  $gender = $this->getGenderCache();
83  $lang = Language::factory( $lang );
84  return new MediaWikiTitleCodec( $lang, $gender );
85  }
86 
87  public function provideFormat() {
88  return array(
89  array( NS_MAIN, 'Foo_Bar', '', 'en', 'Foo Bar' ),
90  array( NS_USER, 'Hansi_Maier', 'stuff_and_so_on', 'en', 'User:Hansi Maier#stuff and so on' ),
91  array( false, 'Hansi_Maier', '', 'en', 'Hansi Maier' ),
92  array( NS_USER_TALK, 'hansi__maier', '', 'en', 'User talk:hansi maier', 'User talk:Hansi maier' ),
93 
94  // getGenderCache() provides a mock that considers first
95  // names ending in "a" to be female.
96  array( NS_USER, 'Lisa_Müller', '', 'de', 'Benutzerin:Lisa Müller' ),
97  );
98  }
99 
103  public function testFormat( $namespace, $text, $fragment, $lang, $expected, $normalized = null ) {
104  if ( $normalized === null ) {
105  $normalized = $expected;
106  }
107 
108  $codec = $this->makeCodec( $lang );
109  $actual = $codec->formatTitle( $namespace, $text, $fragment );
110 
111  $this->assertEquals( $expected, $actual, 'formatted' );
112 
113  // test round trip
114  $parsed = $codec->parseTitle( $actual, NS_MAIN );
115  $actual2 = $codec->formatTitle( $parsed->getNamespace(), $parsed->getText(), $parsed->getFragment() );
116 
117  $this->assertEquals( $normalized, $actual2, 'normalized after round trip' );
118  }
119 
120  public function provideGetText() {
121  return array(
122  array( NS_MAIN, 'Foo_Bar', '', 'en', 'Foo Bar' ),
123  array( NS_USER, 'Hansi_Maier', 'stuff_and_so_on', 'en', 'Hansi Maier' ),
124  );
125  }
126 
130  public function testGetText( $namespace, $dbkey, $fragment, $lang, $expected ) {
131  $codec = $this->makeCodec( $lang );
132  $title = new TitleValue( $namespace, $dbkey, $fragment );
133 
134  $actual = $codec->getText( $title );
135 
136  $this->assertEquals( $expected, $actual );
137  }
138 
139  public function provideGetPrefixedText() {
140  return array(
141  array( NS_MAIN, 'Foo_Bar', '', 'en', 'Foo Bar' ),
142  array( NS_USER, 'Hansi_Maier', 'stuff_and_so_on', 'en', 'User:Hansi Maier' ),
143 
144  // No capitalization or normalization is applied while formatting!
145  array( NS_USER_TALK, 'hansi__maier', '', 'en', 'User talk:hansi maier' ),
146 
147  // getGenderCache() provides a mock that considers first
148  // names ending in "a" to be female.
149  array( NS_USER, 'Lisa_Müller', '', 'de', 'Benutzerin:Lisa Müller' ),
150  );
151  }
152 
156  public function testGetPrefixedText( $namespace, $dbkey, $fragment, $lang, $expected ) {
157  $codec = $this->makeCodec( $lang );
158  $title = new TitleValue( $namespace, $dbkey, $fragment );
159 
160  $actual = $codec->getPrefixedText( $title );
161 
162  $this->assertEquals( $expected, $actual );
163  }
164 
165  public function provideGetFullText() {
166  return array(
167  array( NS_MAIN, 'Foo_Bar', '', 'en', 'Foo Bar' ),
168  array( NS_USER, 'Hansi_Maier', 'stuff_and_so_on', 'en', 'User:Hansi Maier#stuff and so on' ),
169 
170  // No capitalization or normalization is applied while formatting!
171  array( NS_USER_TALK, 'hansi__maier', '', 'en', 'User talk:hansi maier' ),
172  );
173  }
174 
178  public function testGetFullText( $namespace, $dbkey, $fragment, $lang, $expected ) {
179  $codec = $this->makeCodec( $lang );
180  $title = new TitleValue( $namespace, $dbkey, $fragment );
181 
182  $actual = $codec->getFullText( $title );
183 
184  $this->assertEquals( $expected, $actual );
185  }
186 
187  public function provideParseTitle() {
188  //TODO: test capitalization and trimming
189  //TODO: test unicode normalization
190 
191  return array(
192  array( ' : Hansi_Maier _ ', NS_MAIN, 'en',
193  new TitleValue( NS_MAIN, 'Hansi_Maier', '' ) ),
194  array( 'User:::1', NS_MAIN, 'de',
195  new TitleValue( NS_USER, '0:0:0:0:0:0:0:1', '' ) ),
196  array( ' lisa Müller', NS_USER, 'de',
197  new TitleValue( NS_USER, 'Lisa_Müller', '' ) ),
198  array( 'benutzerin:lisa Müller#stuff', NS_MAIN, 'de',
199  new TitleValue( NS_USER, 'Lisa_Müller', 'stuff' ) ),
200 
201  array( ':Category:Quux', NS_MAIN, 'en',
202  new TitleValue( NS_CATEGORY, 'Quux', '' ) ),
203  array( 'Category:Quux', NS_MAIN, 'en',
204  new TitleValue( NS_CATEGORY, 'Quux', '' ) ),
205  array( 'Category:Quux', NS_CATEGORY, 'en',
206  new TitleValue( NS_CATEGORY, 'Quux', '' ) ),
207  array( 'Quux', NS_CATEGORY, 'en',
208  new TitleValue( NS_CATEGORY, 'Quux', '' ) ),
209  array( ':Quux', NS_CATEGORY, 'en',
210  new TitleValue( NS_MAIN, 'Quux', '' ) ),
211 
212  // getGenderCache() provides a mock that considers first
213  // names ending in "a" to be female.
214 
215  array( 'a b c', NS_MAIN, 'en',
216  new TitleValue( NS_MAIN, 'A_b_c' ) ),
217  array( ' a b c ', NS_MAIN, 'en',
218  new TitleValue( NS_MAIN, 'A_b_c' ) ),
219  array( ' _ Foo __ Bar_ _', NS_MAIN, 'en',
220  new TitleValue( NS_MAIN, 'Foo_Bar' ) ),
221 
222  //NOTE: cases copied from TitleTest::testSecureAndSplit. Keep in sync.
223  array( 'Sandbox', NS_MAIN, 'en', ),
224  array( 'A "B"', NS_MAIN, 'en', ),
225  array( 'A \'B\'', NS_MAIN, 'en', ),
226  array( '.com', NS_MAIN, 'en', ),
227  array( '~', NS_MAIN, 'en', ),
228  array( '"', NS_MAIN, 'en', ),
229  array( '\'', NS_MAIN, 'en', ),
230 
231  array( 'Talk:Sandbox', NS_MAIN, 'en',
232  new TitleValue( NS_TALK, 'Sandbox' ) ),
233  array( 'Talk:Foo:Sandbox', NS_MAIN, 'en',
234  new TitleValue( NS_TALK, 'Foo:Sandbox' ) ),
235  array( 'File:Example.svg', NS_MAIN, 'en',
236  new TitleValue( NS_FILE, 'Example.svg' ) ),
237  array( 'File_talk:Example.svg', NS_MAIN, 'en',
238  new TitleValue( NS_FILE_TALK, 'Example.svg' ) ),
239  array( 'Foo/.../Sandbox', NS_MAIN, 'en',
240  'Foo/.../Sandbox' ),
241  array( 'Sandbox/...', NS_MAIN, 'en',
242  'Sandbox/...' ),
243  array( 'A~~', NS_MAIN, 'en',
244  'A~~' ),
245  // Length is 256 total, but only title part matters
246  array( 'Category:' . str_repeat( 'x', 248 ), NS_MAIN, 'en',
247  new TitleValue( NS_CATEGORY,
248  'X' . str_repeat( 'x', 247 ) ) ),
249  array( str_repeat( 'x', 252 ), NS_MAIN, 'en',
250  'X' . str_repeat( 'x', 251 ) )
251  );
252  }
253 
257  public function testParseTitle( $text, $ns, $lang, $title = null ) {
258  if ( $title === null ) {
259  $title = str_replace( ' ', '_', trim( $text ) );
260  }
261 
262  if ( is_string( $title ) ) {
263  $title = new TitleValue( NS_MAIN, $title, '' );
264  }
265 
266  $codec = $this->makeCodec( $lang );
267  $actual = $codec->parseTitle( $text, $ns );
268 
269  $this->assertEquals( $title, $actual );
270  }
271 
272  public function provideParseTitle_invalid() {
273  //TODO: test unicode errors
274 
275  return array(
276  array( '#' ),
277  array( '::' ),
278  array( '::xx' ),
279  array( '::##' ),
280  array( ' :: x' ),
281 
282  array( 'Talk:File:Foo.jpg' ),
283  array( 'Talk:localtestiw:Foo' ),
284  array( 'remotetestiw:Foo' ),
285  array( '::1' ), // only valid in user namespace
286  array( 'User::x' ), // leading ":" in a user name is only valid of IPv6 addresses
287 
288  //NOTE: cases copied from TitleTest::testSecureAndSplit. Keep in sync.
289  array( '' ),
290  array( ':' ),
291  array( '__ __' ),
292  array( ' __ ' ),
293  // Bad characters forbidden regardless of wgLegalTitleChars
294  array( 'A [ B' ),
295  array( 'A ] B' ),
296  array( 'A { B' ),
297  array( 'A } B' ),
298  array( 'A < B' ),
299  array( 'A > B' ),
300  array( 'A | B' ),
301  // URL encoding
302  array( 'A%20B' ),
303  array( 'A%23B' ),
304  array( 'A%2523B' ),
305  // XML/HTML character entity references
306  // Note: Commented out because they are not marked invalid by the PHP test as
307  // Title::newFromText runs Sanitizer::decodeCharReferencesAndNormalize first.
308  //array( 'A &eacute; B' ),
309  //array( 'A &#233; B' ),
310  //array( 'A &#x00E9; B' ),
311  // Subject of NS_TALK does not roundtrip to NS_MAIN
312  array( 'Talk:File:Example.svg' ),
313  // Directory navigation
314  array( '.' ),
315  array( '..' ),
316  array( './Sandbox' ),
317  array( '../Sandbox' ),
318  array( 'Foo/./Sandbox' ),
319  array( 'Foo/../Sandbox' ),
320  array( 'Sandbox/.' ),
321  array( 'Sandbox/..' ),
322  // Tilde
323  array( 'A ~~~ Name' ),
324  array( 'A ~~~~ Signature' ),
325  array( 'A ~~~~~ Timestamp' ),
326  array( str_repeat( 'x', 256 ) ),
327  // Namespace prefix without actual title
328  array( 'Talk:' ),
329  array( 'Category: ' ),
330  array( 'Category: #bar' )
331  );
332  }
333 
337  public function testParseTitle_invalid( $text ) {
338  $this->setExpectedException( 'MalformedTitleException' );
339 
340  $codec = $this->makeCodec( 'en' );
341  $codec->parseTitle( $text, NS_MAIN );
342  }
343 
344  public function provideGetNamespaceName() {
345  return array(
346  array( NS_MAIN, 'Foo', 'en', '' ),
347  array( NS_USER, 'Foo', 'en', 'User' ),
348  array( NS_USER, 'Hansi Maier', 'de', 'Benutzer' ),
349 
350  // getGenderCache() provides a mock that considers first
351  // names ending in "a" to be female.
352  array( NS_USER, 'Lisa Müller', 'de', 'Benutzerin' ),
353  );
354  }
355 
366  public function testGetNamespaceName( $namespace, $text, $lang, $expected ) {
367  $codec = $this->makeCodec( $lang );
368  $name = $codec->getNamespaceName( $namespace, $text );
369 
370  $this->assertEquals( $expected, $name );
371  }
372 }
MediaWikiTitleCodecTest\testParseTitle_invalid
testParseTitle_invalid( $text)
@dataProvider provideParseTitle_invalid
Definition: MediaWikiTitleCodecTest.php:337
MediaWikiTitleCodec
A codec for MediaWiki page titles.
Definition: MediaWikiTitleCodec.php:35
php
skin txt MediaWiki includes four core it has been set as the default in MediaWiki since the replacing Monobook it had been been the default skin since before being replaced by Vector largely rewritten in while keeping its appearance Several legacy skins were removed in the as the burden of supporting them became too heavy to bear Those in etc for skin dependent CSS etc for skin dependent JavaScript These can also be customised on a per user by etc This feature has led to a wide variety of user styles becoming that gallery is a good place to ending in php
Definition: skin.txt:62
MediaWikiTitleCodecTest\testFormat
testFormat( $namespace, $text, $fragment, $lang, $expected, $normalized=null)
@dataProvider provideFormat
Definition: MediaWikiTitleCodecTest.php:103
NS_FILE
const NS_FILE
Definition: Defines.php:85
MediaWikiTitleCodecTest\provideGetFullText
provideGetFullText()
Definition: MediaWikiTitleCodecTest.php:165
MediaWikiTitleCodecTest\provideParseTitle_invalid
provideParseTitle_invalid()
Definition: MediaWikiTitleCodecTest.php:272
NS_MAIN
const NS_MAIN
Definition: Defines.php:79
MediaWikiTestCase\setMwGlobals
setMwGlobals( $pairs, $value=null)
Definition: MediaWikiTestCase.php:302
MediaWikiTitleCodecTest\testGetFullText
testGetFullText( $namespace, $dbkey, $fragment, $lang, $expected)
@dataProvider provideGetFullText
Definition: MediaWikiTitleCodecTest.php:178
MediaWikiTestCase
Definition: MediaWikiTestCase.php:6
MediaWikiTitleCodecTest
@covers MediaWikiTitleCodec
Definition: MediaWikiTitleCodecTest.php:30
array
the array() calling protocol came about after MediaWiki 1.4rc1.
List of Api Query prop modules.
NS_CATEGORY
const NS_CATEGORY
Definition: Defines.php:93
MediaWikiTitleCodecTest\provideGetText
provideGetText()
Definition: MediaWikiTitleCodecTest.php:120
MediaWikiTitleCodecTest\testGetNamespaceName
testGetNamespaceName( $namespace, $text, $lang, $expected)
@dataProvider provideGetNamespaceName
Definition: MediaWikiTitleCodecTest.php:366
MediaWikiTitleCodecTest\provideFormat
provideFormat()
Definition: MediaWikiTitleCodecTest.php:87
$title
presenting them properly to the user as errors is done by the caller $title
Definition: hooks.txt:1324
NS_USER_TALK
const NS_USER_TALK
Definition: Defines.php:82
MediaWikiTitleCodecTest\makeCodec
makeCodec( $lang)
Definition: MediaWikiTitleCodecTest.php:81
$name
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:336
MediaWikiTitleCodecTest\provideGetNamespaceName
provideGetNamespaceName()
Definition: MediaWikiTitleCodecTest.php:344
MediaWikiTitleCodecTest\provideGetPrefixedText
provideGetPrefixedText()
Definition: MediaWikiTitleCodecTest.php:139
NS_USER
const NS_USER
Definition: Defines.php:81
NS_TALK
const NS_TALK
Definition: Defines.php:80
MediaWikiTitleCodecTest\getGenderCache
getGenderCache()
Returns a mock GenderCache that will consider a user "female" if the first part of the user name ends...
Definition: MediaWikiTitleCodecTest.php:67
Language\factory
static factory( $code)
Get a cached or new language object for a given language code.
Definition: Language.php:184
MediaWikiTitleCodecTest\testParseTitle
testParseTitle( $text, $ns, $lang, $title=null)
@dataProvider provideParseTitle
Definition: MediaWikiTitleCodecTest.php:257
MediaWikiTitleCodecTest\provideParseTitle
provideParseTitle()
Definition: MediaWikiTitleCodecTest.php:187
NS_FILE_TALK
const NS_FILE_TALK
Definition: Defines.php:86
MediaWikiTitleCodecTest\testGetText
testGetText( $namespace, $dbkey, $fragment, $lang, $expected)
@dataProvider provideGetText
Definition: MediaWikiTitleCodecTest.php:130
MediaWikiTitleCodecTest\setUp
setUp()
Definition: MediaWikiTitleCodecTest.php:32
MediaWikiTitleCodecTest\testGetPrefixedText
testGetPrefixedText( $namespace, $dbkey, $fragment, $lang, $expected)
@dataProvider provideGetPrefixedText
Definition: MediaWikiTitleCodecTest.php:156
TitleValue
Represents a page (or page fragment) title within MediaWiki.
Definition: TitleValue.php:36