createHookContainer(), $this->createMock( JobQueueGroup::class ), $this->createMock( IConnectionProvider::class ), $this->createMock( ReadOnlyMode::class ), $this->createMock( RepoGroup::class ), new NullLogger(), $this->createMock( RevisionStore::class ), $wpFactory ?? $this->createMock( WikiPageFactory::class ), $this->createMock( PageUpdaterFactory::class ), $this->createMock( IContentHandlerFactory::class ), $archivedRevisionLookup ?? $this->createMock( ArchivedRevisionLookup::class ), $namespaceInfo ?? $this->createMock( NamespaceInfo::class ), $this->createMock( ITextFormatter::class ), $page ?? $this->createMock( ProperPageIdentity::class ), $this->createMock( Authority::class ) ); } /** * @param ProperPageIdentity $page * @param WikiPageFactory $wpFactory * @param NamespaceInfo|null $nsInfo * @param ArchivedRevisionLookup $archivedRevisionLookup * @param string|null $expectedMsg * @covers ::canProbablyUndeleteAssociatedTalk * @dataProvider provideAssociatedTalk */ public function testCanProbablyUndeleteAssociatedTalk( ProperPageIdentity $page, WikiPageFactory $wpFactory, ?NamespaceInfo $nsInfo, ArchivedRevisionLookup $archivedRevisionLookup, ?string $expectedMsg ): void { $res = $this->getUndeletePage( $page, $wpFactory, $nsInfo, $archivedRevisionLookup ) ->canProbablyUndeleteAssociatedTalk(); if ( $expectedMsg === null ) { $this->assertStatusGood( $res ); } else { $this->assertStatusError( $expectedMsg, $res ); } } public function provideAssociatedTalk(): Generator { $getWpFactory = function ( bool $talkExists ): WikiPageFactory { $wpFactory = $this->createMock( WikiPageFactory::class ); $wpFactory->method( 'newFromTitle' )->willReturnCallback( function ( $t ) { $title = Title::castFromPageReference( $t ); $wikiPage = $this->createMock( WikiPage::class ); $wikiPage->method( 'getTitle' )->willReturn( $title ); return $wikiPage; } ); $wpFactory->method( 'newFromLinkTarget' )->willReturnCallback( function ( LinkTarget $t ) use ( $talkExists ) { $existingTalk = $this->createMock( WikiPage::class ); $existingTalk->method( 'exists' )->willReturn( $talkExists ); return $existingTalk; } ); return $wpFactory; }; $getArchiveLookup = function ( bool $hasDeletedRevs ): ArchivedRevisionLookup { $ret = $this->createMock( ArchivedRevisionLookup::class ); $ret->method( 'hasArchivedRevisions' )->willReturn( $hasDeletedRevs ); return $ret; }; $nsInfo = new NamespaceInfo( $this->createMock( ServiceOptions::class ), $this->createHookContainer(), [], [] ); $talkPage = new PageIdentityValue( 42, NS_TALK, 'Test talk page', PageIdentity::LOCAL ); yield 'Talk page' => [ $talkPage, $getWpFactory( false ), $nsInfo, $getArchiveLookup( false ), 'undelete-error-associated-alreadytalk' ]; $nonTalkPage = new PageIdentityValue( 44, NS_MAIN, 'Test article', PageIdentity::LOCAL ); yield 'Article whose talk page exists and does not have deleted revisions' => [ $nonTalkPage, $getWpFactory( true ), $nsInfo, $getArchiveLookup( false ), 'undelete-error-associated-notdeleted' ]; yield 'Article whose talk page does not exist and does not have deleted revisions' => [ $nonTalkPage, $getWpFactory( false ), $nsInfo, $getArchiveLookup( false ), 'undelete-error-associated-notdeleted' ]; yield 'Article whose talk page exists and has deleted revisions' => [ $nonTalkPage, $getWpFactory( true ), $nsInfo, $getArchiveLookup( true ), null ]; yield 'Article whose talk page does not exist and has deleted revisions' => [ $nonTalkPage, $getWpFactory( false ), $nsInfo, $getArchiveLookup( true ), null ]; } }