X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=tests%2Fphpunit%2Fincludes%2FRevision%2FRenderedRevisionTest.php;h=2ee1ab49952b96d05b96fbb1763c8eee986db188;hb=67dc9082463b6023fa1e79cc22cec3ac8589b322;hp=a2a9d0932262f1588d46f00629f48f40ab59b91b;hpb=32a243c457c4af126d697a6a591662c252e1f1d0;p=lhc%2Fweb%2Fwiklou.git diff --git a/tests/phpunit/includes/Revision/RenderedRevisionTest.php b/tests/phpunit/includes/Revision/RenderedRevisionTest.php index a2a9d09322..2ee1ab4995 100644 --- a/tests/phpunit/includes/Revision/RenderedRevisionTest.php +++ b/tests/phpunit/includes/Revision/RenderedRevisionTest.php @@ -6,7 +6,12 @@ use Content; use Language; use MediaWiki\Revision\RenderedRevision; use MediaWiki\Storage\MutableRevisionRecord; +use MediaWiki\Storage\MutableRevisionSlots; +use MediaWiki\Storage\RevisionArchiveRecord; use MediaWiki\Storage\RevisionRecord; +use MediaWiki\Storage\RevisionStore; +use MediaWiki\Storage\RevisionStoreRecord; +use MediaWiki\Storage\SlotRecord; use MediaWiki\Storage\SuppressedDataException; use MediaWiki\User\UserIdentityValue; use MediaWikiTestCase; @@ -15,6 +20,7 @@ use ParserOutput; use PHPUnit\Framework\MockObject\MockObject; use Title; use User; +use Wikimedia\TestingAccessWrapper; use WikitextContent; /** @@ -86,13 +92,13 @@ class RenderedRevisionTest extends MediaWikiTestCase { ->will( $this->returnValue( NS_MAIN ) ); $mock->expects( $this->any() ) ->method( 'getText' ) - ->will( $this->returnValue( __CLASS__ ) ); + ->will( $this->returnValue( 'RenderTestPage' ) ); $mock->expects( $this->any() ) ->method( 'getPrefixedText' ) - ->will( $this->returnValue( __CLASS__ ) ); + ->will( $this->returnValue( 'RenderTestPage' ) ); $mock->expects( $this->any() ) ->method( 'getDBkey' ) - ->will( $this->returnValue( __CLASS__ ) ); + ->will( $this->returnValue( 'RenderTestPage' ) ); $mock->expects( $this->any() ) ->method( 'getArticleID' ) ->will( $this->returnValue( $articleId ) ); @@ -111,7 +117,7 @@ class RenderedRevisionTest extends MediaWikiTestCase { $mock->expects( $this->any() ) ->method( 'equals' ) ->willReturnCallback( function ( Title $other ) use ( $mock ) { - return $mock->getArticleID() === $other->getArticleID(); + return $mock->getPrefixedText() === $other->getPrefixedText(); } ); $mock->expects( $this->any() ) ->method( 'userCan' ) @@ -122,21 +128,66 @@ class RenderedRevisionTest extends MediaWikiTestCase { return $mock; } - public function testGetRevisionParserOutput_new() { - $title = $this->getMockTitle( 7, 21 ); + /** + * @param string $class + * @param Title $title + * @param null|int $id + * @param int $visibility + * @return RevisionRecord + */ + private function getMockRevision( + $class, + $title, + $id = null, + $visibility = 0, + array $content = null + ) { + $frank = new UserIdentityValue( 9, 'Frank', 0 ); + + if ( !$content ) { + $text = ""; + $text .= "* page:{{PAGENAME}}!\n"; + $text .= "* rev:{{REVISIONID}}!\n"; + $text .= "* user:{{REVISIONUSER}}!\n"; + $text .= "* time:{{REVISIONTIMESTAMP}}!\n"; + $text .= "* [[Link It]]\n"; + + $content = [ 'main' => new WikitextContent( $text ) ]; + } - $rev = new MutableRevisionRecord( $title ); - $rev->setUser( new UserIdentityValue( 9, 'Frank', 0 ) ); - $rev->setTimestamp( '20180101000003' ); + /** @var MockObject|RevisionRecord $mock */ + $mock = $this->getMockBuilder( $class ) + ->disableOriginalConstructor() + ->setMethods( [ + 'getId', + 'getPageId', + 'getPageAsLinkTarget', + 'getUser', + 'getVisibility', + 'getTimestamp', + ] )->getMock(); + + $mock->method( 'getId' )->willReturn( $id ); + $mock->method( 'getPageId' )->willReturn( $title->getArticleID() ); + $mock->method( 'getPageAsLinkTarget' )->willReturn( $title ); + $mock->method( 'getUser' )->willReturn( $frank ); + $mock->method( 'getVisibility' )->willReturn( $visibility ); + $mock->method( 'getTimestamp' )->willReturn( '20180101000003' ); + + /** @var object $mockAccess */ + $mockAccess = TestingAccessWrapper::newFromObject( $mock ); + $mockAccess->mSlots = new MutableRevisionSlots(); + + foreach ( $content as $role => $cnt ) { + $mockAccess->mSlots->setContent( $role, $cnt ); + } - $text = ""; - $text .= "* page:{{PAGENAME}}\n"; - $text .= "* rev:{{REVISIONID}}\n"; - $text .= "* user:{{REVISIONUSER}}\n"; - $text .= "* time:{{REVISIONTIMESTAMP}}\n"; - $text .= "* [[Link It]]\n"; + return $mock; + } - $rev->setContent( 'main', new WikitextContent( $text ) ); + public function testGetRevisionParserOutput_new() { + $title = $this->getMockTitle( 0, 21 ); + $rev = $this->getMockRevision( RevisionStoreRecord::class, $title ); $options = ParserOptions::newCanonical( 'canonical' ); $rr = new RenderedRevision( $title, $rev, $options, $this->combinerCallback ); @@ -148,26 +199,33 @@ class RenderedRevisionTest extends MediaWikiTestCase { $html = $rr->getRevisionParserOutput()->getText(); - $this->assertContains( 'page:' . __CLASS__, $html ); - $this->assertContains( 'user:Frank', $html ); - $this->assertContains( 'time:20180101000003', $html ); + $this->assertContains( 'page:RenderTestPage!', $html ); + $this->assertContains( 'user:Frank!', $html ); + $this->assertContains( 'time:20180101000003!', $html ); } - public function testGetRevisionParserOutput_current() { - $title = $this->getMockTitle( 7, 21 ); + public function testGetRevisionParserOutput_previewWithSelfTransclusion() { + $title = $this->getMockTitle( 0, 21 ); + $name = $title->getPrefixedText(); - $rev = new MutableRevisionRecord( $title ); - $rev->setId( 21 ); // current! - $rev->setUser( new UserIdentityValue( 9, 'Frank', 0 ) ); - $rev->setTimestamp( '20180101000003' ); + $text = "(ONE)(TWO)#{{:$name}}#"; - $text = ""; - $text .= "* page:{{PAGENAME}}\n"; - $text .= "* rev:{{REVISIONID}}\n"; - $text .= "* user:{{REVISIONUSER}}\n"; - $text .= "* time:{{REVISIONTIMESTAMP}}\n"; + $content = [ + 'main' => new WikitextContent( $text ) + ]; - $rev->setContent( 'main', new WikitextContent( $text ) ); + $rev = $this->getMockRevision( RevisionStoreRecord::class, $title, null, 0, $content ); + + $options = ParserOptions::newCanonical( 'canonical' ); + $rr = new RenderedRevision( $title, $rev, $options, $this->combinerCallback ); + + $html = $rr->getRevisionParserOutput()->getText(); + $this->assertContains( '(ONE)#(ONE)(TWO)#', $html ); + } + + public function testGetRevisionParserOutput_current() { + $title = $this->getMockTitle( 7, 21 ); + $rev = $this->getMockRevision( RevisionStoreRecord::class, $title, 21 ); $options = ParserOptions::newCanonical( 'canonical' ); $rr = new RenderedRevision( $title, $rev, $options, $this->combinerCallback ); @@ -179,29 +237,39 @@ class RenderedRevisionTest extends MediaWikiTestCase { $html = $rr->getRevisionParserOutput()->getText(); - $this->assertContains( 'page:' . __CLASS__, $html ); - $this->assertContains( 'rev:21', $html ); - $this->assertContains( 'user:Frank', $html ); - $this->assertContains( 'time:20180101000003', $html ); + $this->assertContains( 'page:RenderTestPage!', $html ); + $this->assertContains( 'rev:21!', $html ); + $this->assertContains( 'user:Frank!', $html ); + $this->assertContains( 'time:20180101000003!', $html ); - $this->assertSame( $html, $rr->getSlotParserOutput( 'main' )->getText() ); + $this->assertSame( $html, $rr->getSlotParserOutput( SlotRecord::MAIN )->getText() ); } public function testGetRevisionParserOutput_old() { $title = $this->getMockTitle( 7, 21 ); + $rev = $this->getMockRevision( RevisionStoreRecord::class, $title, 11 ); - $rev = new MutableRevisionRecord( $title ); - $rev->setId( 11 ); // old! - $rev->setUser( new UserIdentityValue( 9, 'Frank', 0 ) ); - $rev->setTimestamp( '20180101000003' ); + $options = ParserOptions::newCanonical( 'canonical' ); + $rr = new RenderedRevision( $title, $rev, $options, $this->combinerCallback ); - $text = ""; - $text .= "* page:{{PAGENAME}}\n"; - $text .= "* rev:{{REVISIONID}}\n"; - $text .= "* user:{{REVISIONUSER}}\n"; - $text .= "* time:{{REVISIONTIMESTAMP}}\n"; + $this->assertFalse( $rr->isContentDeleted(), 'isContentDeleted' ); + + $this->assertSame( $rev, $rr->getRevision() ); + $this->assertSame( $options, $rr->getOptions() ); - $rev->setContent( 'main', new WikitextContent( $text ) ); + $html = $rr->getRevisionParserOutput()->getText(); + + $this->assertContains( 'page:RenderTestPage!', $html ); + $this->assertContains( 'rev:11!', $html ); + $this->assertContains( 'user:Frank!', $html ); + $this->assertContains( 'time:20180101000003!', $html ); + + $this->assertSame( $html, $rr->getSlotParserOutput( SlotRecord::MAIN )->getText() ); + } + + public function testGetRevisionParserOutput_archive() { + $title = $this->getMockTitle( 7, 21 ); + $rev = $this->getMockRevision( RevisionArchiveRecord::class, $title, 11 ); $options = ParserOptions::newCanonical( 'canonical' ); $rr = new RenderedRevision( $title, $rev, $options, $this->combinerCallback ); @@ -213,30 +281,22 @@ class RenderedRevisionTest extends MediaWikiTestCase { $html = $rr->getRevisionParserOutput()->getText(); - $this->assertContains( 'page:' . __CLASS__, $html ); - $this->assertContains( 'rev:11', $html ); - $this->assertContains( 'user:Frank', $html ); - $this->assertContains( 'time:20180101000003', $html ); + $this->assertContains( 'page:RenderTestPage!', $html ); + $this->assertContains( 'rev:11!', $html ); + $this->assertContains( 'user:Frank!', $html ); + $this->assertContains( 'time:20180101000003!', $html ); - $this->assertSame( $html, $rr->getSlotParserOutput( 'main' )->getText() ); + $this->assertSame( $html, $rr->getSlotParserOutput( SlotRecord::MAIN )->getText() ); } public function testGetRevisionParserOutput_suppressed() { $title = $this->getMockTitle( 7, 21 ); - - $rev = new MutableRevisionRecord( $title ); - $rev->setId( 11 ); // old! - $rev->setVisibility( RevisionRecord::DELETED_TEXT ); // suppressed! - $rev->setUser( new UserIdentityValue( 9, 'Frank', 0 ) ); - $rev->setTimestamp( '20180101000003' ); - - $text = ""; - $text .= "* page:{{PAGENAME}}\n"; - $text .= "* rev:{{REVISIONID}}\n"; - $text .= "* user:{{REVISIONUSER}}\n"; - $text .= "* time:{{REVISIONTIMESTAMP}}\n"; - - $rev->setContent( 'main', new WikitextContent( $text ) ); + $rev = $this->getMockRevision( + RevisionStoreRecord::class, + $title, + 11, + RevisionRecord::DELETED_TEXT + ); $options = ParserOptions::newCanonical( 'canonical' ); $rr = new RenderedRevision( $title, $rev, $options, $this->combinerCallback ); @@ -247,20 +307,12 @@ class RenderedRevisionTest extends MediaWikiTestCase { public function testGetRevisionParserOutput_privileged() { $title = $this->getMockTitle( 7, 21 ); - - $rev = new MutableRevisionRecord( $title ); - $rev->setId( 11 ); // old! - $rev->setVisibility( RevisionRecord::DELETED_TEXT ); // suppressed! - $rev->setUser( new UserIdentityValue( 9, 'Frank', 0 ) ); - $rev->setTimestamp( '20180101000003' ); - - $text = ""; - $text .= "* page:{{PAGENAME}}\n"; - $text .= "* rev:{{REVISIONID}}\n"; - $text .= "* user:{{REVISIONUSER}}\n"; - $text .= "* time:{{REVISIONTIMESTAMP}}\n"; - - $rev->setContent( 'main', new WikitextContent( $text ) ); + $rev = $this->getMockRevision( + RevisionStoreRecord::class, + $title, + 11, + RevisionRecord::DELETED_TEXT + ); $options = ParserOptions::newCanonical( 'canonical' ); $sysop = $this->getTestUser( [ 'sysop' ] )->getUser(); // privileged! @@ -281,30 +333,22 @@ class RenderedRevisionTest extends MediaWikiTestCase { $html = $rr->getRevisionParserOutput()->getText(); // Suppressed content should be visible for sysops - $this->assertContains( 'page:' . __CLASS__, $html ); - $this->assertContains( 'rev:11', $html ); - $this->assertContains( 'user:Frank', $html ); - $this->assertContains( 'time:20180101000003', $html ); + $this->assertContains( 'page:RenderTestPage!', $html ); + $this->assertContains( 'rev:11!', $html ); + $this->assertContains( 'user:Frank!', $html ); + $this->assertContains( 'time:20180101000003!', $html ); - $this->assertSame( $html, $rr->getSlotParserOutput( 'main' )->getText() ); + $this->assertSame( $html, $rr->getSlotParserOutput( SlotRecord::MAIN )->getText() ); } public function testGetRevisionParserOutput_raw() { $title = $this->getMockTitle( 7, 21 ); - - $rev = new MutableRevisionRecord( $title ); - $rev->setId( 11 ); // old! - $rev->setVisibility( RevisionRecord::DELETED_TEXT ); // suppressed! - $rev->setUser( new UserIdentityValue( 9, 'Frank', 0 ) ); - $rev->setTimestamp( '20180101000003' ); - - $text = ""; - $text .= "* page:{{PAGENAME}}\n"; - $text .= "* rev:{{REVISIONID}}\n"; - $text .= "* user:{{REVISIONUSER}}\n"; - $text .= "* time:{{REVISIONTIMESTAMP}}\n"; - - $rev->setContent( 'main', new WikitextContent( $text ) ); + $rev = $this->getMockRevision( + RevisionStoreRecord::class, + $title, + 11, + RevisionRecord::DELETED_TEXT + ); $options = ParserOptions::newCanonical( 'canonical' ); $rr = new RenderedRevision( @@ -323,29 +367,28 @@ class RenderedRevisionTest extends MediaWikiTestCase { $html = $rr->getRevisionParserOutput()->getText(); // Suppressed content should be visible for sysops - $this->assertContains( 'page:' . __CLASS__, $html ); - $this->assertContains( 'rev:11', $html ); - $this->assertContains( 'user:Frank', $html ); - $this->assertContains( 'time:20180101000003', $html ); + $this->assertContains( 'page:RenderTestPage!', $html ); + $this->assertContains( 'rev:11!', $html ); + $this->assertContains( 'user:Frank!', $html ); + $this->assertContains( 'time:20180101000003!', $html ); - $this->assertSame( $html, $rr->getSlotParserOutput( 'main' )->getText() ); + $this->assertSame( $html, $rr->getSlotParserOutput( SlotRecord::MAIN )->getText() ); } public function testGetRevisionParserOutput_multi() { - $title = $this->getMockTitle( 7, 21 ); + $content = [ + 'main' => new WikitextContent( '[[Kittens]]' ), + 'aux' => new WikitextContent( '[[Goats]]' ), + ]; - $rev = new MutableRevisionRecord( $title ); - $rev->setUser( new UserIdentityValue( 9, 'Frank', 0 ) ); - $rev->setTimestamp( '20180101000003' ); - - $rev->setContent( 'main', new WikitextContent( '[[Kittens]]' ) ); - $rev->setContent( 'aux', new WikitextContent( '[[Goats]]' ) ); + $title = $this->getMockTitle( 7, 21 ); + $rev = $this->getMockRevision( RevisionStoreRecord::class, $title, 11, 0, $content ); $options = ParserOptions::newCanonical( 'canonical' ); $rr = new RenderedRevision( $title, $rev, $options, $this->combinerCallback ); $combinedOutput = $rr->getRevisionParserOutput(); - $mainOutput = $rr->getSlotParserOutput( 'main' ); + $mainOutput = $rr->getSlotParserOutput( SlotRecord::MAIN ); $auxOutput = $rr->getSlotParserOutput( 'aux' ); $combinedHtml = $combinedOutput->getText(); @@ -369,6 +412,77 @@ class RenderedRevisionTest extends MediaWikiTestCase { $this->assertFalse( isset( $auxLinks[NS_MAIN]['Kittens'] ), 'no main links in aux' ); } + public function testGetRevisionParserOutput_incompleteNoId() { + $title = $this->getMockTitle( 7, 21 ); + + $rev = new MutableRevisionRecord( $title ); + + $text = ""; + $text .= "* page:{{PAGENAME}}!\n"; + $text .= "* rev:{{REVISIONID}}!\n"; + $text .= "* user:{{REVISIONUSER}}!\n"; + $text .= "* time:{{REVISIONTIMESTAMP}}!\n"; + + $rev->setContent( SlotRecord::MAIN, new WikitextContent( $text ) ); + + $options = ParserOptions::newCanonical( 'canonical' ); + $rr = new RenderedRevision( $title, $rev, $options, $this->combinerCallback ); + + // MutableRevisionRecord without ID should be used by the parser. + // USeful for fake + $html = $rr->getRevisionParserOutput()->getText(); + + $this->assertContains( 'page:RenderTestPage!', $html ); + $this->assertContains( 'rev:!', $html ); + $this->assertContains( 'user:!', $html ); + $this->assertContains( 'time:!', $html ); + } + + public function testGetRevisionParserOutput_incompleteWithId() { + $title = $this->getMockTitle( 7, 21 ); + + $rev = new MutableRevisionRecord( $title ); + $rev->setId( 21 ); + + $text = ""; + $text .= "* page:{{PAGENAME}}!\n"; + $text .= "* rev:{{REVISIONID}}!\n"; + $text .= "* user:{{REVISIONUSER}}!\n"; + $text .= "* time:{{REVISIONTIMESTAMP}}!\n"; + + $rev->setContent( SlotRecord::MAIN, new WikitextContent( $text ) ); + + $actualRevision = $this->getMockRevision( + RevisionStoreRecord::class, + $title, + 21, + RevisionRecord::DELETED_TEXT + ); + + $options = ParserOptions::newCanonical( 'canonical' ); + $rr = new RenderedRevision( $title, $rev, $options, $this->combinerCallback ); + + // MutableRevisionRecord with ID should not be used by the parser, + // revision should be loaded instead! + $revisionStore = $this->getMockBuilder( RevisionStore::class ) + ->disableOriginalConstructor() + ->getMock(); + + $revisionStore->expects( $this->once() ) + ->method( 'getKnownCurrentRevision' ) + ->with( $title, 0 ) + ->willReturn( $actualRevision ); + + $this->setService( 'RevisionStore', $revisionStore ); + + $html = $rr->getRevisionParserOutput()->getText(); + + $this->assertContains( 'page:RenderTestPage!', $html ); + $this->assertContains( 'rev:21!', $html ); + $this->assertContains( 'user:Frank!', $html ); + $this->assertContains( 'time:20180101000003!', $html ); + } + public function testNoHtml() { /** @var MockObject|Content $mockContent */ $mockContent = $this->getMockBuilder( WikitextContent::class ) @@ -390,13 +504,13 @@ class RenderedRevisionTest extends MediaWikiTestCase { $title = $this->getMockTitle( 7, 21 ); $rev = new MutableRevisionRecord( $title ); - $rev->setContent( 'main', $mockContent ); + $rev->setContent( SlotRecord::MAIN, $mockContent ); $rev->setContent( 'aux', $mockContent ); $options = ParserOptions::newCanonical( 'canonical' ); $rr = new RenderedRevision( $title, $rev, $options, $this->combinerCallback ); - $output = $rr->getSlotParserOutput( 'main', [ 'generate-html' => false ] ); + $output = $rr->getSlotParserOutput( SlotRecord::MAIN, [ 'generate-html' => false ] ); $this->assertFalse( $output->hasText(), 'hasText' ); $output = $rr->getRevisionParserOutput( [ 'generate-html' => false ] ); @@ -409,24 +523,24 @@ class RenderedRevisionTest extends MediaWikiTestCase { $rev = new MutableRevisionRecord( $title ); $text = ""; - $text .= "* page:{{PAGENAME}}\n"; - $text .= "* rev:{{REVISIONID}}\n"; - $text .= "* user:{{REVISIONUSER}}\n"; - $text .= "* time:{{REVISIONTIMESTAMP}}\n"; + $text .= "* page:{{PAGENAME}}!\n"; + $text .= "* rev:{{REVISIONID}}!\n"; + $text .= "* user:{{REVISIONUSER}}!\n"; + $text .= "* time:{{REVISIONTIMESTAMP}}!\n"; - $rev->setContent( 'main', new WikitextContent( $text ) ); + $rev->setContent( SlotRecord::MAIN, new WikitextContent( $text ) ); $rev->setContent( 'aux', new WikitextContent( '[[Goats]]' ) ); $options = ParserOptions::newCanonical( 'canonical' ); $rr = new RenderedRevision( $title, $rev, $options, $this->combinerCallback ); $firstOutput = $rr->getRevisionParserOutput(); - $mainOutput = $rr->getSlotParserOutput( 'main' ); + $mainOutput = $rr->getSlotParserOutput( SlotRecord::MAIN ); $auxOutput = $rr->getSlotParserOutput( 'aux' ); // emulate a saved revision $savedRev = new MutableRevisionRecord( $title ); - $savedRev->setContent( 'main', new WikitextContent( $text ) ); + $savedRev->setContent( SlotRecord::MAIN, new WikitextContent( $text ) ); $savedRev->setContent( 'aux', new WikitextContent( '[[Goats]]' ) ); $savedRev->setId( 23 ); // saved, new $savedRev->setUser( new UserIdentityValue( 9, 'Frank', 0 ) ); @@ -434,17 +548,17 @@ class RenderedRevisionTest extends MediaWikiTestCase { $rr->updateRevision( $savedRev ); - $this->assertNotSame( $mainOutput, $rr->getSlotParserOutput( 'main' ), 'Reset main' ); + $this->assertNotSame( $mainOutput, $rr->getSlotParserOutput( SlotRecord::MAIN ), 'Reset main' ); $this->assertSame( $auxOutput, $rr->getSlotParserOutput( 'aux' ), 'Keep aux' ); $updatedOutput = $rr->getRevisionParserOutput(); $html = $updatedOutput->getText(); $this->assertNotSame( $firstOutput, $updatedOutput, 'Reset merged' ); - $this->assertContains( 'page:' . __CLASS__, $html ); - $this->assertContains( 'rev:23', $html ); - $this->assertContains( 'user:Frank', $html ); - $this->assertContains( 'time:20180101000003', $html ); + $this->assertContains( 'page:RenderTestPage!', $html ); + $this->assertContains( 'rev:23!', $html ); + $this->assertContains( 'user:Frank!', $html ); + $this->assertContains( 'time:20180101000003!', $html ); $this->assertContains( 'Goats', $html ); $rr->updateRevision( $savedRev ); // should do nothing