diff options
author | DannyS712 <dannys712.wiki@gmail.com> | 2021-05-03 20:38:48 +0000 |
---|---|---|
committer | DannyS712 <dannys712.wiki@gmail.com> | 2021-05-04 19:10:23 +0000 |
commit | 41287e87d81828d9dceb7b4c24fa7f253b792a49 (patch) | |
tree | fdae150f53df9eacb941d8117bc5ca90cad45fb9 | |
parent | da771ce005cebce15f880c2bbd68f9f2d29a3f44 (diff) | |
download | mediawikicore-41287e87d81828d9dceb7b4c24fa7f253b792a49.tar.gz mediawikicore-41287e87d81828d9dceb7b4c24fa7f253b792a49.zip |
Add MediaWikiTitleCodec and NamespaceInfo to DummyServicesTrait
Move MockTitleTrait::makeMockTitleCodec to DummyServicesTrait, and
replace the two existing uses, which are in core. Add some new
uses instead of mocking each time.
Unfortunately, we cannot use an actual MediaWikiTitleCodec
for the tests in BadFileLookup, because those tests are unit tests
and a MalformedTitleException cannot be created in the context
of a unit test. BadFileLookupTest gets around this by using
a mock that throws a mock exception - add a comment inline
explaining why we cannot use a real MediaWikiTitleCodec.
Paired with adding of NamespaceInfo to make mocking the language
methods related to namespaces easier by matching the real
logic in the Language class to the extend possible. Update a few
tests to use the DummyServicesTrait for their NamespaceInfo services.
Change-Id: Ibd691ccf0e632e1bf0bc1f7e9ddc0c660d5cad32
9 files changed, 214 insertions, 213 deletions
diff --git a/tests/phpunit/includes/user/UserNameUtilsTest.php b/tests/phpunit/includes/user/UserNameUtilsTest.php index aad7eb5c2629..6a0c5c1f196d 100644 --- a/tests/phpunit/includes/user/UserNameUtilsTest.php +++ b/tests/phpunit/includes/user/UserNameUtilsTest.php @@ -1,6 +1,7 @@ <?php use MediaWiki\Config\ServiceOptions; +use MediaWiki\Tests\Unit\DummyServicesTrait; use MediaWiki\User\UserNameUtils; use Psr\Log\LoggerInterface; use Psr\Log\LogLevel; @@ -15,7 +16,7 @@ use Wikimedia\Message\MessageValue; * @author DannyS712 */ class UserNameUtilsTest extends MediaWikiIntegrationTestCase { - use MockTitleTrait; + use DummyServicesTrait; private function getUCFirstLanguageMock() { // Used by a number of tests @@ -53,8 +54,8 @@ class UserNameUtilsTest extends MediaWikiIntegrationTestCase { $logger = new NullLogger(); } - // MockTitleTrait::makeMockTitleCodec - $titleParser = $this->makeMockTitleCodec( [ + // DummyServicesTrait::getDummyTitleParser + $titleParser = $this->getDummyTitleParser( [ 'validInterwikis' => [ 'interwiki' ], ] ); diff --git a/tests/phpunit/integration/includes/Rest/Handler/CreationHandlerTest.php b/tests/phpunit/integration/includes/Rest/Handler/CreationHandlerTest.php index 8916cf888f77..91e204b13950 100644 --- a/tests/phpunit/integration/includes/Rest/Handler/CreationHandlerTest.php +++ b/tests/phpunit/integration/includes/Rest/Handler/CreationHandlerTest.php @@ -12,8 +12,8 @@ use MediaWiki\Rest\RequestData; use MediaWiki\Revision\RevisionLookup; use MediaWiki\Storage\MutableRevisionRecord; use MediaWiki\Storage\SlotRecord; +use MediaWiki\Tests\Unit\DummyServicesTrait; use MediaWikiIntegrationTestCase; -use MediaWikiTitleCodec; use MockTitleTrait; use PHPUnit\Framework\MockObject\MockObject; use Status; @@ -26,8 +26,8 @@ use WikitextContent; * @covers \MediaWiki\Rest\Handler\CreationHandler */ class CreationHandlerTest extends MediaWikiIntegrationTestCase { - use ActionModuleBasedHandlerTestTrait; + use DummyServicesTrait; use MockTitleTrait; private function newHandler( $resultData, $throwException = null, $csrfSafe = false ) { @@ -47,25 +47,8 @@ class CreationHandlerTest extends MediaWikiIntegrationTestCase { [ CONTENT_MODEL_TEXT, true ], ] ); - /** @var MockObject|MediaWikiTitleCodec $titleCodec */ - $titleCodec = $this->getMockBuilder( MediaWikiTitleCodec::class ) - ->disableOriginalConstructor() - ->onlyMethods( [ 'formatTitle', 'splitTitleString' ] ) - ->getMock(); - - $titleCodec->method( 'formatTitle' ) - ->willReturnCallback( static function ( $namespace, $text ) { - return "ns:$namespace:" . ucfirst( $text ); - } ); - $titleCodec->method( 'splitTitleString' ) - ->willReturnCallback( static function ( $text ) { - return [ - 'interwiki' => '', - 'fragment' => '', - 'namespace' => 0, - 'dbkey' => str_replace( ' ', '_', $text ) - ]; - } ); + // DummyServicesTrait::getDummyMediaWikiTitleCodec + $titleCodec = $this->getDummyMediaWikiTitleCodec(); /** @var RevisionLookup|MockObject $revisionLookup */ $revisionLookup = $this->createNoOpMock( RevisionLookup::class, [ 'getRevisionById' ] ); @@ -136,8 +119,8 @@ class CreationHandlerTest extends MediaWikiIntegrationTestCase { ], [ // Response expected to be generated by CreationHandler 'id' => 94542, - 'title' => 'ns:0:Foo', - 'key' => 'ns:0:Foo', + 'title' => 'Foo', + 'key' => 'Foo', 'content_model' => 'wikitext', 'latest' => [ 'id' => 371707, @@ -188,8 +171,8 @@ class CreationHandlerTest extends MediaWikiIntegrationTestCase { ], [ // Response expected to be generated by CreationHandler 'id' => 94542, - 'title' => 'ns:0:Talk:Foo', // our mock TitleCodec doesn't parse namespaces - 'key' => 'ns:0:Talk:Foo', + 'title' => 'Talk:Foo', + 'key' => 'Talk:Foo', 'content_model' => CONTENT_MODEL_TEXT, 'latest' => [ 'id' => 371707, @@ -240,8 +223,8 @@ class CreationHandlerTest extends MediaWikiIntegrationTestCase { ], [ // Response expected to be generated by CreationHandler 'id' => 94542, - 'title' => 'ns:0:Foo/bar', - 'key' => 'ns:0:Foo/bar', + 'title' => 'Foo/bar', + 'key' => 'Foo/bar', 'content_model' => 'wikitext', 'latest' => [ 'id' => 371707, @@ -290,8 +273,8 @@ class CreationHandlerTest extends MediaWikiIntegrationTestCase { ], [ // Response expected to be generated by CreationHandler 'id' => 94542, - 'title' => 'ns:0:Foo (ba+r)', - 'key' => 'ns:0:Foo_(ba+r)', + 'title' => 'Foo (ba+r)', + 'key' => 'Foo_(ba+r)', 'content_model' => 'wikitext', 'latest' => [ 'id' => 371707, diff --git a/tests/phpunit/integration/includes/Rest/Handler/LanguageLinksHandlerTest.php b/tests/phpunit/integration/includes/Rest/Handler/LanguageLinksHandlerTest.php index f7bdf0f7493e..0630113d660e 100644 --- a/tests/phpunit/integration/includes/Rest/Handler/LanguageLinksHandlerTest.php +++ b/tests/phpunit/integration/includes/Rest/Handler/LanguageLinksHandlerTest.php @@ -10,7 +10,7 @@ use MediaWiki\Page\PageIdentity; use MediaWiki\Rest\Handler\LanguageLinksHandler; use MediaWiki\Rest\LocalizedHttpException; use MediaWiki\Rest\RequestData; -use MockTitleTrait; +use MediaWiki\Tests\Unit\DummyServicesTrait; use Title; use Wikimedia\Message\MessageValue; @@ -20,9 +20,8 @@ use Wikimedia\Message\MessageValue; * @group Database */ class LanguageLinksHandlerTest extends \MediaWikiIntegrationTestCase { - + use DummyServicesTrait; use HandlerTestTrait; - use MockTitleTrait; public function addDBData() { $defaults = [ @@ -55,7 +54,8 @@ class LanguageLinksHandlerTest extends \MediaWikiIntegrationTestCase { $services->getHookContainer() ); - $titleCodec = $this->makeMockTitleCodec(); + // DummyServicesTrait::getDummyMediaWikiTitleCodec + $titleCodec = $this->getDummyMediaWikiTitleCodec(); return new LanguageLinksHandler( $services->getDBLoadBalancer(), diff --git a/tests/phpunit/integration/includes/Rest/Handler/UpdateHandlerTest.php b/tests/phpunit/integration/includes/Rest/Handler/UpdateHandlerTest.php index 949e304abbb2..211477188872 100644 --- a/tests/phpunit/integration/includes/Rest/Handler/UpdateHandlerTest.php +++ b/tests/phpunit/integration/includes/Rest/Handler/UpdateHandlerTest.php @@ -13,7 +13,7 @@ use MediaWiki\Rest\RequestData; use MediaWiki\Revision\RevisionLookup; use MediaWiki\Storage\MutableRevisionRecord; use MediaWiki\Storage\SlotRecord; -use MediaWikiTitleCodec; +use MediaWiki\Tests\Unit\DummyServicesTrait; use MockTitleTrait; use PHPUnit\Framework\MockObject\MockObject; use Status; @@ -28,8 +28,8 @@ use WikitextContentHandler; * @covers \MediaWiki\Rest\Handler\UpdateHandler */ class UpdateHandlerTest extends \MediaWikiLangTestCase { - use ActionModuleBasedHandlerTestTrait; + use DummyServicesTrait; use MockTitleTrait; private function newHandler( $resultData, $throwException = null, $csrfSafe = false ) { @@ -55,25 +55,8 @@ class UpdateHandlerTest extends \MediaWikiLangTestCase { ->method( 'getContentHandler' ) ->willReturn( new WikitextContentHandler() ); - /** @var MockObject|MediaWikiTitleCodec $titleCodec */ - $titleCodec = $this->getMockBuilder( MediaWikiTitleCodec::class ) - ->disableOriginalConstructor() - ->onlyMethods( [ 'formatTitle', 'splitTitleString' ] ) - ->getMock(); - - $titleCodec->method( 'formatTitle' ) - ->willReturnCallback( static function ( $namespace, $text ) { - return "ns:$namespace:" . ucfirst( $text ); - } ); - $titleCodec->method( 'splitTitleString' ) - ->willReturnCallback( static function ( $text ) { - return [ - 'interwiki' => '', - 'fragment' => '', - 'namespace' => 0, - 'dbkey' => str_replace( ' ', '_', $text ) - ]; - } ); + // DummyServicesTrait::getDummyMediaWikiTitleCodec + $titleCodec = $this->getDummyMediaWikiTitleCodec(); /** @var RevisionLookup|MockObject $revisionLookup */ $revisionLookup = $this->createNoOpMock( @@ -154,8 +137,8 @@ class UpdateHandlerTest extends \MediaWikiLangTestCase { ], [ // Response expected to be generated by UpdateHandler 'id' => 94542, - 'title' => 'ns:0:Foo', - 'key' => 'ns:0:Foo', + 'title' => 'Foo', + 'key' => 'Foo', 'content_model' => 'wikitext', 'latest' => [ 'id' => 371707, @@ -206,8 +189,8 @@ class UpdateHandlerTest extends \MediaWikiLangTestCase { ], [ // Response expected to be generated by UpdateHandler 'id' => 94542, - 'title' => 'ns:0:Foo', - 'key' => 'ns:0:Foo', + 'title' => 'Foo', + 'key' => 'Foo', 'content_model' => 'wikitext', 'latest' => [ 'id' => 371707, @@ -258,8 +241,8 @@ class UpdateHandlerTest extends \MediaWikiLangTestCase { [ // Response expected to be generated by UpdateHandler 'id' => 94542, 'content_model' => 'wikitext', - 'title' => 'ns:0:Foo bar', - 'key' => 'ns:0:Foo_bar', + 'title' => 'Foo bar', + 'key' => 'Foo_bar', 'latest' => [ 'id' => 371707, 'timestamp' => "2018-12-18T16:59:42Z" @@ -310,8 +293,8 @@ class UpdateHandlerTest extends \MediaWikiLangTestCase { [ // Response expected to be generated by UpdateHandler 'id' => 94542, 'content_model' => 'wikitext', - 'title' => 'ns:0:Foo bar', - 'key' => 'ns:0:Foo_bar', + 'title' => 'Foo bar', + 'key' => 'Foo_bar', 'latest' => [ 'id' => 371707, 'timestamp' => "2018-12-18T16:59:42Z" diff --git a/tests/phpunit/mocks/DummyServicesTrait.php b/tests/phpunit/mocks/DummyServicesTrait.php index 75aefd9bf00c..5fb0879b2c08 100644 --- a/tests/phpunit/mocks/DummyServicesTrait.php +++ b/tests/phpunit/mocks/DummyServicesTrait.php @@ -21,17 +21,33 @@ namespace MediaWiki\Tests\Unit; +use GenderCache; +use Language; use MediaWiki\Cache\CacheKeyHelper; +use MediaWiki\Config\ServiceOptions; +use MediaWiki\HookContainer\HookContainer; +use MediaWiki\Interwiki\InterwikiLookup; use MediaWiki\Linker\LinkTarget; use MediaWiki\Page\PageReference; use MediaWiki\User\UserIdentity; +use MediaWikiTitleCodec; +use NamespaceInfo; use PHPUnit\Framework\MockObject\MockObject; +use TitleFormatter; +use TitleParser; use WatchedItem; use WatchedItemStore; /** * Trait to get helper services that can be used in unit tests * + * Getters are in the form getDummy{ServiceName} because they *might* be + * returning mock objects (like getDummyWatchedItemStore), they *might* be + * returning real services but with dependencies that are mocks (like + * getDummyMediaWikiTitleCodec), or they *might* be full real services + * with no mocks (like getDummyNamespaceInfo) but with the name "dummy" + * to be consistent. + * * @internal * @author DannyS712 */ @@ -46,6 +62,157 @@ trait DummyServicesTrait { private $watchedItemStoreData = []; /** + * @param arary $options see getDummyMediaWikiTitleCodec for supported options + * @return TitleFormatter + */ + private function getDummyTitleFormatter( array $options = [] ) : TitleFormatter { + return $this->getDummyMediaWikiTitleCodec( $options ); + } + + /** + * @param arary $options see getDummyMediaWikiTitleCodec for supported options + * @return TitleParser + */ + private function getDummyTitleParser( array $options = [] ) : TitleParser { + return $this->getDummyMediaWikiTitleCodec( $options ); + } + + /** + * Note: you should probably use getDummyTitleFormatter or getDummyTitleParser, + * unless you actually need both services, in which case it doesn't make sense + * to get two different objects when they are implemented together + * + * @param array $options Supported keys: + * - validInterwikis: string[] + * + * @return MediaWikiTitleCodec + */ + private function getDummyMediaWikiTitleCodec( array $options = [] ) : MediaWikiTitleCodec { + $baseConfig = [ + 'validInterwikis' => [], + ]; + $config = $options + $baseConfig; + + $namespaceInfo = $this->getDummyNamespaceInfo(); + + /** @var Language|MockObject $language */ + $language = $this->createNoOpMock( + Language::class, + [ 'ucfirst', 'lc', 'getNsIndex', 'needsGenderDistinction', 'getNsText' ] + ); + $language->method( 'ucfirst' )->willReturnCallback( 'ucfirst' ); + $language->method( 'lc' )->willReturnCallback( + static function ( $str, $first ) { + return $first ? lcfirst( $str ) : strtolower( $str ); + } + ); + $language->method( 'getNsIndex' )->willReturnCallback( + static function ( $text ) use ( $namespaceInfo ) { + $text = strtolower( $text ); + if ( $text === '' ) { + return NS_MAIN; + } + // based on the real Language::getNsIndex but without + // the support for translated namespace names + $index = $namespaceInfo->getCanonicalIndex( $text ); + + if ( $index !== null ) { + return $index; + } + return false; + } + ); + $language->method( 'getNsText' )->willReturnCallback( + static function ( $index ) use ( $namespaceInfo ) { + // based on the real Language::getNsText but without + // the support for translated namespace names + $namespaces = $namespaceInfo->getCanonicalNamespaces(); + return $namespaces[$index] ?? false; + } + ); + // Not dealing with genders, most languages don't - as a result, + // the GenderCache is never used and thus a no-op mock + $language->method( 'needsGenderDistinction' )->willReturn( false ); + + /** @var GenderCache|MockObject $genderCache */ + $genderCache = $this->createNoOpMock( GenderCache::class ); + + /** @var InterwikiLookup|MockObject $interwikiLookup */ + $interwikiLookup = $this->createNoOpMock( InterwikiLookup::class, [ 'isValidInterwiki' ] ); + $interwikiLookup->method( 'isValidInterwiki' )->willReturnCallback( + static function ( $prefix ) use ( $config ) { + // interwikis are lowercase, but we might be given a prefix that + // has uppercase characters, eg. from UserNameUtils normalization + $prefix = strtolower( $prefix ); + return in_array( $prefix, $config['validInterwikis'] ); + } + ); + + $titleCodec = new MediaWikiTitleCodec( + $language, + $genderCache, + [ 'en' ], + $interwikiLookup, + $namespaceInfo + ); + + return $titleCodec; + } + + /** + * @param HookContainer|null $hookContainer + * @return NamespaceInfo + */ + private function getDummyNamespaceInfo( HookContainer $hookContainer = null ) : NamespaceInfo { + // Rather than trying to use a complicated mock, it turns out that almost + // all of the NamespaceInfo service works fine in unit tests. The only issues: + // - in two places, NamespaceInfo tries to read extension attributes through + // ExtensionRegistry::getInstance()->getAttribute() - this should work fine + // in unit tests, it just won't include any extension info since those are + // not loaded + // - ::getRestrictionLevels() is a deprecated wrapper that calls + // PermissionManager::getNamespaceRestrictionLevels() - the PermissionManager + // is retrieved from MediaWikiServices, which doesn't work in unit tests. + // This shouldn't be an issue though, since it should only be called in + // the dedicated tests for that deprecation method, which use the real service + + // configuration is based on DefaultSettings + // TODO add a way for tests to override this + $options = new ServiceOptions( + NamespaceInfo::CONSTRUCTOR_OPTIONS, + [ + 'CanonicalNamespaceNames' => NamespaceInfo::CANONICAL_NAMES, + 'CapitalLinkOverrides' => [], + 'CapitalLinks' => true, + 'ContentNamespaces' => [ NS_MAIN ], + 'ExtraNamespaces' => [], + 'ExtraSignatureNamespaces' => [], + 'NamespaceContentModels' => [], + 'NamespacesWithSubpages' => [ + NS_TALK => true, + NS_USER => true, + NS_USER_TALK => true, + NS_PROJECT => true, + NS_PROJECT_TALK => true, + NS_FILE_TALK => true, + NS_MEDIAWIKI => true, + NS_MEDIAWIKI_TALK => true, + NS_TEMPLATE => true, + NS_TEMPLATE_TALK => true, + NS_HELP => true, + NS_HELP_TALK => true, + NS_CATEGORY_TALK => true, + ], + 'NonincludableNamespaces' => [], + ] + ); + return new NamespaceInfo( + $options, + $hookContainer ?? $this->createHookContainer() + ); + } + + /** * @param UserIdentity $user Should only be called with registered users * @param LinkTarget|PageReference $page * @return string diff --git a/tests/phpunit/mocks/MockTitleTrait.php b/tests/phpunit/mocks/MockTitleTrait.php index 2838dfde6bdf..fc6d423d8f59 100644 --- a/tests/phpunit/mocks/MockTitleTrait.php +++ b/tests/phpunit/mocks/MockTitleTrait.php @@ -1,6 +1,5 @@ <?php -use MediaWiki\Interwiki\InterwikiLookup; use PHPUnit\Framework\MockObject\MockObject; trait MockTitleTrait { @@ -83,75 +82,4 @@ trait MockTitleTrait { return $title; } - - /** - * @param array $options Supported keys: - * - validInterwikis: string[] - * - * @return MediaWikiTitleCodec - */ - private function makeMockTitleCodec( array $options = [] ) { - $baseConfig = [ - 'validInterwikis' => [], - ]; - $config = $options + $baseConfig; - - /** @var Language|MockObject $language */ - $language = $this->createNoOpMock( - Language::class, - [ 'ucfirst', 'lc', 'getNsIndex' ] - ); - $language->method( 'ucfirst' )->willReturnCallback( 'ucfirst' ); - $language->method( 'lc' )->willReturnCallback( - static function ( $str, $first ) { - return $first ? lcfirst( $str ) : strtolower( $str ); - } - ); - $language->method( 'getNsIndex' )->willReturnCallback( - static function ( $text ) { - $text = strtolower( $text ); - if ( $text === '' ) { - return NS_MAIN; - } - // partial support for the most commonly used namespaces in tests, - // feel free to expand as needed - $namespaces = [ - 'talk' => NS_TALK, - 'user' => NS_USER, - 'user_talk' => NS_USER_TALK, - 'project' => NS_PROJECT, - 'project_talk' => NS_PROJECT_TALK, - ]; - return $namespaces[ $text ] ?? false; - } - ); - - /** @var GenderCache|MockObject $genderCache */ - $genderCache = $this->createNoOpMock( GenderCache::class ); - - /** @var InterwikiLookup|MockObject $interwikiLookup */ - $interwikiLookup = $this->createNoOpMock( InterwikiLookup::class, [ 'isValidInterwiki' ] ); - $interwikiLookup->method( 'isValidInterwiki' )->willReturnCallback( - static function ( $prefix ) use ( $config ) { - // interwikis are lowercase, but we might be given a prefix that - // has uppercase characters, eg. from UserNameUtils normalization - $prefix = strtolower( $prefix ); - return in_array( $prefix, $config['validInterwikis'] ); - } - ); - - /** @var NamespaceInfo|MockObject $namespaceInfo */ - $namespaceInfo = $this->createNoOpMock( NamespaceInfo::class, [ 'isCapitalized' ] ); - $namespaceInfo->method( 'isCapitalized' )->willReturn( true ); - - $titleCodec = new MediaWikiTitleCodec( - $language, - $genderCache, - [ 'en' ], - $interwikiLookup, - $namespaceInfo - ); - - return $titleCodec; - } } diff --git a/tests/phpunit/unit/includes/BadFileLookupTest.php b/tests/phpunit/unit/includes/BadFileLookupTest.php index 6eb24a96763a..1e08e0511fea 100644 --- a/tests/phpunit/unit/includes/BadFileLookupTest.php +++ b/tests/phpunit/unit/includes/BadFileLookupTest.php @@ -87,6 +87,11 @@ WIKITEXT; } private function getMockTitleParser() { + // We can't use a real MediaWikiTitleCode, eg from DummyServicesTrait, + // because actual MalformedTitleException objects cannot be constructed in unit + // tests, and the tests in this file cover the code in BadFileLookup that + // handles an exception being thrown. Instead, we use a mock that throws mock + // exceptions $mock = $this->createMock( TitleParser::class ); $mock->method( 'parseTitle' )->will( $this->returnCallback( function ( $text ) { if ( strpos( $text, '<' ) !== false ) { diff --git a/tests/phpunit/unit/includes/watcheditem/WatchedItemStoreUnitTest.php b/tests/phpunit/unit/includes/watcheditem/WatchedItemStoreUnitTest.php index 59fcaf46eccb..8cd456c04d7d 100644 --- a/tests/phpunit/unit/includes/watcheditem/WatchedItemStoreUnitTest.php +++ b/tests/phpunit/unit/includes/watcheditem/WatchedItemStoreUnitTest.php @@ -6,6 +6,7 @@ use MediaWiki\Linker\LinkTarget; use MediaWiki\Page\PageIdentityValue; use MediaWiki\Revision\RevisionLookup; use MediaWiki\Revision\RevisionRecord; +use MediaWiki\Tests\Unit\DummyServicesTrait; use MediaWiki\User\UserFactory; use MediaWiki\User\UserIdentity; use MediaWiki\User\UserIdentityValue; @@ -22,6 +23,7 @@ use Wikimedia\TestingAccessWrapper; * @covers WatchedItemStore */ class WatchedItemStoreUnitTest extends MediaWikiUnitTestCase { + use DummyServicesTrait; use MockTitleTrait; /** @@ -121,40 +123,6 @@ class WatchedItemStoreUnitTest extends MediaWikiUnitTestCase { } /** - * Assumes that only getSubjectPage and getTalkPage will ever be called, and everything passed - * to them will have namespace 0. - * @return MockObject|NamespaceInfo - */ - private function getMockNsInfo() : NamespaceInfo { - $mock = $this->createMock( NamespaceInfo::class ); - $mock->method( 'getSubjectPage' )->will( $this->returnArgument( 0 ) ); - $mock->method( 'getTalkPage' )->willReturnCallback( - static function ( $target ) { - return new TitleValue( 1, $target->getDbKey() ); - } - ); - $mock->method( 'getSubject' )->willReturn( 0 ); - $mock->method( 'getTalk' )->willReturn( 1 ); - $mock->method( 'isWatchable' )->willReturnCallback( - static function ( $ns ) { - return $ns >= 0; - } - ); - - $mock->expects( $this->never() ) - ->method( - $this->anythingBut( - 'getSubjectPage', - 'getTalkPage', - 'getSubject', - 'getTalk', - 'isWatchable' - ) - ); - return $mock; - } - - /** * No methods may be called except provided callbacks, if any. * * @param array $callbacks Keys are method names, values are callbacks @@ -308,6 +276,11 @@ class WatchedItemStoreUnitTest extends MediaWikiUnitTestCase { ] ); $db = $mocks['db'] ?? $this->getMockDb(); + + // If we don't use a manual mock for something specific, get a full + // NamespaceInfo service from DummyServicesTrait::getDummyNamespaceInfo + $nsInfo = $mocks['nsInfo'] ?? $this->getDummyNamespaceInfo(); + return new WatchedItemStore( $options, $mocks['lbFactory'] ?? @@ -316,7 +289,7 @@ class WatchedItemStoreUnitTest extends MediaWikiUnitTestCase { new HashBagOStuff(), $mocks['cache'] ?? $this->getMockCache(), $mocks['readOnlyMode'] ?? $this->getMockReadOnlyMode(), - $mocks['nsInfo'] ?? $this->getMockNsInfo(), + $nsInfo, $mocks['revisionLookup'] ?? $this->getMockRevisionLookup(), $this->createHookContainer(), $this->getMockLinkBatchFactory( $db ), diff --git a/tests/phpunit/unit/includes/watchlist/WatchlistManagerTest.php b/tests/phpunit/unit/includes/watchlist/WatchlistManagerTest.php index e8c758b8e949..b7be5093812d 100644 --- a/tests/phpunit/unit/includes/watchlist/WatchlistManagerTest.php +++ b/tests/phpunit/unit/includes/watchlist/WatchlistManagerTest.php @@ -1,7 +1,6 @@ <?php use MediaWiki\Config\ServiceOptions; -use MediaWiki\HookContainer\HookContainer; use MediaWiki\Page\PageIdentity; use MediaWiki\Page\PageIdentityValue; use MediaWiki\Page\PageReference; @@ -29,45 +28,6 @@ class WatchlistManagerUnitTest extends MediaWikiUnitTestCase { use MockTitleTrait; use MockAuthorityTrait; - private function getNamespaceInfo( HookContainer $hookContainer ) { - // Don't try to mock all of the behavior needed for getting associated - // talk/subject pages, etc. Instead, since almost all of the NamespaceInfo - // class can be used within Unit tests already, and the parts that would - // create errors in unit tests aren't needed for this test, we can - // just use a real object - - // based on DefaultSettings - $options = new ServiceOptions( - NamespaceInfo::CONSTRUCTOR_OPTIONS, - [ - 'CanonicalNamespaceNames' => NamespaceInfo::CANONICAL_NAMES, - 'CapitalLinkOverrides' => [], - 'CapitalLinks' => true, - 'ContentNamespaces' => [ NS_MAIN ], - 'ExtraNamespaces' => [], - 'ExtraSignatureNamespaces' => [], - 'NamespaceContentModels' => [], - 'NamespacesWithSubpages' => [ - NS_TALK => true, - NS_USER => true, - NS_USER_TALK => true, - NS_PROJECT => true, - NS_PROJECT_TALK => true, - NS_FILE_TALK => true, - NS_MEDIAWIKI => true, - NS_MEDIAWIKI_TALK => true, - NS_TEMPLATE => true, - NS_TEMPLATE_TALK => true, - NS_HELP => true, - NS_HELP_TALK => true, - NS_CATEGORY_TALK => true, - ], - 'NonincludableNamespaces' => [], - ] - ); - return new NamespaceInfo( $options, $hookContainer ); - } - private function getWikiPageFactory() { // Needed so that we can test addWatchIgnoringRights and removeWatchIgnoringRights, // which convert a PageIdentity to a WikiPage to use WikiPage::getTitle so that @@ -122,7 +82,8 @@ class WatchlistManagerUnitTest extends MediaWikiUnitTestCase { $hookContainer = $params['hookContainer'] ?? $this->createHookContainer(); - $nsInfo = $this->getNamespaceInfo( $hookContainer ); + // DummyServicesTrait::getDummyNamespaceInfo + $nsInfo = $this->getDummyNamespaceInfo( $hookContainer ); return new WatchlistManager( $options, |