diff options
Diffstat (limited to 'tests/phpunit/includes/specialpage/SpecialPageFactoryTest.php')
-rw-r--r-- | tests/phpunit/includes/specialpage/SpecialPageFactoryTest.php | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/tests/phpunit/includes/specialpage/SpecialPageFactoryTest.php b/tests/phpunit/includes/specialpage/SpecialPageFactoryTest.php new file mode 100644 index 00000000..779fa558 --- /dev/null +++ b/tests/phpunit/includes/specialpage/SpecialPageFactoryTest.php @@ -0,0 +1,225 @@ +<?php +/** + * Factory for handling the special page list and generating SpecialPage objects. + * + * 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 + * + * @covers SpecialPageFactory + * @group SpecialPage + */ +class SpecialPageFactoryTest extends MediaWikiTestCase { + + protected function tearDown() { + parent::tearDown(); + + SpecialPageFactory::resetList(); + } + + public function newSpecialAllPages() { + return new SpecialAllPages(); + } + + public function specialPageProvider() { + return array( + 'class name' => array( 'SpecialAllPages', false ), + 'closure' => array( function() { + return new SpecialAllPages(); + }, false ), + 'function' => array( array( $this, 'newSpecialAllPages' ), false ), + ); + } + + /** + * @dataProvider specialPageProvider + */ + public function testGetPage( $spec, $shouldReuseInstance ) { + $this->mergeMwGlobalArrayValue( 'wgSpecialPages', array( 'testdummy' => $spec ) ); + SpecialPageFactory::resetList(); + + $page = SpecialPageFactory::getPage( 'testdummy' ); + $this->assertInstanceOf( 'SpecialPage', $page ); + + $page2 = SpecialPageFactory::getPage( 'testdummy' ); + $this->assertEquals( $shouldReuseInstance, $page2 === $page, "Should re-use instance:" ); + } + + public function testGetNames() { + $this->mergeMwGlobalArrayValue( 'wgSpecialPages', array( 'testdummy' => 'SpecialAllPages' ) ); + SpecialPageFactory::resetList(); + + $names = SpecialPageFactory::getNames(); + $this->assertInternalType( 'array', $names ); + $this->assertContains( 'testdummy', $names ); + } + + public function testResolveAlias() { + $this->setMwGlobals( 'wgContLang', Language::factory( 'de' ) ); + SpecialPageFactory::resetList(); + + list( $name, $param ) = SpecialPageFactory::resolveAlias( 'Spezialseiten/Foo' ); + $this->assertEquals( 'Specialpages', $name ); + $this->assertEquals( 'Foo', $param ); + } + + public function testGetLocalNameFor() { + $this->setMwGlobals( 'wgContLang', Language::factory( 'de' ) ); + SpecialPageFactory::resetList(); + + $name = SpecialPageFactory::getLocalNameFor( 'Specialpages', 'Foo' ); + $this->assertEquals( 'Spezialseiten/Foo', $name ); + } + + public function testGetTitleForAlias() { + $this->setMwGlobals( 'wgContLang', Language::factory( 'de' ) ); + SpecialPageFactory::resetList(); + + $title = SpecialPageFactory::getTitleForAlias( 'Specialpages/Foo' ); + $this->assertEquals( 'Spezialseiten/Foo', $title->getText() ); + $this->assertEquals( NS_SPECIAL, $title->getNamespace() ); + } + + /** + * @dataProvider provideTestConflictResolution + */ + public function testConflictResolution( + $test, $aliasesList, $alias, $expectedName, $expectedAlias, $expectWarnings + ) { + global $wgContLang; + $lang = clone $wgContLang; + $lang->mExtendedSpecialPageAliases = $aliasesList; + $this->setMwGlobals( 'wgContLang', $lang ); + $this->setMwGlobals( 'wgSpecialPages', + array_combine( array_keys( $aliasesList ), array_keys( $aliasesList ) ) + ); + SpecialPageFactory::resetList(); + + // Catch the warnings we expect to be raised + $warnings = array(); + $this->setMwGlobals( 'wgDevelopmentWarnings', true ); + set_error_handler( function ( $errno, $errstr ) use ( &$warnings ) { + if ( preg_match( '/First alias \'[^\']*\' for .*/', $errstr ) || + preg_match( '/Did not find a usable alias for special page .*/', $errstr ) + ) { + $warnings[] = $errstr; + return true; + } + return false; + } ); + $reset = new ScopedCallback( 'restore_error_handler' ); + + list( $name, /*...*/ ) = SpecialPageFactory::resolveAlias( $alias ); + $this->assertEquals( $expectedName, $name, "$test: Alias to name" ); + $result = SpecialPageFactory::getLocalNameFor( $name ); + $this->assertEquals( $expectedAlias, $result, "$test: Alias to name to alias" ); + + $gotWarnings = count( $warnings ); + if ( $gotWarnings !== $expectWarnings ) { + $this->fail( "Expected $expectWarnings warning(s), but got $gotWarnings:\n" . + join( "\n", $warnings ) + ); + } + } + + /** + * @dataProvider provideTestConflictResolution + */ + public function testConflictResolutionReversed( + $test, $aliasesList, $alias, $expectedName, $expectedAlias, $expectWarnings + ) { + // Make sure order doesn't matter by reversing the list + $aliasesList = array_reverse( $aliasesList ); + return $this->testConflictResolution( + $test, $aliasesList, $alias, $expectedName, $expectedAlias, $expectWarnings + ); + } + + public function provideTestConflictResolution() { + return array( + array( + 'Canonical name wins', + array( 'Foo' => array( 'Foo', 'Bar' ), 'Baz' => array( 'Foo', 'BazPage', 'Baz2' ) ), + 'Foo', + 'Foo', + 'Foo', + 1, + ), + + array( + 'Doesn\'t redirect to a different special page\'s canonical name', + array( 'Foo' => array( 'Foo', 'Bar' ), 'Baz' => array( 'Foo', 'BazPage', 'Baz2' ) ), + 'Baz', + 'Baz', + 'BazPage', + 1, + ), + + array( + 'Canonical name wins even if not aliased', + array( 'Foo' => array( 'FooPage' ), 'Baz' => array( 'Foo', 'BazPage', 'Baz2' ) ), + 'Foo', + 'Foo', + 'FooPage', + 1, + ), + + array( + 'Doesn\'t redirect to a different special page\'s canonical name even if not aliased', + array( 'Foo' => array( 'FooPage' ), 'Baz' => array( 'Foo', 'BazPage', 'Baz2' ) ), + 'Baz', + 'Baz', + 'BazPage', + 1, + ), + + array( + 'First local name beats non-first', + array( 'First' => array( 'Foo' ), 'NonFirst' => array( 'Bar', 'Foo' ) ), + 'Foo', + 'First', + 'Foo', + 0, + ), + + array( + 'Doesn\'t redirect to a different special page\'s first alias', + array( + 'Foo' => array( 'Foo' ), + 'First' => array( 'Bar' ), + 'Baz' => array( 'Foo', 'Bar', 'BazPage', 'Baz2' ) + ), + 'Baz', + 'Baz', + 'BazPage', + 1, + ), + + array( + 'Doesn\'t redirect wrong even if all aliases conflict', + array( + 'Foo' => array( 'Foo' ), + 'First' => array( 'Bar' ), + 'Baz' => array( 'Foo', 'Bar' ) + ), + 'Baz', + 'Baz', + 'Baz', + 2, + ), + + ); + } + +} |