From: Amir Sarabadani Date: Mon, 8 Jul 2019 13:25:31 +0000 (+0200) Subject: Unset all globals unneeded for unit tests, assert correct directory X-Git-Tag: 1.34.0-rc.0~1113^2 X-Git-Url: http://git.cyclocoop.org/clavettes/images/siteon3.jpg?a=commitdiff_plain;h=d23af35764bc7a5f223852d25baf554f1ae8f944;p=lhc%2Fweb%2Fwiklou.git Unset all globals unneeded for unit tests, assert correct directory * Unset globals to avoid tests that look like unit tests but actually rely on globals * move some tests out of unit directory so that the test suite will pass. * Assert that tests which extend MediaWikiUnitTestCase are in a directory with "/unit/" in its path name Depends-On: I67b37b1bde94eaa3d4298d9bd98ac57995ce93b9 Depends-On: I90921679518ee95fe393f8b1bbd9134daf0ba032 Bug: T87781 Change-Id: I16691fc8ac063705ba0c2bc63b96c4534ca8660b --- diff --git a/tests/phpunit/MediaWikiUnitTestCase.php b/tests/phpunit/MediaWikiUnitTestCase.php index 1065c2f26a..3f0fc7a55d 100644 --- a/tests/phpunit/MediaWikiUnitTestCase.php +++ b/tests/phpunit/MediaWikiUnitTestCase.php @@ -31,4 +31,26 @@ abstract class MediaWikiUnitTestCase extends TestCase { use PHPUnit4And6Compat; use MediaWikiCoversValidator; + private $unitGlobals = []; + + protected function setUp() { + parent::setUp(); + $reflection = new ReflectionClass( $this ); + if ( strpos( $reflection->getFilename(), '/unit/' ) === false ) { + $this->fail( 'This unit test needs to be in "tests/phpunit/unit" !' ); + } + $this->unitGlobals = $GLOBALS; + unset( $GLOBALS ); + $GLOBALS = []; + // Add back the minimal set of globals needed for unit tests to run for core + + // extensions/skins. + foreach ( [ 'wgAutoloadClasses', 'wgAutoloadLocalClasses', 'IP' ] as $requiredGlobal ) { + $GLOBALS[$requiredGlobal] = $this->unitGlobals[ $requiredGlobal ]; + } + } + + protected function tearDown() { + $GLOBALS = $this->unitGlobals; + parent::tearDown(); + } } diff --git a/tests/phpunit/includes/MediaWikiVersionFetcherTest.php b/tests/phpunit/includes/MediaWikiVersionFetcherTest.php new file mode 100644 index 0000000000..8f0a44dc05 --- /dev/null +++ b/tests/phpunit/includes/MediaWikiVersionFetcherTest.php @@ -0,0 +1,21 @@ + + */ +class MediaWikiVersionFetcherTest extends \MediaWikiIntegrationTestCase { + + public function testReturnsResult() { + global $wgVersion; + $versionFetcher = new MediaWikiVersionFetcher(); + $this->assertSame( $wgVersion, $versionFetcher->fetchVersion() ); + } + +} diff --git a/tests/phpunit/includes/Revision/RevisionStoreFactoryTest.php b/tests/phpunit/includes/Revision/RevisionStoreFactoryTest.php new file mode 100644 index 0000000000..f4d324dde7 --- /dev/null +++ b/tests/phpunit/includes/Revision/RevisionStoreFactoryTest.php @@ -0,0 +1,193 @@ +getMockLoadBalancerFactory(), + $this->getMockBlobStoreFactory(), + $this->getNameTableStoreFactory(), + $this->getMockSlotRoleRegistry(), + $this->getHashWANObjectCache(), + $this->getMockCommentStore(), + ActorMigration::newMigration(), + MIGRATION_OLD, + $this->getMockLoggerSpi(), + true + ); + $this->assertTrue( true ); + } + + public function provideWikiIds() { + yield [ true ]; + yield [ false ]; + yield [ 'somewiki' ]; + yield [ 'somewiki', MIGRATION_OLD , false ]; + yield [ 'somewiki', MIGRATION_NEW , true ]; + } + + /** + * @dataProvider provideWikiIds + * @covers \MediaWiki\Revision\RevisionStoreFactory::getRevisionStore + */ + public function testGetRevisionStore( + $dbDomain, + $mcrMigrationStage = MIGRATION_OLD, + $contentHandlerUseDb = true + ) { + $lbFactory = $this->getMockLoadBalancerFactory(); + $blobStoreFactory = $this->getMockBlobStoreFactory(); + $nameTableStoreFactory = $this->getNameTableStoreFactory(); + $slotRoleRegistry = $this->getMockSlotRoleRegistry(); + $cache = $this->getHashWANObjectCache(); + $commentStore = $this->getMockCommentStore(); + $actorMigration = ActorMigration::newMigration(); + $loggerProvider = $this->getMockLoggerSpi(); + + $factory = new RevisionStoreFactory( + $lbFactory, + $blobStoreFactory, + $nameTableStoreFactory, + $slotRoleRegistry, + $cache, + $commentStore, + $actorMigration, + $mcrMigrationStage, + $loggerProvider, + $contentHandlerUseDb + ); + + $store = $factory->getRevisionStore( $dbDomain ); + $wrapper = TestingAccessWrapper::newFromObject( $store ); + + // ensure the correct object type is returned + $this->assertInstanceOf( RevisionStore::class, $store ); + + // ensure the RevisionStore is for the given wikiId + $this->assertSame( $dbDomain, $wrapper->dbDomain ); + + // ensure all other required services are correctly set + $this->assertSame( $cache, $wrapper->cache ); + $this->assertSame( $commentStore, $wrapper->commentStore ); + $this->assertSame( $mcrMigrationStage, $wrapper->mcrMigrationStage ); + $this->assertSame( $actorMigration, $wrapper->actorMigration ); + $this->assertSame( $contentHandlerUseDb, $store->getContentHandlerUseDB() ); + + $this->assertInstanceOf( ILoadBalancer::class, $wrapper->loadBalancer ); + $this->assertInstanceOf( BlobStore::class, $wrapper->blobStore ); + $this->assertInstanceOf( NameTableStore::class, $wrapper->contentModelStore ); + $this->assertInstanceOf( NameTableStore::class, $wrapper->slotRoleStore ); + $this->assertInstanceOf( LoggerInterface::class, $wrapper->logger ); + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject|ILoadBalancer + */ + private function getMockLoadBalancer() { + return $this->getMockBuilder( ILoadBalancer::class ) + ->disableOriginalConstructor()->getMock(); + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject|ILBFactory + */ + private function getMockLoadBalancerFactory() { + $mock = $this->getMockBuilder( ILBFactory::class ) + ->disableOriginalConstructor()->getMock(); + + $mock->method( 'getMainLB' ) + ->willReturnCallback( function () { + return $this->getMockLoadBalancer(); + } ); + + return $mock; + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject|SqlBlobStore + */ + private function getMockSqlBlobStore() { + return $this->getMockBuilder( SqlBlobStore::class ) + ->disableOriginalConstructor()->getMock(); + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject|BlobStoreFactory + */ + private function getMockBlobStoreFactory() { + $mock = $this->getMockBuilder( BlobStoreFactory::class ) + ->disableOriginalConstructor()->getMock(); + + $mock->method( 'newSqlBlobStore' ) + ->willReturnCallback( function () { + return $this->getMockSqlBlobStore(); + } ); + + return $mock; + } + + /** + * @return SlotRoleRegistry + */ + private function getMockSlotRoleRegistry() { + return $this->createMock( SlotRoleRegistry::class ); + } + + /** + * @return NameTableStoreFactory + */ + private function getNameTableStoreFactory() { + return new NameTableStoreFactory( + $this->getMockLoadBalancerFactory(), + $this->getHashWANObjectCache(), + new NullLogger() ); + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject|CommentStore + */ + private function getMockCommentStore() { + return $this->getMockBuilder( CommentStore::class ) + ->disableOriginalConstructor()->getMock(); + } + + private function getHashWANObjectCache() { + return new WANObjectCache( [ 'cache' => new \HashBagOStuff() ] ); + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject|LoggerSpi + */ + private function getMockLoggerSpi() { + $mock = $this->getMock( LoggerSpi::class ); + + $mock->method( 'getLogger' ) + ->willReturn( new NullLogger() ); + + return $mock; + } + +} diff --git a/tests/phpunit/includes/config/ConfigFactoryTest.php b/tests/phpunit/includes/config/ConfigFactoryTest.php new file mode 100644 index 0000000000..f1cc8573b2 --- /dev/null +++ b/tests/phpunit/includes/config/ConfigFactoryTest.php @@ -0,0 +1,168 @@ +register( 'unittest', 'GlobalVarConfig::newInstance' ); + $this->assertInstanceOf( GlobalVarConfig::class, $factory->makeConfig( 'unittest' ) ); + } + + /** + * @covers ConfigFactory::register + */ + public function testRegisterInvalid() { + $factory = new ConfigFactory(); + $this->setExpectedException( InvalidArgumentException::class ); + $factory->register( 'invalid', 'Invalid callback' ); + } + + /** + * @covers ConfigFactory::register + */ + public function testRegisterInvalidInstance() { + $factory = new ConfigFactory(); + $this->setExpectedException( InvalidArgumentException::class ); + $factory->register( 'invalidInstance', new stdClass ); + } + + /** + * @covers ConfigFactory::register + */ + public function testRegisterInstance() { + $config = GlobalVarConfig::newInstance(); + $factory = new ConfigFactory(); + $factory->register( 'unittest', $config ); + $this->assertSame( $config, $factory->makeConfig( 'unittest' ) ); + } + + /** + * @covers ConfigFactory::register + */ + public function testRegisterAgain() { + $factory = new ConfigFactory(); + $factory->register( 'unittest', 'GlobalVarConfig::newInstance' ); + $config1 = $factory->makeConfig( 'unittest' ); + + $factory->register( 'unittest', 'GlobalVarConfig::newInstance' ); + $config2 = $factory->makeConfig( 'unittest' ); + + $this->assertNotSame( $config1, $config2 ); + } + + /** + * @covers ConfigFactory::salvage + */ + public function testSalvage() { + $oldFactory = new ConfigFactory(); + $oldFactory->register( 'foo', 'GlobalVarConfig::newInstance' ); + $oldFactory->register( 'bar', 'GlobalVarConfig::newInstance' ); + $oldFactory->register( 'quux', 'GlobalVarConfig::newInstance' ); + + // instantiate two of the three defined configurations + $foo = $oldFactory->makeConfig( 'foo' ); + $bar = $oldFactory->makeConfig( 'bar' ); + $quux = $oldFactory->makeConfig( 'quux' ); + + // define new config instance + $newFactory = new ConfigFactory(); + $newFactory->register( 'foo', 'GlobalVarConfig::newInstance' ); + $newFactory->register( 'bar', function () { + return new HashConfig(); + } ); + + // "foo" and "quux" are defined in the old and the new factory. + // The old factory has instances for "foo" and "bar", but not "quux". + $newFactory->salvage( $oldFactory ); + + $newFoo = $newFactory->makeConfig( 'foo' ); + $this->assertSame( $foo, $newFoo, 'existing instance should be salvaged' ); + + $newBar = $newFactory->makeConfig( 'bar' ); + $this->assertNotSame( $bar, $newBar, 'don\'t salvage if callbacks differ' ); + + // the new factory doesn't have quux defined, so the quux instance should not be salvaged + $this->setExpectedException( ConfigException::class ); + $newFactory->makeConfig( 'quux' ); + } + + /** + * @covers ConfigFactory::getConfigNames + */ + public function testGetConfigNames() { + $factory = new ConfigFactory(); + $factory->register( 'foo', 'GlobalVarConfig::newInstance' ); + $factory->register( 'bar', new HashConfig() ); + + $this->assertEquals( [ 'foo', 'bar' ], $factory->getConfigNames() ); + } + + /** + * @covers ConfigFactory::makeConfig + */ + public function testMakeConfigWithCallback() { + $factory = new ConfigFactory(); + $factory->register( 'unittest', 'GlobalVarConfig::newInstance' ); + + $conf = $factory->makeConfig( 'unittest' ); + $this->assertInstanceOf( Config::class, $conf ); + $this->assertSame( $conf, $factory->makeConfig( 'unittest' ) ); + } + + /** + * @covers ConfigFactory::makeConfig + */ + public function testMakeConfigWithObject() { + $factory = new ConfigFactory(); + $conf = new HashConfig(); + $factory->register( 'test', $conf ); + $this->assertSame( $conf, $factory->makeConfig( 'test' ) ); + } + + /** + * @covers ConfigFactory::makeConfig + */ + public function testMakeConfigFallback() { + $factory = new ConfigFactory(); + $factory->register( '*', 'GlobalVarConfig::newInstance' ); + $conf = $factory->makeConfig( 'unittest' ); + $this->assertInstanceOf( Config::class, $conf ); + } + + /** + * @covers ConfigFactory::makeConfig + */ + public function testMakeConfigWithNoBuilders() { + $factory = new ConfigFactory(); + $this->setExpectedException( ConfigException::class ); + $factory->makeConfig( 'nobuilderregistered' ); + } + + /** + * @covers ConfigFactory::makeConfig + */ + public function testMakeConfigWithInvalidCallback() { + $factory = new ConfigFactory(); + $factory->register( 'unittest', function () { + return true; // Not a Config object + } ); + $this->setExpectedException( UnexpectedValueException::class ); + $factory->makeConfig( 'unittest' ); + } + + /** + * @covers ConfigFactory::getDefaultInstance + */ + public function testGetDefaultInstance() { + // NOTE: the global config factory returned here has been overwritten + // for operation in test mode. It may not reflect LocalSettings. + $factory = MediaWikiServices::getInstance()->getConfigFactory(); + $this->assertInstanceOf( Config::class, $factory->makeConfig( 'main' ) ); + } + +} diff --git a/tests/phpunit/includes/media/SVGMetadataExtractorTest.php b/tests/phpunit/includes/media/SVGMetadataExtractorTest.php new file mode 100644 index 0000000000..c84efa1640 --- /dev/null +++ b/tests/phpunit/includes/media/SVGMetadataExtractorTest.php @@ -0,0 +1,201 @@ +assertMetadata( $infile, $expected ); + } + + /** + * @dataProvider provideSvgFilesWithXMLMetadata + */ + public function testGetXMLMetadata( $infile, $expected ) { + $r = new XMLReader(); + $this->assertMetadata( $infile, $expected ); + } + + /** + * @dataProvider provideSvgUnits + */ + public function testScaleSVGUnit( $inUnit, $expected ) { + $this->assertEquals( + $expected, + SVGReader::scaleSVGUnit( $inUnit ), + 'SVG unit conversion and scaling failure' + ); + } + + function assertMetadata( $infile, $expected ) { + try { + $data = SVGMetadataExtractor::getMetadata( $infile ); + $this->assertEquals( $expected, $data, 'SVG metadata extraction test' ); + } catch ( MWException $e ) { + if ( $expected === false ) { + $this->assertTrue( true, 'SVG metadata extracted test (expected failure)' ); + } else { + throw $e; + } + } + } + + public static function provideSvgFiles() { + $base = __DIR__ . '/../../data/media'; + + return [ + [ + "$base/Wikimedia-logo.svg", + [ + 'width' => 1024, + 'height' => 1024, + 'originalWidth' => '1024', + 'originalHeight' => '1024', + 'translations' => [], + ] + ], + [ + "$base/QA_icon.svg", + [ + 'width' => 60, + 'height' => 60, + 'originalWidth' => '60', + 'originalHeight' => '60', + 'translations' => [], + ] + ], + [ + "$base/Gtk-media-play-ltr.svg", + [ + 'width' => 60, + 'height' => 60, + 'originalWidth' => '60.0000000', + 'originalHeight' => '60.0000000', + 'translations' => [], + ] + ], + [ + "$base/Toll_Texas_1.svg", + // This file triggered T33719, needs entity expansion in the xmlns checks + [ + 'width' => 385, + 'height' => 385, + 'originalWidth' => '385', + 'originalHeight' => '385.0004883', + 'translations' => [], + ] + ], + [ + "$base/Tux.svg", + [ + 'width' => 512, + 'height' => 594, + 'originalWidth' => '100%', + 'originalHeight' => '100%', + 'title' => 'Tux', + 'translations' => [], + 'description' => 'For more information see: http://commons.wikimedia.org/wiki/Image:Tux.svg', + ] + ], + [ + "$base/Speech_bubbles.svg", + [ + 'width' => 627, + 'height' => 461, + 'originalWidth' => '17.7cm', + 'originalHeight' => '13cm', + 'translations' => [ + 'de' => SVGReader::LANG_FULL_MATCH, + 'fr' => SVGReader::LANG_FULL_MATCH, + 'nl' => SVGReader::LANG_FULL_MATCH, + 'tlh-ca' => SVGReader::LANG_FULL_MATCH, + 'tlh' => SVGReader::LANG_PREFIX_MATCH + ], + ] + ], + [ + "$base/Soccer_ball_animated.svg", + [ + 'width' => 150, + 'height' => 150, + 'originalWidth' => '150', + 'originalHeight' => '150', + 'animated' => true, + 'translations' => [] + ], + ], + [ + "$base/comma_separated_viewbox.svg", + [ + 'width' => 512, + 'height' => 594, + 'originalWidth' => '100%', + 'originalHeight' => '100%', + 'translations' => [] + ], + ], + ]; + } + + public static function provideSvgFilesWithXMLMetadata() { + $base = __DIR__ . '/../../data/media'; + // phpcs:disable Generic.Files.LineLength + $metadata = ' + + image/svg+xml + + + '; + // phpcs:enable + + $metadata = str_replace( "\r", '', $metadata ); // Windows compat + return [ + [ + "$base/US_states_by_total_state_tax_revenue.svg", + [ + 'height' => 593, + 'metadata' => $metadata, + 'width' => 959, + 'originalWidth' => '958.69', + 'originalHeight' => '592.78998', + 'translations' => [], + ] + ], + ]; + } + + public static function provideSvgUnits() { + return [ + [ '1' , 1 ], + [ '1.1' , 1.1 ], + [ '0.1' , 0.1 ], + [ '.1' , 0.1 ], + [ '1e2' , 100 ], + [ '1E2' , 100 ], + [ '+1' , 1 ], + [ '-1' , -1 ], + [ '-1.1' , -1.1 ], + [ '1e+2' , 100 ], + [ '1e-2' , 0.01 ], + [ '10px' , 10 ], + [ '10pt' , 10 * 1.25 ], + [ '10pc' , 10 * 15 ], + [ '10mm' , 10 * 3.543307 ], + [ '10cm' , 10 * 35.43307 ], + [ '10in' , 10 * 90 ], + [ '10em' , 10 * 16 ], + [ '10ex' , 10 * 12 ], + [ '10%' , 51.2 ], + [ '10 px' , 10 ], + // Invalid values + [ '1e1.1', 10 ], + [ '10bp', 10 ], + [ 'p10', null ], + ]; + } +} diff --git a/tests/phpunit/includes/parser/SanitizerTest.php b/tests/phpunit/includes/parser/SanitizerTest.php index e665d672f8..99e8fb7ebd 100644 --- a/tests/phpunit/includes/parser/SanitizerTest.php +++ b/tests/phpunit/includes/parser/SanitizerTest.php @@ -271,4 +271,29 @@ class SanitizerTest extends MediaWikiTestCase { $this->setMwGlobals( 'wgFragmentMode', [ 666 => 'html5' ] ); Sanitizer::escapeIdForLink( 'This should throw' ); } + + /** + * Test escapeIdReferenceList for consistency with escapeIdForAttribute + * + * @dataProvider provideEscapeIdReferenceList + * @covers Sanitizer::escapeIdReferenceList + */ + public function testEscapeIdReferenceList( $referenceList, $id1, $id2 ) { + $this->assertEquals( + Sanitizer::escapeIdReferenceList( $referenceList ), + Sanitizer::escapeIdForAttribute( $id1 ) + . ' ' + . Sanitizer::escapeIdForAttribute( $id2 ) + ); + } + + public static function provideEscapeIdReferenceList() { + /** [ , , ] */ + return [ + [ 'foo bar', 'foo', 'bar' ], + [ '#1 #2', '#1', '#2' ], + [ '+1 +2', '+1', '+2' ], + ]; + } + } diff --git a/tests/phpunit/includes/site/CachingSiteStoreTest.php b/tests/phpunit/includes/site/CachingSiteStoreTest.php new file mode 100644 index 0000000000..df12eba765 --- /dev/null +++ b/tests/phpunit/includes/site/CachingSiteStoreTest.php @@ -0,0 +1,167 @@ + + */ +class CachingSiteStoreTest extends \MediaWikiIntegrationTestCase { + + /** + * @covers CachingSiteStore::getSites + */ + public function testGetSites() { + $testSites = TestSites::getSites(); + + $store = new CachingSiteStore( + $this->getHashSiteStore( $testSites ), + ObjectCache::getLocalClusterInstance() + ); + + $sites = $store->getSites(); + + $this->assertInstanceOf( SiteList::class, $sites ); + + /** + * @var Site $site + */ + foreach ( $sites as $site ) { + $this->assertInstanceOf( Site::class, $site ); + } + + foreach ( $testSites as $site ) { + if ( $site->getGlobalId() !== null ) { + $this->assertTrue( $sites->hasSite( $site->getGlobalId() ) ); + } + } + } + + /** + * @covers CachingSiteStore::saveSites + */ + public function testSaveSites() { + $store = new CachingSiteStore( + new HashSiteStore(), ObjectCache::getLocalClusterInstance() + ); + + $sites = []; + + $site = new Site(); + $site->setGlobalId( 'ertrywuutr' ); + $site->setLanguageCode( 'en' ); + $sites[] = $site; + + $site = new MediaWikiSite(); + $site->setGlobalId( 'sdfhxujgkfpth' ); + $site->setLanguageCode( 'nl' ); + $sites[] = $site; + + $this->assertTrue( $store->saveSites( $sites ) ); + + $site = $store->getSite( 'ertrywuutr' ); + $this->assertInstanceOf( Site::class, $site ); + $this->assertEquals( 'en', $site->getLanguageCode() ); + + $site = $store->getSite( 'sdfhxujgkfpth' ); + $this->assertInstanceOf( Site::class, $site ); + $this->assertEquals( 'nl', $site->getLanguageCode() ); + } + + /** + * @covers CachingSiteStore::reset + */ + public function testReset() { + $dbSiteStore = $this->getMockBuilder( SiteStore::class ) + ->disableOriginalConstructor() + ->getMock(); + + $dbSiteStore->expects( $this->any() ) + ->method( 'getSite' ) + ->will( $this->returnValue( $this->getTestSite() ) ); + + $dbSiteStore->expects( $this->any() ) + ->method( 'getSites' ) + ->will( $this->returnCallback( function () { + $siteList = new SiteList(); + $siteList->setSite( $this->getTestSite() ); + + return $siteList; + } ) ); + + $store = new CachingSiteStore( $dbSiteStore, ObjectCache::getLocalClusterInstance() ); + + // initialize internal cache + $this->assertGreaterThan( 0, $store->getSites()->count(), 'count sites' ); + + $store->getSite( 'enwiki' )->setLanguageCode( 'en-ca' ); + + // sanity check: $store should have the new language code for 'enwiki' + $this->assertEquals( 'en-ca', $store->getSite( 'enwiki' )->getLanguageCode(), 'sanity check' ); + + // purge cache + $store->reset(); + + // the internal cache of $store should be updated, and now pulling + // the site from the 'fallback' DBSiteStore with the original language code. + $this->assertEquals( 'en', $store->getSite( 'enwiki' )->getLanguageCode(), 'reset' ); + } + + public function getTestSite() { + $enwiki = new MediaWikiSite(); + $enwiki->setGlobalId( 'enwiki' ); + $enwiki->setLanguageCode( 'en' ); + + return $enwiki; + } + + /** + * @covers CachingSiteStore::clear + */ + public function testClear() { + $store = new CachingSiteStore( + new HashSiteStore(), ObjectCache::getLocalClusterInstance() + ); + $this->assertTrue( $store->clear() ); + + $site = $store->getSite( 'enwiki' ); + $this->assertNull( $site ); + + $sites = $store->getSites(); + $this->assertEquals( 0, $sites->count() ); + } + + /** + * @param Site[] $sites + * + * @return SiteStore + */ + private function getHashSiteStore( array $sites ) { + $siteStore = new HashSiteStore(); + $siteStore->saveSites( $sites ); + + return $siteStore; + } + +} diff --git a/tests/phpunit/includes/site/HashSiteStoreTest.php b/tests/phpunit/includes/site/HashSiteStoreTest.php new file mode 100644 index 0000000000..3912504038 --- /dev/null +++ b/tests/phpunit/includes/site/HashSiteStoreTest.php @@ -0,0 +1,105 @@ + + */ +class HashSiteStoreTest extends \MediaWikiIntegrationTestCase { + + /** + * @covers HashSiteStore::getSites + */ + public function testGetSites() { + $expectedSites = []; + + foreach ( TestSites::getSites() as $testSite ) { + $siteId = $testSite->getGlobalId(); + $expectedSites[$siteId] = $testSite; + } + + $siteStore = new HashSiteStore( $expectedSites ); + + $this->assertEquals( new SiteList( $expectedSites ), $siteStore->getSites() ); + } + + /** + * @covers HashSiteStore::saveSite + * @covers HashSiteStore::getSite + */ + public function testSaveSite() { + $store = new HashSiteStore(); + + $site = new Site(); + $site->setGlobalId( 'dewiki' ); + + $this->assertCount( 0, $store->getSites(), '0 sites in store' ); + + $store->saveSite( $site ); + + $this->assertCount( 1, $store->getSites(), 'Store has 1 sites' ); + $this->assertEquals( $site, $store->getSite( 'dewiki' ), 'Store has dewiki' ); + } + + /** + * @covers HashSiteStore::saveSites + */ + public function testSaveSites() { + $store = new HashSiteStore(); + + $sites = []; + + $site = new Site(); + $site->setGlobalId( 'enwiki' ); + $site->setLanguageCode( 'en' ); + $sites[] = $site; + + $site = new MediaWikiSite(); + $site->setGlobalId( 'eswiki' ); + $site->setLanguageCode( 'es' ); + $sites[] = $site; + + $this->assertCount( 0, $store->getSites(), '0 sites in store' ); + + $store->saveSites( $sites ); + + $this->assertCount( 2, $store->getSites(), 'Store has 2 sites' ); + $this->assertTrue( $store->getSites()->hasSite( 'enwiki' ), 'Store has enwiki' ); + $this->assertTrue( $store->getSites()->hasSite( 'eswiki' ), 'Store has eswiki' ); + } + + /** + * @covers HashSiteStore::clear + */ + public function testClear() { + $store = new HashSiteStore(); + + $site = new Site(); + $site->setGlobalId( 'arwiki' ); + $store->saveSite( $site ); + + $this->assertCount( 1, $store->getSites(), '1 site in store' ); + + $store->clear(); + $this->assertCount( 0, $store->getSites(), '0 sites in store' ); + } +} diff --git a/tests/phpunit/languages/SpecialPageAliasTest.php b/tests/phpunit/languages/SpecialPageAliasTest.php deleted file mode 100644 index cce9d0eb0f..0000000000 --- a/tests/phpunit/languages/SpecialPageAliasTest.php +++ /dev/null @@ -1,64 +0,0 @@ - - */ -class SpecialPageAliasTest extends \MediaWikiUnitTestCase { - - /** - * @coversNothing - * @dataProvider validSpecialPageAliasesProvider - */ - public function testValidSpecialPageAliases( $code, $specialPageAliases ) { - foreach ( $specialPageAliases as $specialPage => $aliases ) { - foreach ( $aliases as $alias ) { - $msg = "$specialPage alias '$alias' in $code is valid with no slashes"; - $this->assertRegExp( '/^[^\/]*$/', $msg ); - } - } - } - - public function validSpecialPageAliasesProvider() { - $codes = array_keys( Language::fetchLanguageNames( null, 'mwfile' ) ); - - $data = []; - - foreach ( $codes as $code ) { - $specialPageAliases = $this->getSpecialPageAliases( $code ); - - if ( $specialPageAliases !== [] ) { - $data[] = [ $code, $specialPageAliases ]; - } - } - - return $data; - } - - /** - * @param string $code - * - * @return array - */ - protected function getSpecialPageAliases( $code ) { - $file = Language::getMessagesFileName( $code ); - - if ( is_readable( $file ) ) { - include $file; - - if ( isset( $specialPageAliases ) && $specialPageAliases !== null ) { - return $specialPageAliases; - } - } - - return []; - } - -} diff --git a/tests/phpunit/unit/includes/MediaWikiVersionFetcherTest.php b/tests/phpunit/unit/includes/MediaWikiVersionFetcherTest.php deleted file mode 100644 index dfdbfa7344..0000000000 --- a/tests/phpunit/unit/includes/MediaWikiVersionFetcherTest.php +++ /dev/null @@ -1,21 +0,0 @@ - - */ -class MediaWikiVersionFetcherTest extends \MediaWikiUnitTestCase { - - public function testReturnsResult() { - global $wgVersion; - $versionFetcher = new MediaWikiVersionFetcher(); - $this->assertSame( $wgVersion, $versionFetcher->fetchVersion() ); - } - -} diff --git a/tests/phpunit/unit/includes/Revision/RevisionStoreFactoryTest.php b/tests/phpunit/unit/includes/Revision/RevisionStoreFactoryTest.php deleted file mode 100644 index 8e8fbd760f..0000000000 --- a/tests/phpunit/unit/includes/Revision/RevisionStoreFactoryTest.php +++ /dev/null @@ -1,193 +0,0 @@ -getMockLoadBalancerFactory(), - $this->getMockBlobStoreFactory(), - $this->getNameTableStoreFactory(), - $this->getMockSlotRoleRegistry(), - $this->getHashWANObjectCache(), - $this->getMockCommentStore(), - ActorMigration::newMigration(), - MIGRATION_OLD, - $this->getMockLoggerSpi(), - true - ); - $this->assertTrue( true ); - } - - public function provideWikiIds() { - yield [ true ]; - yield [ false ]; - yield [ 'somewiki' ]; - yield [ 'somewiki', MIGRATION_OLD , false ]; - yield [ 'somewiki', MIGRATION_NEW , true ]; - } - - /** - * @dataProvider provideWikiIds - * @covers \MediaWiki\Revision\RevisionStoreFactory::getRevisionStore - */ - public function testGetRevisionStore( - $dbDomain, - $mcrMigrationStage = MIGRATION_OLD, - $contentHandlerUseDb = true - ) { - $lbFactory = $this->getMockLoadBalancerFactory(); - $blobStoreFactory = $this->getMockBlobStoreFactory(); - $nameTableStoreFactory = $this->getNameTableStoreFactory(); - $slotRoleRegistry = $this->getMockSlotRoleRegistry(); - $cache = $this->getHashWANObjectCache(); - $commentStore = $this->getMockCommentStore(); - $actorMigration = ActorMigration::newMigration(); - $loggerProvider = $this->getMockLoggerSpi(); - - $factory = new RevisionStoreFactory( - $lbFactory, - $blobStoreFactory, - $nameTableStoreFactory, - $slotRoleRegistry, - $cache, - $commentStore, - $actorMigration, - $mcrMigrationStage, - $loggerProvider, - $contentHandlerUseDb - ); - - $store = $factory->getRevisionStore( $dbDomain ); - $wrapper = TestingAccessWrapper::newFromObject( $store ); - - // ensure the correct object type is returned - $this->assertInstanceOf( RevisionStore::class, $store ); - - // ensure the RevisionStore is for the given wikiId - $this->assertSame( $dbDomain, $wrapper->dbDomain ); - - // ensure all other required services are correctly set - $this->assertSame( $cache, $wrapper->cache ); - $this->assertSame( $commentStore, $wrapper->commentStore ); - $this->assertSame( $mcrMigrationStage, $wrapper->mcrMigrationStage ); - $this->assertSame( $actorMigration, $wrapper->actorMigration ); - $this->assertSame( $contentHandlerUseDb, $store->getContentHandlerUseDB() ); - - $this->assertInstanceOf( ILoadBalancer::class, $wrapper->loadBalancer ); - $this->assertInstanceOf( BlobStore::class, $wrapper->blobStore ); - $this->assertInstanceOf( NameTableStore::class, $wrapper->contentModelStore ); - $this->assertInstanceOf( NameTableStore::class, $wrapper->slotRoleStore ); - $this->assertInstanceOf( LoggerInterface::class, $wrapper->logger ); - } - - /** - * @return \PHPUnit_Framework_MockObject_MockObject|ILoadBalancer - */ - private function getMockLoadBalancer() { - return $this->getMockBuilder( ILoadBalancer::class ) - ->disableOriginalConstructor()->getMock(); - } - - /** - * @return \PHPUnit_Framework_MockObject_MockObject|ILBFactory - */ - private function getMockLoadBalancerFactory() { - $mock = $this->getMockBuilder( ILBFactory::class ) - ->disableOriginalConstructor()->getMock(); - - $mock->method( 'getMainLB' ) - ->willReturnCallback( function () { - return $this->getMockLoadBalancer(); - } ); - - return $mock; - } - - /** - * @return \PHPUnit_Framework_MockObject_MockObject|SqlBlobStore - */ - private function getMockSqlBlobStore() { - return $this->getMockBuilder( SqlBlobStore::class ) - ->disableOriginalConstructor()->getMock(); - } - - /** - * @return \PHPUnit_Framework_MockObject_MockObject|BlobStoreFactory - */ - private function getMockBlobStoreFactory() { - $mock = $this->getMockBuilder( BlobStoreFactory::class ) - ->disableOriginalConstructor()->getMock(); - - $mock->method( 'newSqlBlobStore' ) - ->willReturnCallback( function () { - return $this->getMockSqlBlobStore(); - } ); - - return $mock; - } - - /** - * @return SlotRoleRegistry - */ - private function getMockSlotRoleRegistry() { - return $this->createMock( SlotRoleRegistry::class ); - } - - /** - * @return NameTableStoreFactory - */ - private function getNameTableStoreFactory() { - return new NameTableStoreFactory( - $this->getMockLoadBalancerFactory(), - $this->getHashWANObjectCache(), - new NullLogger() ); - } - - /** - * @return \PHPUnit_Framework_MockObject_MockObject|CommentStore - */ - private function getMockCommentStore() { - return $this->getMockBuilder( CommentStore::class ) - ->disableOriginalConstructor()->getMock(); - } - - private function getHashWANObjectCache() { - return new WANObjectCache( [ 'cache' => new \HashBagOStuff() ] ); - } - - /** - * @return \PHPUnit_Framework_MockObject_MockObject|LoggerSpi - */ - private function getMockLoggerSpi() { - $mock = $this->getMock( LoggerSpi::class ); - - $mock->method( 'getLogger' ) - ->willReturn( new NullLogger() ); - - return $mock; - } - -} diff --git a/tests/phpunit/unit/includes/config/ConfigFactoryTest.php b/tests/phpunit/unit/includes/config/ConfigFactoryTest.php deleted file mode 100644 index a136018c96..0000000000 --- a/tests/phpunit/unit/includes/config/ConfigFactoryTest.php +++ /dev/null @@ -1,168 +0,0 @@ -register( 'unittest', 'GlobalVarConfig::newInstance' ); - $this->assertInstanceOf( GlobalVarConfig::class, $factory->makeConfig( 'unittest' ) ); - } - - /** - * @covers ConfigFactory::register - */ - public function testRegisterInvalid() { - $factory = new ConfigFactory(); - $this->setExpectedException( InvalidArgumentException::class ); - $factory->register( 'invalid', 'Invalid callback' ); - } - - /** - * @covers ConfigFactory::register - */ - public function testRegisterInvalidInstance() { - $factory = new ConfigFactory(); - $this->setExpectedException( InvalidArgumentException::class ); - $factory->register( 'invalidInstance', new stdClass ); - } - - /** - * @covers ConfigFactory::register - */ - public function testRegisterInstance() { - $config = GlobalVarConfig::newInstance(); - $factory = new ConfigFactory(); - $factory->register( 'unittest', $config ); - $this->assertSame( $config, $factory->makeConfig( 'unittest' ) ); - } - - /** - * @covers ConfigFactory::register - */ - public function testRegisterAgain() { - $factory = new ConfigFactory(); - $factory->register( 'unittest', 'GlobalVarConfig::newInstance' ); - $config1 = $factory->makeConfig( 'unittest' ); - - $factory->register( 'unittest', 'GlobalVarConfig::newInstance' ); - $config2 = $factory->makeConfig( 'unittest' ); - - $this->assertNotSame( $config1, $config2 ); - } - - /** - * @covers ConfigFactory::salvage - */ - public function testSalvage() { - $oldFactory = new ConfigFactory(); - $oldFactory->register( 'foo', 'GlobalVarConfig::newInstance' ); - $oldFactory->register( 'bar', 'GlobalVarConfig::newInstance' ); - $oldFactory->register( 'quux', 'GlobalVarConfig::newInstance' ); - - // instantiate two of the three defined configurations - $foo = $oldFactory->makeConfig( 'foo' ); - $bar = $oldFactory->makeConfig( 'bar' ); - $quux = $oldFactory->makeConfig( 'quux' ); - - // define new config instance - $newFactory = new ConfigFactory(); - $newFactory->register( 'foo', 'GlobalVarConfig::newInstance' ); - $newFactory->register( 'bar', function () { - return new HashConfig(); - } ); - - // "foo" and "quux" are defined in the old and the new factory. - // The old factory has instances for "foo" and "bar", but not "quux". - $newFactory->salvage( $oldFactory ); - - $newFoo = $newFactory->makeConfig( 'foo' ); - $this->assertSame( $foo, $newFoo, 'existing instance should be salvaged' ); - - $newBar = $newFactory->makeConfig( 'bar' ); - $this->assertNotSame( $bar, $newBar, 'don\'t salvage if callbacks differ' ); - - // the new factory doesn't have quux defined, so the quux instance should not be salvaged - $this->setExpectedException( ConfigException::class ); - $newFactory->makeConfig( 'quux' ); - } - - /** - * @covers ConfigFactory::getConfigNames - */ - public function testGetConfigNames() { - $factory = new ConfigFactory(); - $factory->register( 'foo', 'GlobalVarConfig::newInstance' ); - $factory->register( 'bar', new HashConfig() ); - - $this->assertEquals( [ 'foo', 'bar' ], $factory->getConfigNames() ); - } - - /** - * @covers ConfigFactory::makeConfig - */ - public function testMakeConfigWithCallback() { - $factory = new ConfigFactory(); - $factory->register( 'unittest', 'GlobalVarConfig::newInstance' ); - - $conf = $factory->makeConfig( 'unittest' ); - $this->assertInstanceOf( Config::class, $conf ); - $this->assertSame( $conf, $factory->makeConfig( 'unittest' ) ); - } - - /** - * @covers ConfigFactory::makeConfig - */ - public function testMakeConfigWithObject() { - $factory = new ConfigFactory(); - $conf = new HashConfig(); - $factory->register( 'test', $conf ); - $this->assertSame( $conf, $factory->makeConfig( 'test' ) ); - } - - /** - * @covers ConfigFactory::makeConfig - */ - public function testMakeConfigFallback() { - $factory = new ConfigFactory(); - $factory->register( '*', 'GlobalVarConfig::newInstance' ); - $conf = $factory->makeConfig( 'unittest' ); - $this->assertInstanceOf( Config::class, $conf ); - } - - /** - * @covers ConfigFactory::makeConfig - */ - public function testMakeConfigWithNoBuilders() { - $factory = new ConfigFactory(); - $this->setExpectedException( ConfigException::class ); - $factory->makeConfig( 'nobuilderregistered' ); - } - - /** - * @covers ConfigFactory::makeConfig - */ - public function testMakeConfigWithInvalidCallback() { - $factory = new ConfigFactory(); - $factory->register( 'unittest', function () { - return true; // Not a Config object - } ); - $this->setExpectedException( UnexpectedValueException::class ); - $factory->makeConfig( 'unittest' ); - } - - /** - * @covers ConfigFactory::getDefaultInstance - */ - public function testGetDefaultInstance() { - // NOTE: the global config factory returned here has been overwritten - // for operation in test mode. It may not reflect LocalSettings. - $factory = MediaWikiServices::getInstance()->getConfigFactory(); - $this->assertInstanceOf( Config::class, $factory->makeConfig( 'main' ) ); - } - -} diff --git a/tests/phpunit/unit/includes/media/SVGMetadataExtractorTest.php b/tests/phpunit/unit/includes/media/SVGMetadataExtractorTest.php deleted file mode 100644 index 30d10083f4..0000000000 --- a/tests/phpunit/unit/includes/media/SVGMetadataExtractorTest.php +++ /dev/null @@ -1,201 +0,0 @@ -assertMetadata( $infile, $expected ); - } - - /** - * @dataProvider provideSvgFilesWithXMLMetadata - */ - public function testGetXMLMetadata( $infile, $expected ) { - $r = new XMLReader(); - $this->assertMetadata( $infile, $expected ); - } - - /** - * @dataProvider provideSvgUnits - */ - public function testScaleSVGUnit( $inUnit, $expected ) { - $this->assertEquals( - $expected, - SVGReader::scaleSVGUnit( $inUnit ), - 'SVG unit conversion and scaling failure' - ); - } - - function assertMetadata( $infile, $expected ) { - try { - $data = SVGMetadataExtractor::getMetadata( $infile ); - $this->assertEquals( $expected, $data, 'SVG metadata extraction test' ); - } catch ( MWException $e ) { - if ( $expected === false ) { - $this->assertTrue( true, 'SVG metadata extracted test (expected failure)' ); - } else { - throw $e; - } - } - } - - public static function provideSvgFiles() { - $base = __DIR__ . '/../../../data/media'; - - return [ - [ - "$base/Wikimedia-logo.svg", - [ - 'width' => 1024, - 'height' => 1024, - 'originalWidth' => '1024', - 'originalHeight' => '1024', - 'translations' => [], - ] - ], - [ - "$base/QA_icon.svg", - [ - 'width' => 60, - 'height' => 60, - 'originalWidth' => '60', - 'originalHeight' => '60', - 'translations' => [], - ] - ], - [ - "$base/Gtk-media-play-ltr.svg", - [ - 'width' => 60, - 'height' => 60, - 'originalWidth' => '60.0000000', - 'originalHeight' => '60.0000000', - 'translations' => [], - ] - ], - [ - "$base/Toll_Texas_1.svg", - // This file triggered T33719, needs entity expansion in the xmlns checks - [ - 'width' => 385, - 'height' => 385, - 'originalWidth' => '385', - 'originalHeight' => '385.0004883', - 'translations' => [], - ] - ], - [ - "$base/Tux.svg", - [ - 'width' => 512, - 'height' => 594, - 'originalWidth' => '100%', - 'originalHeight' => '100%', - 'title' => 'Tux', - 'translations' => [], - 'description' => 'For more information see: http://commons.wikimedia.org/wiki/Image:Tux.svg', - ] - ], - [ - "$base/Speech_bubbles.svg", - [ - 'width' => 627, - 'height' => 461, - 'originalWidth' => '17.7cm', - 'originalHeight' => '13cm', - 'translations' => [ - 'de' => SVGReader::LANG_FULL_MATCH, - 'fr' => SVGReader::LANG_FULL_MATCH, - 'nl' => SVGReader::LANG_FULL_MATCH, - 'tlh-ca' => SVGReader::LANG_FULL_MATCH, - 'tlh' => SVGReader::LANG_PREFIX_MATCH - ], - ] - ], - [ - "$base/Soccer_ball_animated.svg", - [ - 'width' => 150, - 'height' => 150, - 'originalWidth' => '150', - 'originalHeight' => '150', - 'animated' => true, - 'translations' => [] - ], - ], - [ - "$base/comma_separated_viewbox.svg", - [ - 'width' => 512, - 'height' => 594, - 'originalWidth' => '100%', - 'originalHeight' => '100%', - 'translations' => [] - ], - ], - ]; - } - - public static function provideSvgFilesWithXMLMetadata() { - $base = __DIR__ . '/../../../data/media'; - // phpcs:disable Generic.Files.LineLength - $metadata = ' - - image/svg+xml - - - '; - // phpcs:enable - - $metadata = str_replace( "\r", '', $metadata ); // Windows compat - return [ - [ - "$base/US_states_by_total_state_tax_revenue.svg", - [ - 'height' => 593, - 'metadata' => $metadata, - 'width' => 959, - 'originalWidth' => '958.69', - 'originalHeight' => '592.78998', - 'translations' => [], - ] - ], - ]; - } - - public static function provideSvgUnits() { - return [ - [ '1' , 1 ], - [ '1.1' , 1.1 ], - [ '0.1' , 0.1 ], - [ '.1' , 0.1 ], - [ '1e2' , 100 ], - [ '1E2' , 100 ], - [ '+1' , 1 ], - [ '-1' , -1 ], - [ '-1.1' , -1.1 ], - [ '1e+2' , 100 ], - [ '1e-2' , 0.01 ], - [ '10px' , 10 ], - [ '10pt' , 10 * 1.25 ], - [ '10pc' , 10 * 15 ], - [ '10mm' , 10 * 3.543307 ], - [ '10cm' , 10 * 35.43307 ], - [ '10in' , 10 * 90 ], - [ '10em' , 10 * 16 ], - [ '10ex' , 10 * 12 ], - [ '10%' , 51.2 ], - [ '10 px' , 10 ], - // Invalid values - [ '1e1.1', 10 ], - [ '10bp', 10 ], - [ 'p10', null ], - ]; - } -} diff --git a/tests/phpunit/unit/includes/parser/SanitizerUnitTest.php b/tests/phpunit/unit/includes/parser/SanitizerUnitTest.php index 71e4fffb4d..0436e19205 100644 --- a/tests/phpunit/unit/includes/parser/SanitizerUnitTest.php +++ b/tests/phpunit/unit/includes/parser/SanitizerUnitTest.php @@ -274,30 +274,6 @@ class SanitizerUnitTest extends MediaWikiUnitTestCase { ]; } - /** - * Test escapeIdReferenceList for consistency with escapeIdForAttribute - * - * @dataProvider provideEscapeIdReferenceList - * @covers Sanitizer::escapeIdReferenceList - */ - public function testEscapeIdReferenceList( $referenceList, $id1, $id2 ) { - $this->assertEquals( - Sanitizer::escapeIdReferenceList( $referenceList ), - Sanitizer::escapeIdForAttribute( $id1 ) - . ' ' - . Sanitizer::escapeIdForAttribute( $id2 ) - ); - } - - public static function provideEscapeIdReferenceList() { - /** [ , , ] */ - return [ - [ 'foo bar', 'foo', 'bar' ], - [ '#1 #2', '#1', '#2' ], - [ '+1 +2', '+1', '+2' ], - ]; - } - /** * @dataProvider provideIsReservedDataAttribute * @covers Sanitizer::isReservedDataAttribute diff --git a/tests/phpunit/unit/includes/site/CachingSiteStoreTest.php b/tests/phpunit/unit/includes/site/CachingSiteStoreTest.php deleted file mode 100644 index 92ed1f53e8..0000000000 --- a/tests/phpunit/unit/includes/site/CachingSiteStoreTest.php +++ /dev/null @@ -1,167 +0,0 @@ - - */ -class CachingSiteStoreTest extends \MediaWikiUnitTestCase { - - /** - * @covers CachingSiteStore::getSites - */ - public function testGetSites() { - $testSites = TestSites::getSites(); - - $store = new CachingSiteStore( - $this->getHashSiteStore( $testSites ), - ObjectCache::getLocalClusterInstance() - ); - - $sites = $store->getSites(); - - $this->assertInstanceOf( SiteList::class, $sites ); - - /** - * @var Site $site - */ - foreach ( $sites as $site ) { - $this->assertInstanceOf( Site::class, $site ); - } - - foreach ( $testSites as $site ) { - if ( $site->getGlobalId() !== null ) { - $this->assertTrue( $sites->hasSite( $site->getGlobalId() ) ); - } - } - } - - /** - * @covers CachingSiteStore::saveSites - */ - public function testSaveSites() { - $store = new CachingSiteStore( - new HashSiteStore(), ObjectCache::getLocalClusterInstance() - ); - - $sites = []; - - $site = new Site(); - $site->setGlobalId( 'ertrywuutr' ); - $site->setLanguageCode( 'en' ); - $sites[] = $site; - - $site = new MediaWikiSite(); - $site->setGlobalId( 'sdfhxujgkfpth' ); - $site->setLanguageCode( 'nl' ); - $sites[] = $site; - - $this->assertTrue( $store->saveSites( $sites ) ); - - $site = $store->getSite( 'ertrywuutr' ); - $this->assertInstanceOf( Site::class, $site ); - $this->assertEquals( 'en', $site->getLanguageCode() ); - - $site = $store->getSite( 'sdfhxujgkfpth' ); - $this->assertInstanceOf( Site::class, $site ); - $this->assertEquals( 'nl', $site->getLanguageCode() ); - } - - /** - * @covers CachingSiteStore::reset - */ - public function testReset() { - $dbSiteStore = $this->getMockBuilder( SiteStore::class ) - ->disableOriginalConstructor() - ->getMock(); - - $dbSiteStore->expects( $this->any() ) - ->method( 'getSite' ) - ->will( $this->returnValue( $this->getTestSite() ) ); - - $dbSiteStore->expects( $this->any() ) - ->method( 'getSites' ) - ->will( $this->returnCallback( function () { - $siteList = new SiteList(); - $siteList->setSite( $this->getTestSite() ); - - return $siteList; - } ) ); - - $store = new CachingSiteStore( $dbSiteStore, ObjectCache::getLocalClusterInstance() ); - - // initialize internal cache - $this->assertGreaterThan( 0, $store->getSites()->count(), 'count sites' ); - - $store->getSite( 'enwiki' )->setLanguageCode( 'en-ca' ); - - // sanity check: $store should have the new language code for 'enwiki' - $this->assertEquals( 'en-ca', $store->getSite( 'enwiki' )->getLanguageCode(), 'sanity check' ); - - // purge cache - $store->reset(); - - // the internal cache of $store should be updated, and now pulling - // the site from the 'fallback' DBSiteStore with the original language code. - $this->assertEquals( 'en', $store->getSite( 'enwiki' )->getLanguageCode(), 'reset' ); - } - - public function getTestSite() { - $enwiki = new MediaWikiSite(); - $enwiki->setGlobalId( 'enwiki' ); - $enwiki->setLanguageCode( 'en' ); - - return $enwiki; - } - - /** - * @covers CachingSiteStore::clear - */ - public function testClear() { - $store = new CachingSiteStore( - new HashSiteStore(), ObjectCache::getLocalClusterInstance() - ); - $this->assertTrue( $store->clear() ); - - $site = $store->getSite( 'enwiki' ); - $this->assertNull( $site ); - - $sites = $store->getSites(); - $this->assertEquals( 0, $sites->count() ); - } - - /** - * @param Site[] $sites - * - * @return SiteStore - */ - private function getHashSiteStore( array $sites ) { - $siteStore = new HashSiteStore(); - $siteStore->saveSites( $sites ); - - return $siteStore; - } - -} diff --git a/tests/phpunit/unit/includes/site/HashSiteStoreTest.php b/tests/phpunit/unit/includes/site/HashSiteStoreTest.php deleted file mode 100644 index 8b0d4e080b..0000000000 --- a/tests/phpunit/unit/includes/site/HashSiteStoreTest.php +++ /dev/null @@ -1,105 +0,0 @@ - - */ -class HashSiteStoreTest extends \MediaWikiUnitTestCase { - - /** - * @covers HashSiteStore::getSites - */ - public function testGetSites() { - $expectedSites = []; - - foreach ( TestSites::getSites() as $testSite ) { - $siteId = $testSite->getGlobalId(); - $expectedSites[$siteId] = $testSite; - } - - $siteStore = new HashSiteStore( $expectedSites ); - - $this->assertEquals( new SiteList( $expectedSites ), $siteStore->getSites() ); - } - - /** - * @covers HashSiteStore::saveSite - * @covers HashSiteStore::getSite - */ - public function testSaveSite() { - $store = new HashSiteStore(); - - $site = new Site(); - $site->setGlobalId( 'dewiki' ); - - $this->assertCount( 0, $store->getSites(), '0 sites in store' ); - - $store->saveSite( $site ); - - $this->assertCount( 1, $store->getSites(), 'Store has 1 sites' ); - $this->assertEquals( $site, $store->getSite( 'dewiki' ), 'Store has dewiki' ); - } - - /** - * @covers HashSiteStore::saveSites - */ - public function testSaveSites() { - $store = new HashSiteStore(); - - $sites = []; - - $site = new Site(); - $site->setGlobalId( 'enwiki' ); - $site->setLanguageCode( 'en' ); - $sites[] = $site; - - $site = new MediaWikiSite(); - $site->setGlobalId( 'eswiki' ); - $site->setLanguageCode( 'es' ); - $sites[] = $site; - - $this->assertCount( 0, $store->getSites(), '0 sites in store' ); - - $store->saveSites( $sites ); - - $this->assertCount( 2, $store->getSites(), 'Store has 2 sites' ); - $this->assertTrue( $store->getSites()->hasSite( 'enwiki' ), 'Store has enwiki' ); - $this->assertTrue( $store->getSites()->hasSite( 'eswiki' ), 'Store has eswiki' ); - } - - /** - * @covers HashSiteStore::clear - */ - public function testClear() { - $store = new HashSiteStore(); - - $site = new Site(); - $site->setGlobalId( 'arwiki' ); - $store->saveSite( $site ); - - $this->assertCount( 1, $store->getSites(), '1 site in store' ); - - $store->clear(); - $this->assertCount( 0, $store->getSites(), '0 sites in store' ); - } -} diff --git a/tests/phpunit/unit/languages/SpecialPageAliasTest.php b/tests/phpunit/unit/languages/SpecialPageAliasTest.php new file mode 100644 index 0000000000..cce9d0eb0f --- /dev/null +++ b/tests/phpunit/unit/languages/SpecialPageAliasTest.php @@ -0,0 +1,64 @@ + + */ +class SpecialPageAliasTest extends \MediaWikiUnitTestCase { + + /** + * @coversNothing + * @dataProvider validSpecialPageAliasesProvider + */ + public function testValidSpecialPageAliases( $code, $specialPageAliases ) { + foreach ( $specialPageAliases as $specialPage => $aliases ) { + foreach ( $aliases as $alias ) { + $msg = "$specialPage alias '$alias' in $code is valid with no slashes"; + $this->assertRegExp( '/^[^\/]*$/', $msg ); + } + } + } + + public function validSpecialPageAliasesProvider() { + $codes = array_keys( Language::fetchLanguageNames( null, 'mwfile' ) ); + + $data = []; + + foreach ( $codes as $code ) { + $specialPageAliases = $this->getSpecialPageAliases( $code ); + + if ( $specialPageAliases !== [] ) { + $data[] = [ $code, $specialPageAliases ]; + } + } + + return $data; + } + + /** + * @param string $code + * + * @return array + */ + protected function getSpecialPageAliases( $code ) { + $file = Language::getMessagesFileName( $code ); + + if ( is_readable( $file ) ) { + include $file; + + if ( isset( $specialPageAliases ) && $specialPageAliases !== null ) { + return $specialPageAliases; + } + } + + return []; + } + +}