diff options
Diffstat (limited to 'www/wiki/tests/phpunit/includes/interwiki')
3 files changed, 528 insertions, 0 deletions
diff --git a/www/wiki/tests/phpunit/includes/interwiki/ClassicInterwikiLookupTest.php b/www/wiki/tests/phpunit/includes/interwiki/ClassicInterwikiLookupTest.php new file mode 100644 index 00000000..7fb2cd49 --- /dev/null +++ b/www/wiki/tests/phpunit/includes/interwiki/ClassicInterwikiLookupTest.php @@ -0,0 +1,273 @@ +<?php +/** + * @covers MediaWiki\Interwiki\ClassicInterwikiLookup + * + * @group MediaWiki + * @group Database + */ +class ClassicInterwikiLookupTest extends MediaWikiTestCase { + + private function populateDB( $iwrows ) { + $dbw = wfGetDB( DB_MASTER ); + $dbw->delete( 'interwiki', '*', __METHOD__ ); + $dbw->insert( 'interwiki', array_values( $iwrows ), __METHOD__ ); + $this->tablesUsed[] = 'interwiki'; + } + + public function testDatabaseStorage() { + // NOTE: database setup is expensive, so we only do + // it once and run all the tests in one go. + $dewiki = [ + 'iw_prefix' => 'de', + 'iw_url' => 'http://de.wikipedia.org/wiki/', + 'iw_api' => 'http://de.wikipedia.org/w/api.php', + 'iw_wikiid' => 'dewiki', + 'iw_local' => 1, + 'iw_trans' => 0 + ]; + + $zzwiki = [ + 'iw_prefix' => 'zz', + 'iw_url' => 'http://zzwiki.org/wiki/', + 'iw_api' => 'http://zzwiki.org/w/api.php', + 'iw_wikiid' => 'zzwiki', + 'iw_local' => 0, + 'iw_trans' => 0 + ]; + + $this->populateDB( [ $dewiki, $zzwiki ] ); + $lookup = new \MediaWiki\Interwiki\ClassicInterwikiLookup( + Language::factory( 'en' ), + WANObjectCache::newEmpty(), + 60 * 60, + false, + 3, + 'en' + ); + + $this->assertEquals( + [ $dewiki, $zzwiki ], + $lookup->getAllPrefixes(), + 'getAllPrefixes()' + ); + $this->assertEquals( + [ $dewiki ], + $lookup->getAllPrefixes( true ), + 'getAllPrefixes()' + ); + $this->assertEquals( + [ $zzwiki ], + $lookup->getAllPrefixes( false ), + 'getAllPrefixes()' + ); + + $this->assertTrue( $lookup->isValidInterwiki( 'de' ), 'known prefix is valid' ); + $this->assertFalse( $lookup->isValidInterwiki( 'xyz' ), 'unknown prefix is valid' ); + + $this->assertNull( $lookup->fetch( null ), 'no prefix' ); + $this->assertFalse( $lookup->fetch( 'xyz' ), 'unknown prefix' ); + + $interwiki = $lookup->fetch( 'de' ); + $this->assertInstanceOf( Interwiki::class, $interwiki ); + $this->assertSame( $interwiki, $lookup->fetch( 'de' ), 'in-process caching' ); + + $this->assertSame( 'http://de.wikipedia.org/wiki/', $interwiki->getURL(), 'getURL' ); + $this->assertSame( 'http://de.wikipedia.org/w/api.php', $interwiki->getAPI(), 'getAPI' ); + $this->assertSame( 'dewiki', $interwiki->getWikiID(), 'getWikiID' ); + $this->assertSame( true, $interwiki->isLocal(), 'isLocal' ); + $this->assertSame( false, $interwiki->isTranscludable(), 'isTranscludable' ); + + $lookup->invalidateCache( 'de' ); + $this->assertNotSame( $interwiki, $lookup->fetch( 'de' ), 'invalidate cache' ); + } + + /** + * @param string $thisSite + * @param string[] $local + * @param string[] $global + * + * @return string[] + */ + private function populateHash( $thisSite, $local, $global ) { + $hash = []; + $hash[ '__sites:' . wfWikiID() ] = $thisSite; + + $globals = []; + $locals = []; + + foreach ( $local as $row ) { + $prefix = $row['iw_prefix']; + $data = $row['iw_local'] . ' ' . $row['iw_url']; + $locals[] = $prefix; + $hash[ "_{$thisSite}:{$prefix}" ] = $data; + } + + foreach ( $global as $row ) { + $prefix = $row['iw_prefix']; + $data = $row['iw_local'] . ' ' . $row['iw_url']; + $globals[] = $prefix; + $hash[ "__global:{$prefix}" ] = $data; + } + + $hash[ '__list:__global' ] = implode( ' ', $globals ); + $hash[ '__list:_' . $thisSite ] = implode( ' ', $locals ); + + return $hash; + } + + private function populateCDB( $thisSite, $local, $global ) { + $cdbFile = tempnam( wfTempDir(), 'MW-ClassicInterwikiLookupTest-' ) . '.cdb'; + $cdb = \Cdb\Writer::open( $cdbFile ); + + $hash = $this->populateHash( $thisSite, $local, $global ); + + foreach ( $hash as $key => $value ) { + $cdb->set( $key, $value ); + } + + $cdb->close(); + return $cdbFile; + } + + public function testCDBStorage() { + // NOTE: CDB setup is expensive, so we only do + // it once and run all the tests in one go. + + $zzwiki = [ + 'iw_prefix' => 'zz', + 'iw_url' => 'http://zzwiki.org/wiki/', + 'iw_local' => 0 + ]; + + $dewiki = [ + 'iw_prefix' => 'de', + 'iw_url' => 'http://de.wikipedia.org/wiki/', + 'iw_local' => 1 + ]; + + $cdbFile = $this->populateCDB( + 'en', + [ $dewiki ], + [ $zzwiki ] + ); + $lookup = new \MediaWiki\Interwiki\ClassicInterwikiLookup( + Language::factory( 'en' ), + WANObjectCache::newEmpty(), + 60 * 60, + $cdbFile, + 3, + 'en' + ); + + $this->assertEquals( + [ $zzwiki, $dewiki ], + $lookup->getAllPrefixes(), + 'getAllPrefixes()' + ); + + $this->assertTrue( $lookup->isValidInterwiki( 'de' ), 'known prefix is valid' ); + $this->assertTrue( $lookup->isValidInterwiki( 'zz' ), 'known prefix is valid' ); + + $interwiki = $lookup->fetch( 'de' ); + $this->assertInstanceOf( Interwiki::class, $interwiki ); + + $this->assertSame( 'http://de.wikipedia.org/wiki/', $interwiki->getURL(), 'getURL' ); + $this->assertSame( true, $interwiki->isLocal(), 'isLocal' ); + + $interwiki = $lookup->fetch( 'zz' ); + $this->assertInstanceOf( Interwiki::class, $interwiki ); + + $this->assertSame( 'http://zzwiki.org/wiki/', $interwiki->getURL(), 'getURL' ); + $this->assertSame( false, $interwiki->isLocal(), 'isLocal' ); + + // cleanup temp file + unlink( $cdbFile ); + } + + public function testArrayStorage() { + $zzwiki = [ + 'iw_prefix' => 'zz', + 'iw_url' => 'http://zzwiki.org/wiki/', + 'iw_local' => 0 + ]; + $dewiki = [ + 'iw_prefix' => 'de', + 'iw_url' => 'http://de.wikipedia.org/wiki/', + 'iw_local' => 1 + ]; + + $hash = $this->populateHash( + 'en', + [ $dewiki ], + [ $zzwiki ] + ); + $lookup = new \MediaWiki\Interwiki\ClassicInterwikiLookup( + Language::factory( 'en' ), + WANObjectCache::newEmpty(), + 60 * 60, + $hash, + 3, + 'en' + ); + + $this->assertEquals( + [ $zzwiki, $dewiki ], + $lookup->getAllPrefixes(), + 'getAllPrefixes()' + ); + + $this->assertTrue( $lookup->isValidInterwiki( 'de' ), 'known prefix is valid' ); + $this->assertTrue( $lookup->isValidInterwiki( 'zz' ), 'known prefix is valid' ); + + $interwiki = $lookup->fetch( 'de' ); + $this->assertInstanceOf( Interwiki::class, $interwiki ); + + $this->assertSame( 'http://de.wikipedia.org/wiki/', $interwiki->getURL(), 'getURL' ); + $this->assertSame( true, $interwiki->isLocal(), 'isLocal' ); + + $interwiki = $lookup->fetch( 'zz' ); + $this->assertInstanceOf( Interwiki::class, $interwiki ); + + $this->assertSame( 'http://zzwiki.org/wiki/', $interwiki->getURL(), 'getURL' ); + $this->assertSame( false, $interwiki->isLocal(), 'isLocal' ); + } + + public function testGetAllPrefixes() { + $zz = [ + 'iw_prefix' => 'zz', + 'iw_url' => 'https://azz.example.org/', + 'iw_local' => 1 + ]; + $de = [ + 'iw_prefix' => 'de', + 'iw_url' => 'https://de.example.org/', + 'iw_local' => 1 + ]; + $azz = [ + 'iw_prefix' => 'azz', + 'iw_url' => 'https://azz.example.org/', + 'iw_local' => 1 + ]; + + $hash = $this->populateHash( + 'en', + [], + [ $zz, $de, $azz ] + ); + $lookup = new \MediaWiki\Interwiki\ClassicInterwikiLookup( + Language::factory( 'en' ), + WANObjectCache::newEmpty(), + 60 * 60, + $hash, + 3, + 'en' + ); + + $this->assertEquals( + [ $zz, $de, $azz ], + $lookup->getAllPrefixes(), + 'getAllPrefixes() - preserves order' + ); + } + +} diff --git a/www/wiki/tests/phpunit/includes/interwiki/InterwikiLookupAdapterTest.php b/www/wiki/tests/phpunit/includes/interwiki/InterwikiLookupAdapterTest.php new file mode 100644 index 00000000..0a13de1d --- /dev/null +++ b/www/wiki/tests/phpunit/includes/interwiki/InterwikiLookupAdapterTest.php @@ -0,0 +1,133 @@ +<?php + +use MediaWiki\Interwiki\InterwikiLookupAdapter; + +/** + * @covers MediaWiki\Interwiki\InterwikiLookupAdapter + * + * @group MediaWiki + * @group Interwiki + */ +class InterwikiLookupAdapterTest extends MediaWikiTestCase { + + /** + * @var InterwikiLookupAdapter + */ + private $interwikiLookup; + + protected function setUp() { + parent::setUp(); + + $this->interwikiLookup = new InterwikiLookupAdapter( + $this->getSiteLookup( $this->getSites() ) + ); + } + + public function testIsValidInterwiki() { + $this->assertTrue( + $this->interwikiLookup->isValidInterwiki( 'enwt' ), + 'enwt known prefix is valid' + ); + $this->assertTrue( + $this->interwikiLookup->isValidInterwiki( 'foo' ), + 'foo site known prefix is valid' + ); + $this->assertFalse( + $this->interwikiLookup->isValidInterwiki( 'xyz' ), + 'unknown prefix is not valid' + ); + } + + public function testFetch() { + $interwiki = $this->interwikiLookup->fetch( '' ); + $this->assertNull( $interwiki ); + + $interwiki = $this->interwikiLookup->fetch( 'xyz' ); + $this->assertFalse( $interwiki ); + + $interwiki = $this->interwikiLookup->fetch( 'foo' ); + $this->assertInstanceOf( Interwiki::class, $interwiki ); + $this->assertSame( 'foobar', $interwiki->getWikiID() ); + + $interwiki = $this->interwikiLookup->fetch( 'enwt' ); + $this->assertInstanceOf( Interwiki::class, $interwiki ); + + $this->assertSame( 'https://en.wiktionary.org/wiki/$1', $interwiki->getURL(), 'getURL' ); + $this->assertSame( 'https://en.wiktionary.org/w/api.php', $interwiki->getAPI(), 'getAPI' ); + $this->assertSame( 'enwiktionary', $interwiki->getWikiID(), 'getWikiID' ); + $this->assertTrue( $interwiki->isLocal(), 'isLocal' ); + } + + public function testGetAllPrefixes() { + $foo = [ + 'iw_prefix' => 'foo', + 'iw_url' => '', + 'iw_api' => '', + 'iw_wikiid' => 'foobar', + 'iw_local' => false, + 'iw_trans' => false, + ]; + $enwt = [ + 'iw_prefix' => 'enwt', + 'iw_url' => 'https://en.wiktionary.org/wiki/$1', + 'iw_api' => 'https://en.wiktionary.org/w/api.php', + 'iw_wikiid' => 'enwiktionary', + 'iw_local' => true, + 'iw_trans' => false, + ]; + + $this->assertEquals( + [ $foo, $enwt ], + $this->interwikiLookup->getAllPrefixes(), + 'getAllPrefixes()' + ); + + $this->assertEquals( + [ $foo ], + $this->interwikiLookup->getAllPrefixes( false ), + 'get external prefixes' + ); + + $this->assertEquals( + [ $enwt ], + $this->interwikiLookup->getAllPrefixes( true ), + 'get local prefixes' + ); + } + + private function getSiteLookup( SiteList $sites ) { + $siteLookup = $this->getMockBuilder( SiteLookup::class ) + ->disableOriginalConstructor() + ->getMock(); + + $siteLookup->expects( $this->any() ) + ->method( 'getSites' ) + ->will( $this->returnValue( $sites ) ); + + return $siteLookup; + } + + private function getSites() { + $sites = []; + + $site = new Site(); + $site->setGlobalId( 'foobar' ); + $site->addInterwikiId( 'foo' ); + $site->setSource( 'external' ); + $sites[] = $site; + + $site = new MediaWikiSite(); + $site->setGlobalId( 'enwiktionary' ); + $site->setGroup( 'wiktionary' ); + $site->setLanguageCode( 'en' ); + $site->addNavigationId( 'enwiktionary' ); + $site->addInterwikiId( 'enwt' ); + $site->setSource( 'local' ); + $site->setPath( MediaWikiSite::PATH_PAGE, "https://en.wiktionary.org/wiki/$1" ); + $site->setPath( MediaWikiSite::PATH_FILE, "https://en.wiktionary.org/w/$1" ); + $sites[] = $site; + + return new SiteList( $sites ); + } + +} diff --git a/www/wiki/tests/phpunit/includes/interwiki/InterwikiTest.php b/www/wiki/tests/phpunit/includes/interwiki/InterwikiTest.php new file mode 100644 index 00000000..0d41c520 --- /dev/null +++ b/www/wiki/tests/phpunit/includes/interwiki/InterwikiTest.php @@ -0,0 +1,122 @@ +<?php +use MediaWiki\MediaWikiServices; + +/** + * @covers Interwiki + * + * @group MediaWiki + * @group Database + */ +class InterwikiTest extends MediaWikiTestCase { + + public function testConstructor() { + $interwiki = new Interwiki( + 'xyz', + 'http://xyz.acme.test/wiki/$1', + 'http://xyz.acme.test/w/api.php', + 'xyzwiki', + 1, + 0 + ); + + $this->setContentLang( 'qqx' ); + + $this->assertSame( '(interwiki-name-xyz)', $interwiki->getName() ); + $this->assertSame( '(interwiki-desc-xyz)', $interwiki->getDescription() ); + $this->assertSame( 'http://xyz.acme.test/w/api.php', $interwiki->getAPI() ); + $this->assertSame( 'http://xyz.acme.test/wiki/$1', $interwiki->getURL() ); + $this->assertSame( 'xyzwiki', $interwiki->getWikiID() ); + $this->assertTrue( $interwiki->isLocal() ); + $this->assertFalse( $interwiki->isTranscludable() ); + } + + public function testGetUrl() { + $interwiki = new Interwiki( + 'xyz', + 'http://xyz.acme.test/wiki/$1' + ); + + $this->assertSame( 'http://xyz.acme.test/wiki/$1', $interwiki->getURL() ); + $this->assertSame( 'http://xyz.acme.test/wiki/Foo%26Bar', $interwiki->getURL( 'Foo&Bar' ) ); + } + + //// tests for static data access methods below /////////////////////////////////////////////// + + private function populateDB( $iwrows ) { + $dbw = wfGetDB( DB_MASTER ); + $dbw->delete( 'interwiki', '*', __METHOD__ ); + $dbw->insert( 'interwiki', array_values( $iwrows ), __METHOD__ ); + $this->tablesUsed[] = 'interwiki'; + } + + private function setWgInterwikiCache( $interwikiCache ) { + $this->overrideMwServices(); + MediaWikiServices::getInstance()->resetServiceForTesting( 'InterwikiLookup' ); + $this->setMwGlobals( 'wgInterwikiCache', $interwikiCache ); + } + + public function testDatabaseStorage() { + $this->markTestSkipped( 'Needs I37b8e8018b3 <https://gerrit.wikimedia.org/r/#/c/270555/>' ); + + // NOTE: database setup is expensive, so we only do + // it once and run all the tests in one go. + $dewiki = [ + 'iw_prefix' => 'de', + 'iw_url' => 'http://de.wikipedia.org/wiki/', + 'iw_api' => 'http://de.wikipedia.org/w/api.php', + 'iw_wikiid' => 'dewiki', + 'iw_local' => 1, + 'iw_trans' => 0 + ]; + + $zzwiki = [ + 'iw_prefix' => 'zz', + 'iw_url' => 'http://zzwiki.org/wiki/', + 'iw_api' => 'http://zzwiki.org/w/api.php', + 'iw_wikiid' => 'zzwiki', + 'iw_local' => 0, + 'iw_trans' => 0 + ]; + + $this->populateDB( [ $dewiki, $zzwiki ] ); + + $this->setWgInterwikiCache( false ); + + $interwikiLookup = MediaWikiServices::getInstance()->getInterwikiLookup(); + $this->assertEquals( + [ $dewiki, $zzwiki ], + $interwikiLookup->getAllPrefixes(), + 'getAllPrefixes()' + ); + $this->assertEquals( + [ $dewiki ], + $interwikiLookup->getAllPrefixes( true ), + 'getAllPrefixes()' + ); + $this->assertEquals( + [ $zzwiki ], + $interwikiLookup->getAllPrefixes( false ), + 'getAllPrefixes()' + ); + + $this->assertTrue( $interwikiLookup->isValidInterwiki( 'de' ), 'known prefix is valid' ); + $this->assertFalse( $interwikiLookup->isValidInterwiki( 'xyz' ), 'unknown prefix is valid' ); + + $this->assertNull( $interwikiLookup->fetch( null ), 'no prefix' ); + $this->assertFalse( $interwikiLookup->fetch( 'xyz' ), 'unknown prefix' ); + + $interwiki = $interwikiLookup->fetch( 'de' ); + $this->assertInstanceOf( Interwiki::class, $interwiki ); + $this->assertSame( $interwiki, $interwikiLookup->fetch( 'de' ), 'in-process caching' ); + + $this->assertSame( 'http://de.wikipedia.org/wiki/', $interwiki->getURL(), 'getURL' ); + $this->assertSame( 'http://de.wikipedia.org/w/api.php', $interwiki->getAPI(), 'getAPI' ); + $this->assertSame( 'dewiki', $interwiki->getWikiID(), 'getWikiID' ); + $this->assertSame( true, $interwiki->isLocal(), 'isLocal' ); + $this->assertSame( false, $interwiki->isTranscludable(), 'isTranscludable' ); + + Interwiki::invalidateCache( 'de' ); + $this->assertNotSame( $interwiki, $interwikiLookup->fetch( 'de' ), 'invalidate cache' ); + } + +} |