setTestTitle( null ); parent::setUp(); // Set up interwikis (via wgInterwikiCache) before creating any Titles $this->setMwGlobals( [ 'wgServer' => '//wiki.local', 'wgCanonicalServer' => 'http://wiki.local', 'wgUsePathInfo' => true, 'wgActionPaths' => [], 'wgScript' => '/w/index.php', 'wgScriptPath' => '/w', 'wgArticlePath' => '/wiki/$1', 'wgInterwikiCache' => ClassicInterwikiLookup::buildCdbHash( [ [ 'iw_prefix' => 'interwikiprefix', 'iw_url' => '//test.wikipedia.org/wiki/$1', 'iw_local' => 0, ], ] ), ] ); $editor = self::getTestSysop()->getUser(); $wikiPageFactory = $this->getServiceContainer()->getWikiPageFactory(); // Page for getContent test $page = $wikiPageFactory->newFromTitle( Title::newFromText( 'ScribuntoTestPage' ) ); $page->doUserEditContent( new WikitextContent( '{{int:mainpage}}......' ), $editor, 'Summary' ); $this->testPageId = $page->getId(); // Pages for redirectTarget tests $page = $wikiPageFactory->newFromTitle( Title::newFromText( 'ScribuntoTestRedirect' ) ); $page->doUserEditContent( new WikitextContent( '#REDIRECT [[ScribuntoTestTarget]]' ), $editor, 'Summary' ); $page = $wikiPageFactory->newFromTitle( Title::newFromText( 'ScribuntoTestNonRedirect' ) ); $page->doUserEditContent( new WikitextContent( 'Not a redirect.' ), $editor, 'Summary' ); // Set restrictions for protectionLevels and cascadingProtection tests $restrictionStore = $this->createNoOpMock( RestrictionStore::class, [ 'getCascadeProtectionSources', 'getRestrictions', 'areRestrictionsLoaded', 'areCascadeProtectionSourcesLoaded', 'getAllRestrictions', 'registerOldRestrictions' // just do nothing ] ); $this->setService( 'RestrictionStore', $restrictionStore ); $restrictionStore->method( 'areRestrictionsLoaded' )->willReturn( true ); $restrictionStore->method( 'areCascadeProtectionSourcesLoaded' )->willReturn( true ); $restrictions = [ 'Main_Page' => [ 'edit' => [], 'move' => [] ], 'Module:TestFramework' => [ 'edit' => [ 'sysop', 'bogus' ], 'move' => [ 'sysop', 'bogus' ], ], 'interwikiprefix:Module:TestFramework' => [], 'Talk:Has/A/Subpage' => [ 'create' => [ 'sysop' ] ], 'Not/A/Subpage' => [ 'edit' => [ 'autoconfirmed' ], 'move' => [ 'sysop' ] ], 'Module_talk:Test_Framework' => [ 'edit' => [], 'move' => [ 'sysop' ] ], ]; $restrictionStore->method( 'getAllRestrictions' ) ->willReturnCallback( static function ( $title ) use ( $restrictions ) { $key = $title->getPrefixedDBkey(); return $restrictions[$key] ?? []; } ); $restrictionStore->method( 'getRestrictions' ) ->willReturnCallback( static function ( $title, $action ) { $key = $title->getPrefixedDBkey(); $pageRestrictions = $restrictions[$key] ?? []; return $pageRestrictions[$action] ?? []; } ); $restrictionStore->method( 'getCascadeProtectionSources' ) ->willReturnCallback( static function ( $title ) { if ( $title->getPrefixedDBkey() === 'Main_Page' ) { return [ [ PageIdentityValue::localIdentity( 5678, NS_MAIN, "Lockbox" ), PageIdentityValue::localIdentity( 8765, NS_MAIN, "Lockbox2" ), ], [ 'edit' => [ 'sysop' ] ] ]; } else { return [ [], [] ]; } } ); // Note this depends on every iteration of the data provider running with a clean parser $this->getEngine()->getParser()->getOptions()->setExpensiveParserFunctionLimit( 10 ); // Indicate to the tests that it's safe to create the title objects $interpreter = $this->getEngine()->getInterpreter(); $interpreter->callFunction( $interpreter->loadString( "mw.title.testPageId = $this->testPageId", 'fortest' ) ); } protected function getTestTitle() { return $this->testTitle ?? parent::getTestTitle(); } protected function setTestTitle( $title ) { $this->testTitle = $title !== null ? Title::newFromText( $title ) : null; $this->resetEngine(); } protected function getTestModules() { return parent::getTestModules() + [ 'TitleLibraryTests' => __DIR__ . '/TitleLibraryTests.lua', ]; } public function testAddsLinks() { $engine = $this->getEngine(); $interpreter = $engine->getInterpreter(); // Loading a title should create a link $links = $engine->getParser()->getOutput()->getLinks(); $this->assertFalse( isset( $links[NS_PROJECT]['Referenced_from_Lua'] ) ); $interpreter->callFunction( $interpreter->loadString( 'local _ = mw.title.new( "Project:Referenced from Lua" ).id', 'reference title' ) ); $links = $engine->getParser()->getOutput()->getLinks(); $this->assertArrayHasKey( NS_PROJECT, $links ); $this->assertArrayHasKey( 'Referenced_from_Lua', $links[NS_PROJECT] ); // Loading the page content should create a templatelink $templates = $engine->getParser()->getOutput()->getTemplates(); $this->assertFalse( isset( $links[NS_PROJECT]['Loaded_from_Lua'] ) ); $interpreter->callFunction( $interpreter->loadString( 'mw.title.new( "Project:Loaded from Lua" ):getContent()', 'load title' ) ); $templates = $engine->getParser()->getOutput()->getTemplates(); $this->assertArrayHasKey( NS_PROJECT, $templates ); $this->assertArrayHasKey( 'Loaded_from_Lua', $templates[NS_PROJECT] ); } /** * @dataProvider provideVaryPageId */ public function testVaryPageId( $testTitle, $code, $flag ) { $this->setTestTitle( $testTitle ); $code = strtr( $code, [ '$$ID$$' => $this->testPageId ] ); $engine = $this->getEngine(); $interpreter = $engine->getInterpreter(); $this->assertFalse( $engine->getParser()->getOutput()->getOutputFlag( ParserOutputFlags::VARY_PAGE_ID ), 'sanity check' ); $interpreter->callFunction( $interpreter->loadString( "local _ = $code", 'reference title but not id' ) ); $this->assertFalse( $engine->getParser()->getOutput()->getOutputFlag( ParserOutputFlags::VARY_PAGE_ID ) ); $interpreter->callFunction( $interpreter->loadString( "local _ = $code.id", 'reference id' ) ); $this->assertSame( $flag, $engine->getParser()->getOutput()->getOutputFlag( ParserOutputFlags::VARY_PAGE_ID ) ); } public function provideVaryPageId() { return [ 'by getCurrentTitle()' => [ 'ScribuntoTestPage', 'mw.title.getCurrentTitle()', true ], 'by name' => [ 'ScribuntoTestPage', 'mw.title.new("ScribuntoTestPage")', true ], 'by id' => [ 'ScribuntoTestPage', 'mw.title.new( $$ID$$ )', true ], 'other page by name' => [ 'ScribuntoTestRedirect', 'mw.title.new("ScribuntoTestPage")', false ], 'other page by id' => [ 'ScribuntoTestRedirect', 'mw.title.new( $$ID$$ )', false ], 'new page by getCurrentTitle()' => [ 'ScribuntoTestPage/DoesNotExist', 'mw.title.getCurrentTitle()', true ], 'new page by name' => [ 'ScribuntoTestPage/DoesNotExist', 'mw.title.new("ScribuntoTestPage/DoesNotExist")', true ], ]; } }