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();
+ }
}
--- /dev/null
+<?php
+
+/**
+ * Note: this is not a unit test, as it touches the file system and reads an actual file.
+ * If unit tests are added for MediaWikiVersionFetcher, this should be done in a distinct test case.
+ *
+ * @covers MediaWikiVersionFetcher
+ *
+ * @group ComposerHooks
+ *
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class MediaWikiVersionFetcherTest extends \MediaWikiIntegrationTestCase {
+
+ public function testReturnsResult() {
+ global $wgVersion;
+ $versionFetcher = new MediaWikiVersionFetcher();
+ $this->assertSame( $wgVersion, $versionFetcher->fetchVersion() );
+ }
+
+}
--- /dev/null
+<?php
+
+namespace MediaWiki\Tests\Revision;
+
+use ActorMigration;
+use CommentStore;
+use MediaWiki\Logger\Spi as LoggerSpi;
+use MediaWiki\Revision\RevisionStore;
+use MediaWiki\Revision\RevisionStoreFactory;
+use MediaWiki\Revision\SlotRoleRegistry;
+use MediaWiki\Storage\BlobStore;
+use MediaWiki\Storage\BlobStoreFactory;
+use MediaWiki\Storage\NameTableStore;
+use MediaWiki\Storage\NameTableStoreFactory;
+use MediaWiki\Storage\SqlBlobStore;
+use Psr\Log\LoggerInterface;
+use Psr\Log\NullLogger;
+use WANObjectCache;
+use Wikimedia\Rdbms\ILBFactory;
+use Wikimedia\Rdbms\ILoadBalancer;
+use Wikimedia\TestingAccessWrapper;
+
+class RevisionStoreFactoryTest extends \MediaWikiIntegrationTestCase {
+
+ /**
+ * @covers \MediaWiki\Revision\RevisionStoreFactory::__construct
+ */
+ public function testValidConstruction_doesntCauseErrors() {
+ new RevisionStoreFactory(
+ $this->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;
+ }
+
+}
--- /dev/null
+<?php
+
+use MediaWiki\MediaWikiServices;
+
+class ConfigFactoryTest extends \MediaWikiIntegrationTestCase {
+
+ /**
+ * @covers ConfigFactory::register
+ */
+ public function testRegister() {
+ $factory = new ConfigFactory();
+ $factory->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' ) );
+ }
+
+}
--- /dev/null
+<?php
+
+/**
+ * @group Media
+ * @covers SVGMetadataExtractor
+ */
+class SVGMetadataExtractorTest extends \MediaWikiIntegrationTestCase {
+
+ /**
+ * @dataProvider provideSvgFiles
+ */
+ public function testGetMetadata( $infile, $expected ) {
+ $this->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 = '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <ns4:Work xmlns:ns4="http://creativecommons.org/ns#" rdf:about="">
+ <ns5:format xmlns:ns5="http://purl.org/dc/elements/1.1/">image/svg+xml</ns5:format>
+ <ns5:type xmlns:ns5="http://purl.org/dc/elements/1.1/" rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ </ns4:Work>
+ </rdf:RDF>';
+ // 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 ],
+ ];
+ }
+}
$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() {
+ /** [ <reference list>, <individual id 1>, <individual id 2> ] */
+ return [
+ [ 'foo bar', 'foo', 'bar' ],
+ [ '#1 #2', '#1', '#2' ],
+ [ '+1 +2', '+1', '+2' ],
+ ];
+ }
+
}
--- /dev/null
+<?php
+
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @since 1.25
+ *
+ * @ingroup Site
+ * @ingroup Test
+ *
+ * @group Site
+ * @group Database
+ *
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+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;
+ }
+
+}
--- /dev/null
+<?php
+
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @since 1.25
+ *
+ * @ingroup Site
+ * @group Site
+ *
+ * @author Katie Filbert < aude.wiki@gmail.com >
+ */
+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' );
+ }
+}
+++ /dev/null
-<?php
-
-/**
- * Verifies that special page aliases are valid, with no slashes.
- *
- * @group Language
- * @group SpecialPageAliases
- * @group SystemTest
- * @group medium
- * @todo This should be a structure test
- *
- * @author Katie Filbert < aude.wiki@gmail.com >
- */
-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 [];
- }
-
-}
+++ /dev/null
-<?php
-
-/**
- * Note: this is not a unit test, as it touches the file system and reads an actual file.
- * If unit tests are added for MediaWikiVersionFetcher, this should be done in a distinct test case.
- *
- * @covers MediaWikiVersionFetcher
- *
- * @group ComposerHooks
- *
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- */
-class MediaWikiVersionFetcherTest extends \MediaWikiUnitTestCase {
-
- public function testReturnsResult() {
- global $wgVersion;
- $versionFetcher = new MediaWikiVersionFetcher();
- $this->assertSame( $wgVersion, $versionFetcher->fetchVersion() );
- }
-
-}
+++ /dev/null
-<?php
-
-namespace MediaWiki\Tests\Revision;
-
-use ActorMigration;
-use CommentStore;
-use MediaWiki\Logger\Spi as LoggerSpi;
-use MediaWiki\Revision\RevisionStore;
-use MediaWiki\Revision\RevisionStoreFactory;
-use MediaWiki\Revision\SlotRoleRegistry;
-use MediaWiki\Storage\BlobStore;
-use MediaWiki\Storage\BlobStoreFactory;
-use MediaWiki\Storage\NameTableStore;
-use MediaWiki\Storage\NameTableStoreFactory;
-use MediaWiki\Storage\SqlBlobStore;
-use Psr\Log\LoggerInterface;
-use Psr\Log\NullLogger;
-use WANObjectCache;
-use Wikimedia\Rdbms\ILBFactory;
-use Wikimedia\Rdbms\ILoadBalancer;
-use Wikimedia\TestingAccessWrapper;
-
-class RevisionStoreFactoryTest extends \MediaWikiUnitTestCase {
-
- /**
- * @covers \MediaWiki\Revision\RevisionStoreFactory::__construct
- */
- public function testValidConstruction_doesntCauseErrors() {
- new RevisionStoreFactory(
- $this->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;
- }
-
-}
+++ /dev/null
-<?php
-
-use MediaWiki\MediaWikiServices;
-
-class ConfigFactoryTest extends \MediaWikiUnitTestCase {
-
- /**
- * @covers ConfigFactory::register
- */
- public function testRegister() {
- $factory = new ConfigFactory();
- $factory->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' ) );
- }
-
-}
+++ /dev/null
-<?php
-
-/**
- * @group Media
- * @covers SVGMetadataExtractor
- */
-class SVGMetadataExtractorTest extends \MediaWikiUnitTestCase {
-
- /**
- * @dataProvider provideSvgFiles
- */
- public function testGetMetadata( $infile, $expected ) {
- $this->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 = '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
- <ns4:Work xmlns:ns4="http://creativecommons.org/ns#" rdf:about="">
- <ns5:format xmlns:ns5="http://purl.org/dc/elements/1.1/">image/svg+xml</ns5:format>
- <ns5:type xmlns:ns5="http://purl.org/dc/elements/1.1/" rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
- </ns4:Work>
- </rdf:RDF>';
- // 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 ],
- ];
- }
-}
];
}
- /**
- * 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() {
- /** [ <reference list>, <individual id 1>, <individual id 2> ] */
- return [
- [ 'foo bar', 'foo', 'bar' ],
- [ '#1 #2', '#1', '#2' ],
- [ '+1 +2', '+1', '+2' ],
- ];
- }
-
/**
* @dataProvider provideIsReservedDataAttribute
* @covers Sanitizer::isReservedDataAttribute
+++ /dev/null
-<?php
-
-/**
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @since 1.25
- *
- * @ingroup Site
- * @ingroup Test
- *
- * @group Site
- * @group Database
- *
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- */
-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;
- }
-
-}
+++ /dev/null
-<?php
-
-/**
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @since 1.25
- *
- * @ingroup Site
- * @group Site
- *
- * @author Katie Filbert < aude.wiki@gmail.com >
- */
-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' );
- }
-}
--- /dev/null
+<?php
+
+/**
+ * Verifies that special page aliases are valid, with no slashes.
+ *
+ * @group Language
+ * @group SpecialPageAliases
+ * @group SystemTest
+ * @group medium
+ * @todo This should be a structure test
+ *
+ * @author Katie Filbert < aude.wiki@gmail.com >
+ */
+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 [];
+ }
+
+}