8 protected function setUp() {
12 'wgAllowUserJs' =>
false,
13 'wgDefaultLanguageVariant' =>
false,
14 'wgMetaNamespace' =>
'Project',
24 $titlechars = Title::legalChars();
26 foreach ( range( 1, 255 ) as $num ) {
28 if ( strpos(
"#[]{}<>|", $chr ) !==
false || preg_match(
"/[\\x00-\\x1f\\x7f]/", $chr ) ) {
30 (
bool)preg_match(
"/[$titlechars]/", $chr ),
31 "chr($num) = $chr is not a valid titlechar"
35 (
bool)preg_match(
"/[$titlechars]/", $chr ),
36 "chr($num) = $chr is a valid titlechar"
53 [
'Talk:Foo:Sandbox' ],
54 [
'File:Example.svg' ],
55 [
'File_talk:Example.svg' ],
56 [
'Foo/.../Sandbox' ],
61 [
'Category:' . str_repeat(
'x', 248 ) ],
62 [ str_repeat(
'x', 252 ) ],
64 [
'localtestiw: #anchor' ],
66 [
'localtestiw:foo' ],
67 [
'localtestiw: foo # anchor' ],
68 [
'localtestiw: Talk: Sandbox # anchor' ],
70 [
'remotetestiw: Talk: # anchor' ],
71 [
'remotetestiw: #bar' ],
72 [
'remotetestiw: Talk:' ],
73 [
'remotetestiw: Talk: Foo' ],
74 [
'localtestiw:remotetestiw:' ],
75 [
'localtestiw:remotetestiw:foo' ]
81 [
'',
'title-invalid-empty' ],
82 [
':',
'title-invalid-empty' ],
83 [
'__ __',
'title-invalid-empty' ],
84 [
' __ ',
'title-invalid-empty' ],
86 [
'A [ B',
'title-invalid-characters' ],
87 [
'A ] B',
'title-invalid-characters' ],
88 [
'A { B',
'title-invalid-characters' ],
89 [
'A } B',
'title-invalid-characters' ],
90 [
'A < B',
'title-invalid-characters' ],
91 [
'A > B',
'title-invalid-characters' ],
92 [
'A | B',
'title-invalid-characters' ],
93 [
"A \t B",
'title-invalid-characters' ],
94 [
"A \n B",
'title-invalid-characters' ],
96 [
'A%20B',
'title-invalid-characters' ],
97 [
'A%23B',
'title-invalid-characters' ],
98 [
'A%2523B',
'title-invalid-characters' ],
106 [
'Talk:File:Example.svg',
'title-invalid-talk-namespace' ],
108 [
'.',
'title-invalid-relative' ],
109 [
'..',
'title-invalid-relative' ],
110 [
'./Sandbox',
'title-invalid-relative' ],
111 [
'../Sandbox',
'title-invalid-relative' ],
112 [
'Foo/./Sandbox',
'title-invalid-relative' ],
113 [
'Foo/../Sandbox',
'title-invalid-relative' ],
114 [
'Sandbox/.',
'title-invalid-relative' ],
115 [
'Sandbox/..',
'title-invalid-relative' ],
117 [
'A ~~~ Name',
'title-invalid-magic-tilde' ],
118 [
'A ~~~~ Signature',
'title-invalid-magic-tilde' ],
119 [
'A ~~~~~ Timestamp',
'title-invalid-magic-tilde' ],
121 [ str_repeat(
'x', 256 ),
'title-invalid-too-long' ],
123 [
'Talk:',
'title-invalid-empty' ],
124 [
'Talk:#',
'title-invalid-empty' ],
125 [
'Category: ',
'title-invalid-empty' ],
126 [
'Category: #bar',
'title-invalid-empty' ],
128 [
'localtestiw: Talk: # anchor',
'title-invalid-empty' ],
129 [
'localtestiw: Talk:',
'title-invalid-empty' ]
135 'wgLocalInterwikis' => [
'localtestiw' ],
137 'InterwikiLoadPrefix' => [
138 function ( $prefix, &$data ) {
139 if ( $prefix ===
'localtestiw' ) {
140 $data = [
'iw_url' =>
'localtestiw' ];
141 } elseif ( $prefix ===
'remotetestiw' ) {
142 $data = [
'iw_url' =>
'remotetestiw' ];
152 Language::factory(
'en' ),
166 $this->assertInstanceOf( Title::class, Title::newFromText( $text ),
"Valid: $text" );
178 Title::newFromTextThrow( $text );
179 $this->assertTrue(
false,
"Invalid: $text" );
181 $this->assertEquals( $expectedErrorMessage, $ex->getErrorMessage(),
"Invalid: $text" );
188 ' %!"$&\'()*,\\-.\\/0-9:;=?@A-Z\\\\^_`a-z~\\x80-\\xFF+',
189 ' %!"$&\'()*,\\-./0-9:;=?@A-Z\\\\\\^_`a-z~+\\u0080-\\uFFFF',
193 'QWERTYf-\\x7F+\\u0080-\\uFFFF',
196 'QWERTY\\x66-\\xFD+',
197 'QWERTYf-\\x7F+\\u0080-\\uFFFF',
205 'QWERTYf-\\x7F+\\u0080-\\uFFFF',
208 'QWERTY\\x66-\\x80+\\x23',
209 'QWERTYf-\\x7F+#\\u0080-\\uFFFF',
212 'QWERTY\\x66-\\x80+\\xD3',
213 'QWERTYf-\\x7F+\\u0080-\\uFFFF',
217 '\\\\\\u0080-\\uFFFF',
221 '\\-\\u0080-\\uFFFF',
225 'QWERTY\\-\\u0080-\\uFFFF',
233 'A-\\x7F\\u0080-\\uFFFF',
236 '\\x66-\\x77QWERTY\\x88-\\x91FXZ',
237 'f-wQWERTYFXZ\\u0080-\\uFFFF',
240 '\\x66-\\x99QWERTY\\xAA-\\xEEFXZ',
241 'f-\\x7FQWERTYFXZ\\u0080-\\uFFFF',
251 $this->assertEquals( $unicodeClass, Title::convertByteClassToUnicodeClass( $byteClass ) );
259 $title = Title::newFromText( $text );
260 $fixed = $title->fixSpecialName();
261 $stuff = explode(
'/', $fixed->getDBkey(), 2 );
262 if ( count( $stuff ) == 2 ) {
270 "T33100 regression check: Title->fixSpecialName() should preserve parameter"
276 [
'Special:Version', null ],
277 [
'Special:Version/',
'' ],
278 [
'Special:Version/param',
'param' ],
294 $title = Title::newFromText(
$source );
295 $nt = Title::newFromText( $target );
296 $errors = $title->isValidMoveOperation( $nt,
false );
297 if ( $expected ===
true ) {
298 $this->assertTrue( $errors );
301 foreach ( (array)$expected as $error ) {
302 $this->assertContains( $error, $errors );
310 [
'Some page',
'',
'badtitletext' ],
311 [
'Test',
'Test',
'selfmove' ],
312 [
'Special:FooBar',
'Test',
'immobile-source-namespace' ],
313 [
'Test',
'Special:FooBar',
'immobile-target-namespace' ],
314 [
'MediaWiki:Common.js',
'Help:Some wikitext page',
'bad-target-model' ],
315 [
'Page',
'File:Test.jpg',
'nonfile-cannot-move-to-file' ],
317 [
'File:Test.jpg',
'Page',
'imagenocrossnamespace' ],
337 if ( is_string( $whitelistRegexp ) ) {
338 $whitelistRegexp = [ $whitelistRegexp ];
343 'wgGroupPermissions' => [
'*' => [
'read' =>
false ] ],
344 'wgWhitelistRead' => [
'some random non sense title' ],
345 'wgWhitelistReadRegexp' => $whitelistRegexp,
348 $title = Title::newFromDBkey(
$source );
353 $errors = $title->userCan( $action, $user );
355 if ( is_bool( $expected ) ) {
356 # Forge the assertion message depending on the assertion expectation
357 $allowableness = $expected
358 ?
" should be allowed"
359 :
" should NOT be allowed";
363 "User action '$action' on [[$source]] $allowableness."
367 foreach ( (array)$expected as $error ) {
368 $this->assertContains( $error, $errors );
382 [
'/.*/',
'Main_Page',
'read', $ALLOWED ],
383 [
'/.*/',
'Main_Page',
'edit', $DISALLOWED ],
386 [
'/^Main_Page$/',
'Main_Page',
'read', $DISALLOWED ],
388 [
'/^Main/',
'Main_Page',
'read', $ALLOWED ],
389 [
'/^Main.*/',
'Main_Page',
'read', $ALLOWED ],
391 [
'/Mic\sCheck/',
'Mic Check',
'read', $ALLOWED ],
394 [
'/Unicode Test . Yes/',
'Unicode Test Ñ Yes',
'read', $DISALLOWED ],
396 [
'/Unicode Test . Yes/u',
'Unicode Test Ñ Yes',
'read', $ALLOWED ],
398 [
'/MiC ChEcK/',
'mic check',
'read', $DISALLOWED ],
399 [
'/MiC ChEcK/i',
'mic check',
'read', $ALLOWED ],
402 [
"@^UsEr.*@i",
'User is banned',
'read', $ALLOWED ],
403 [
"@^UsEr.*@i",
'User:John Doe',
'read', $ALLOWED ],
406 [
'/^Special:NewPages$/',
'Special:NewPages',
'read', $ALLOWED ],
407 [
null,
'Special:Newpages',
'read', $DISALLOWED ],
414 foreach ( $errors as $error ) {
415 $result[] = $error[0];
426 $lang, $variant, $msg =
''
430 'wgDefaultLanguageVariant' => $variant,
431 'wgAllowUserJs' =>
true,
436 $title = Title::newFromText( $titleText );
437 $this->assertInstanceOf( Title::class, $title,
438 "Test must be passed a valid title text, you gave '$titleText'"
440 $this->assertEquals( $expected,
441 $title->getPageViewLanguage()->getCode(),
450 # - wgContLang (expected in most case)
451 # - wgLang (on some specific pages)
452 # - wgDefaultLanguageVariant
455 [
'fr',
'Help:I_need_somebody',
'fr',
'fr',
false ],
456 [
'es',
'Help:I_need_somebody',
'es',
'zh-tw',
false ],
457 [
'zh',
'Help:I_need_somebody',
'zh',
'zh-tw',
false ],
459 [
'es',
'Help:I_need_somebody',
'es',
'zh-tw',
'zh-cn' ],
460 [
'es',
'MediaWiki:About',
'es',
'zh-tw',
'zh-cn' ],
461 [
'es',
'MediaWiki:About/',
'es',
'zh-tw',
'zh-cn' ],
462 [
'de',
'MediaWiki:About/de',
'es',
'zh-tw',
'zh-cn' ],
463 [
'en',
'MediaWiki:Common.js',
'es',
'zh-tw',
'zh-cn' ],
464 [
'en',
'MediaWiki:Common.css',
'es',
'zh-tw',
'zh-cn' ],
465 [
'en',
'User:JohnDoe/Common.js',
'es',
'zh-tw',
'zh-cn' ],
466 [
'en',
'User:JohnDoe/Monobook.css',
'es',
'zh-tw',
'zh-cn' ],
468 [
'zh-cn',
'Help:I_need_somebody',
'zh',
'zh-tw',
'zh-cn' ],
469 [
'zh',
'MediaWiki:About',
'zh',
'zh-tw',
'zh-cn' ],
470 [
'zh',
'MediaWiki:About/',
'zh',
'zh-tw',
'zh-cn' ],
471 [
'de',
'MediaWiki:About/de',
'zh',
'zh-tw',
'zh-cn' ],
472 [
'zh-cn',
'MediaWiki:About/zh-cn',
'zh',
'zh-tw',
'zh-cn' ],
473 [
'zh-tw',
'MediaWiki:About/zh-tw',
'zh',
'zh-tw',
'zh-cn' ],
474 [
'en',
'MediaWiki:Common.js',
'zh',
'zh-tw',
'zh-cn' ],
475 [
'en',
'MediaWiki:Common.css',
'zh',
'zh-tw',
'zh-cn' ],
476 [
'en',
'User:JohnDoe/Common.js',
'zh',
'zh-tw',
'zh-cn' ],
477 [
'en',
'User:JohnDoe/Monobook.css',
'zh',
'zh-tw',
'zh-cn' ],
479 [
'zh-tw',
'Special:NewPages',
'es',
'zh-tw',
'zh-cn' ],
480 [
'zh-tw',
'Special:NewPages',
'zh',
'zh-tw',
'zh-cn' ],
490 $title = Title::newFromText( $title );
491 $this->assertEquals( $expected,
492 $title->getBaseText(),
499 # Title, expected base, optional message
500 [
'User:John_Doe/subOne/subTwo',
'John Doe/subOne' ],
501 [
'User:Foo/Bar/Baz',
'Foo/Bar' ],
510 $title = Title::newFromText( $title );
511 $this->assertEquals( $expected,
512 $title->getRootText(),
519 # Title, expected base, optional message
520 [
'User:John_Doe/subOne/subTwo',
'John Doe' ],
521 [
'User:Foo/Bar/Baz',
'Foo' ],
531 $title = Title::newFromText( $title );
532 $this->assertEquals( $expected,
533 $title->getSubpageText(),
540 # Title, expected base, optional message
541 [
'User:John_Doe/subOne/subTwo',
'subTwo' ],
542 [
'User:John_Doe/subOne',
'subOne' ],
559 $title = Title::newFromTitleValue(
$value );
561 $dbkey = str_replace(
' ',
'_',
$value->getText() );
562 $this->assertEquals( $dbkey, $title->getDBkey() );
563 $this->assertEquals(
$value->getNamespace(), $title->getNamespace() );
564 $this->assertEquals(
$value->getFragment(), $title->getFragment() );
571 [
'User:Hansi_Maier' ],
580 $title = Title::newFromText( $text );
581 $value = $title->getTitleValue();
583 $dbkey = str_replace(
' ',
'_',
$value->getText() );
584 $this->assertEquals( $title->getDBkey(), $dbkey );
585 $this->assertEquals( $title->getNamespace(),
$value->getNamespace() );
586 $this->assertEquals( $title->getFragment(),
$value->getFragment() );
592 [
'Foo#bar',
'bar' ],
593 [
'Foo#bär',
'bär' ],
596 [
'Foo#bar_bar',
'bar bar' ],
597 [
'Foo#bar bar',
'bar bar' ],
598 [
'Foo#bar bar',
'bar bar' ],
602 [
'Foo#_bar_bar_',
' bar bar' ],
603 [
'Foo# bar bar ',
' bar bar' ],
615 $title = Title::newFromText( $full );
616 $this->assertEquals( $fragment, $title->getFragment() );
626 $title = Title::newFromText( $page );
627 $this->assertEquals( $isKnown, $title->isAlwaysKnown() );
632 [
'Some nonexistent page',
false ],
635 [
'Special:BlankPage',
true ],
636 [
'Special:SomeNonexistentSpecialPage',
false ],
637 [
'MediaWiki:Parentheses',
true ],
638 [
'MediaWiki:Some nonexistent message',
false ],
649 $this->assertEquals( $isValid, $title->isValid(), $title->getPrefixedText() );
659 [ Title::makeTitle( -33,
'Test' ),
false ],
660 [ Title::makeTitle( 77663399,
'Test' ),
false ],
668 $title = Title::makeTitle(
NS_MAIN,
'Interwiki link',
'',
'externalwiki' );
669 $this->assertTrue( $title->isAlwaysKnown() );
676 $title = Title::makeTitle(
NS_PROJECT,
'New page' );
677 $linkCache = LinkCache::singleton();
679 $article =
new Article( $title );
680 $page = $article->getPage();
681 $page->doEditContent(
new WikitextContent(
'Some [[link]]' ),
'summary' );
684 $title->mArticleID = -1;
687 $linkCache->clearLink( $title );
688 $linkCache->addBadLinkObj( $title );
693 'exists() should rely on link cache unless GAID_FOR_UPDATE is used'
697 $title->exists( Title::GAID_FOR_UPDATE ),
698 'exists() should re-query database when GAID_FOR_UPDATE is used'
704 'User page has talk page' => [
705 Title::makeTitle( NS_USER,
'Jane' ),
true
707 'Talke page has talk page' => [
710 'Special page cannot have talk page' => [
713 'Virtual namespace cannot have talk page' => [
727 $actual = $title->canHaveTalkPage();
728 $this->assertSame( $expected, $actual, $title->getPrefixedDBkey() );
739 $actual = $title->canTalk();
740 $this->assertSame( $expected, $actual, $title->getPrefixedDBkey() );
745 [ Title::makeTitle(
NS_MAIN,
'Test' ), Title::makeTitle(
NS_TALK,
'Test' ) ],
746 [ Title::makeTitle(
NS_TALK,
'Test' ), Title::makeTitle(
NS_TALK,
'Test' ) ],
755 $talk = $title->getTalkPage();
757 $expected->getPrefixedDBKey(),
758 $talk->getPrefixedDBKey(),
759 $title->getPrefixedDBKey()
768 $talk = $title->getTalkPageIfDefined();
769 $this->assertInstanceOf(
772 $title->getPrefixedDBKey()
779 [ Title::makeTitle(
NS_MEDIA,
'Test' ) ],
788 $talk = $title->getTalkPageIfDefined();
791 $title->getPrefixedDBKey()
797 [ Title::makeTitle(
NS_MAIN,
'Test' ),
'foo' ],
798 [ Title::makeTitle(
NS_TALK,
'Test',
'foo' ),
'' ],
799 [ Title::makeTitle(
NS_CATEGORY,
'Test',
'foo' ),
'bar' ],
800 [ Title::makeTitle(
NS_MAIN,
'Test1',
'',
'interwiki' ),
'baz' ]
810 'InterwikiLoadPrefix' => [
811 function ( $prefix, &$iwdata ) {
812 if ( $prefix ===
'interwiki' ) {
814 'iw_url' =>
'http://example.com/',
824 $fragmentTitle = $title->createFragmentTarget( $fragment );
826 $this->assertEquals( $title->getNamespace(), $fragmentTitle->getNamespace() );
827 $this->assertEquals( $title->getText(), $fragmentTitle->getText() );
828 $this->assertEquals( $title->getInterwiki(), $fragmentTitle->getInterwiki() );
829 $this->assertEquals( $fragment, $fragmentTitle->getFragment() );
836 Title::makeTitle(
NS_MAIN,
'Foo bar' ),
841 Title::makeTitle( NS_USER,
'Foo bar' ),
851 Title::makeTitle(
NS_MAIN,
'Foo bar',
'fragment' ),
856 Title::makeTitle(
NS_MEDIA,
'Foo bar' ),
861 Title::makeTitle( 100777,
'Foo bar' ),
862 'Special:Badtitle/NS100777:Foo bar'
872 $this->assertEquals( $expected, $title->getPrefixedText() );
879 Title::makeTitle(
NS_MAIN,
'Foo_bar' ),
884 Title::makeTitle( NS_USER,
'Foo_bar' ),
894 Title::makeTitle(
NS_MAIN,
'Foo_bar',
'fragment' ),
899 Title::makeTitle(
NS_MEDIA,
'Foo_bar' ),
904 Title::makeTitle( 100777,
'Foo_bar' ),
905 'Special:Badtitle/NS100777:Foo_bar'
915 $this->assertEquals( $expected, $title->getPrefixedDBkey() );
927 'wgFragmentMode' => [
'html5' ],
928 'wgExternalInterwikiFragmentMode' =>
'legacy',
931 $dbw->insert(
'interwiki',
935 'iw_url' =>
'http://de.wikipedia.org/wiki/',
936 'iw_api' =>
'http://de.wikipedia.org/w/api.php',
937 'iw_wikiid' =>
'dewiki',
943 'iw_url' =>
'http://zzwiki.org/wiki/',
944 'iw_api' =>
'http://zzwiki.org/w/api.php',
945 'iw_wikiid' =>
'zzwiki',
954 $title = Title::newFromText( $titleStr );
955 self::assertEquals( $expected, $title->getFragmentForURL() );
957 $dbw->delete(
'interwiki',
'*', __METHOD__ );
963 [
'Foo#ümlåût',
'#ümlåût' ],
964 [
'de:Foo#Bå®',
'#Bå®' ],
965 [
'zz:Foo#тест',
'#.D1.82.D0.B5.D1.81.D1.82' ],
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
Class for viewing MediaWiki article and history.
Caches user genders when needed to use correct namespace aliases.
testFixSpecialNameRetainsParameter( $text, $expectedParam)
provideSpecialNamesWithAndWithoutParameter Title::fixSpecialName
testIsAlwaysKnown( $page, $isKnown)
Title::isAlwaysKnown provideIsAlwaysKnown.
testGetFragment( $full, $fragment)
Title::getFragment provideGetFragment.
flattenErrorsArray( $errors)
testGetPageViewLanguage( $expected, $titleText, $contLang, $lang, $variant, $msg='')
provideGetPageViewLanguage Title::getPageViewLanguage
static provideBaseTitleCases()
static provideConvertByteClassToUnicodeClass()
testGetFragmentForURL( $titleStr, $expected)
Title::getFragmentForURL provideGetFragmentForURL.
testGetTitleValue( $text)
Title::getTitleValue provideGetTitleValue.
testWgWhitelistReadRegexp( $whitelistRegexp, $source, $action, $expected)
Auth-less test of Title::userCan.
static provideTestIsValidMoveOperation()
testGetPrefixedDBKey(Title $title, $expected)
Title::getPrefixedDBKey provideGetPrefixedDBKey.
testIsValidMoveOperation( $source, $target, $expected)
Auth-less test of Title::isValidMoveOperation.
provideCreateFragmentTitle()
testGetBaseText( $title, $expected, $msg='')
provideBaseTitleCases Title::getBaseText
testGetTalkPageIfDefined_good(Title $title)
provideGetTalkPage_good Title::getTalkPageIfDefined
static provideRootTitleCases()
static provideGetTalkPage_bad()
testNewFromTitleValue(TitleValue $value)
Title::newFromTitleValue provideNewFromTitleValue.
static provideIsAlwaysKnown()
static provideGetTitleValue()
static provideGetFragment()
testSecureAndSplitInvalid( $text, $expectedErrorMessage)
See also mediawiki.Title.test.js Title::secureAndSplit provideInvalidSecureAndSplit.
testGetRootText( $title, $expected, $msg='')
provideRootTitleCases Title::getRootText
dataWgWhitelistReadRegexp()
Provides test parameter values for testWgWhitelistReadRegexp()
testGetTalkPage_good(Title $title, Title $expected)
provideGetTalkPage_good Title::getTalkPage
testCanTalk(Title $title, $expected)
provideCanHaveTalkPage Title::canTalk
testConvertByteClassToUnicodeClass( $byteClass, $unicodeClass)
provideConvertByteClassToUnicodeClass Title::convertByteClassToUnicodeClass
testGetSubpageText( $title, $expected, $msg='')
provideGetPrefixedDBKey()
static provideSubpageTitleCases()
testCanHaveTalkPage(Title $title, $expected)
provideCanHaveTalkPage Title::canHaveTalkPage
testGetPrefixedText(Title $title, $expected)
Title::getPrefixedText provideGetPrefixedText.
static provideGetPageViewLanguage()
testLegalChars()
Title::legalChars.
testExists()
Title::exists.
testSecureAndSplitValid( $text)
See also mediawiki.Title.test.js Title::secureAndSplit provideValidSecureAndSplit.
testIsAlwaysKnownOnInterwiki()
Title::isAlwaysKnown.
static provideInvalidSecureAndSplit()
static provideNewFromTitleValue()
static provideValidSecureAndSplit()
testGetTalkPageIfDefined_bad(Title $title)
provideGetTalkPage_bad Title::getTalkPageIfDefined
testCreateFragmentTitle(Title $title, $fragment)
Title::createFragmentTarget provideCreateFragmentTitle.
provideGetFragmentForURL()
static provideSpecialNamesWithAndWithoutParameter()
testIsValid(Title $title, $isValid)
Title::isValid provideIsValid.
static provideGetTalkPage_good()
Represents a page (or page fragment) title within MediaWiki.
Represents a title within MediaWiki.
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Content object for wiki text pages.
namespace being checked & $result
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return true
processing should stop and the error should be shown to the user * false
if(!isset( $args[0])) $lang