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