23 parent::__construct(
$name,
$data, $dataName );
25 $this->tablesUsed = array_merge( $this->tablesUsed,
72 12313 =>
'Dummy_talk',
77 'wgNamespaceContentModels',
99 if ( !$this->testPage ) {
104 $this->testPage = $this->
createPage( __CLASS__, __CLASS__ );
114 ->disableOriginalConstructor()
116 $mock->expects( $this->
any() )
117 ->method(
'getNamespace' )
119 $mock->expects( $this->
any() )
120 ->method(
'getPrefixedText' )
121 ->will( $this->returnValue( __CLASS__ ) );
122 $mock->expects( $this->
any() )
123 ->method(
'getDBkey' )
124 ->will( $this->returnValue( __CLASS__ ) );
125 $mock->expects( $this->
any() )
126 ->method(
'getArticleID' )
127 ->will( $this->returnValue( 23 ) );
135 if ( $props ===
null ) {
139 if ( !isset( $props[
'content'] ) && !isset( $props[
'text'] ) ) {
140 $props[
'text'] =
'Lorem Ipsum';
143 if ( !isset( $props[
'user_text'] ) ) {
145 $props[
'user_text'] =
$user->getName();
146 $props[
'user'] =
$user->getId();
149 if ( !isset( $props[
'user'] ) ) {
153 if ( !isset( $props[
'comment'] ) ) {
154 $props[
'comment'] =
'just a test';
157 if ( !isset( $props[
'page'] ) ) {
158 $props[
'page'] = $this->testPage->getId();
161 if ( !isset( $props[
'content_model'] ) ) {
168 $rev->insertOn( $dbw );
180 private function createPage( $titleString, $text, $model =
null ) {
181 if ( !preg_match(
'/:/', $titleString ) &&
192 if ( $wikipage->exists() ) {
193 $wikipage->doDeleteArticle(
"done" );
203 $this->assertNotNull(
$rev,
'missing revision' );
205 $this->assertEquals( $orig->
getId(),
$rev->getId() );
206 $this->assertEquals( $orig->
getPage(),
$rev->getPage() );
208 $this->assertEquals( $orig->
getUser(),
$rev->getUser() );
211 $this->assertEquals( $orig->
getSha1(),
$rev->getSha1() );
218 $rev = $this->testPage->getRevision();
219 $recentChange =
$rev->getRecentChange();
222 $this->assertEquals(
$rev->getTimestamp(), $recentChange->getAttribute(
'rc_timestamp' ) );
224 $rev->getTitle()->getNamespace(),
225 $recentChange->getAttribute(
'rc_namespace' )
228 $rev->getTitle()->getDBkey(),
229 $recentChange->getAttribute(
'rc_title' )
231 $this->assertEquals(
$rev->getUser(), $recentChange->getAttribute(
'rc_user' ) );
232 $this->assertEquals(
$rev->getUserText(), $recentChange->getAttribute(
'rc_user_text' ) );
233 $this->assertEquals(
$rev->getComment(), $recentChange->getAttribute(
'rc_comment' ) );
234 $this->assertEquals(
$rev->getPage(), $recentChange->getAttribute(
'rc_cur_id' ) );
235 $this->assertEquals(
$rev->getId(), $recentChange->getAttribute(
'rc_this_oldid' ) );
242 $parentId = $this->testPage->getLatest();
248 'page' => $this->testPage->getId(),
249 'title' => $this->testPage->getTitle(),
250 'text' =>
'Revision Text',
251 'comment' =>
'Revision comment',
256 $this->assertInternalType(
'integer', $revId );
257 $this->assertSame( $revId,
$rev->getId() );
260 $this->assertInternalType(
'integer',
$rev->getTextId() );
262 $mainSlot =
$rev->getRevisionRecord()->getSlot( SlotRecord::MAIN, RevisionRecord::RAW );
265 $textId = MediaWikiServices::getInstance()
267 ->getTextIdFromAddress( $mainSlot->getAddress() );
271 [
'old_id',
'old_text' ],
273 [ [ strval( $textId ),
'Revision Text' ] ]
286 "rev_id = {$rev->getId()}",
288 strval(
$rev->getId() ),
289 strval( $this->testPage->getId() ),
294 's0ngbdoxagreuf2vjtuxzwdz64n29xm',
303 yield
'no parent' => [
310 "rev_page field must not be 0!"
313 yield
'no comment' => [
320 "comment must not be NULL!"
323 yield
'no content' => [
330 "Uninitialized field: content_address"
341 $this->setExpectedException( $expException, $expMessage );
353 $latestRevId = $this->testPage->getLatest();
357 $this->assertTrue( $this->testPage->getTitle()->equals(
$rev->getTitle() ) );
358 $this->assertEquals( $latestRevId,
$rev->getId() );
365 $latestRevId = $this->testPage->getLatest();
369 $this->assertTrue( $this->testPage->getTitle()->equals(
$rev->getTitle() ) );
370 $this->assertEquals( $latestRevId,
$rev->getId() );
377 $latestRevId = $this->testPage->getLatest();
381 $this->assertNull(
$rev );
394 $this->assertTrue( is_object(
$res ),
'query failed' );
396 $row =
$res->fetchObject();
412 return $f + [
'ar_namespace',
'ar_title' ];
417 unset(
$f[
'ar_text_id'] );
423 unset(
$f[
'ar_page_id'] );
429 unset(
$f[
'ar_parent_id'] );
435 unset(
$f[
'ar_rev_id'] );
441 unset(
$f[
'ar_sha1'] );
452 $services = MediaWikiServices::getInstance();
456 $services->getService(
'_SqlBlobStore' ),
470 'RevisionStorageTest_testNewFromArchiveRow',
474 $orig = $page->getRevision();
475 $page->doDeleteArticle(
'test Revision::newFromArchiveRow' );
479 $arQuery[
'fields'] = $selectModifier( $arQuery[
'fields'] );
481 $arQuery[
'tables'], $arQuery[
'fields'], [
'ar_rev_id' => $orig->getId() ],
482 __METHOD__, [], $arQuery[
'joins']
484 $this->assertTrue( is_object(
$res ),
'query failed' );
486 $row =
$res->fetchObject();
501 'RevisionStorageTest_testNewFromArchiveRow',
505 $orig = $page->getRevision();
506 $page->doDeleteArticle(
'test Revision::newFromArchiveRow' );
511 $arQuery[
'tables'], $arQuery[
'fields'], [
'ar_rev_id' => $orig->getId() ],
512 __METHOD__, [], $arQuery[
'joins']
514 $this->assertTrue( is_object(
$res ),
'query failed' );
516 $row =
$res->fetchObject();
521 $this->assertNotEquals( $orig->getComment(),
$rev->getComment() );
522 $this->assertEquals(
'SOMEOVERRIDE',
$rev->getComment() );
529 $orig = $this->testPage->getRevision();
540 $this->testPage->getRevision(),
550 $this->testPage->getId(),
551 $this->testPage->getLatest()
554 $this->testPage->getRevision(),
564 $this->testPage->doEditContent(
$content, __METHOD__ );
566 $this->testPage->getId(),
567 $this->testPage->getRevision()->getPrevious()->getId()
570 $this->testPage->getRevision()->getPrevious(),
584 $this->assertEquals( $page->getId(),
$rev->getPage() );
591 $rev1 = $this->testPage->getRevision();
593 # @todo find out if this should be true
594 # $this->assertTrue( $rev1->isCurrent() );
597 $this->assertTrue( $rev1x->isCurrent() );
599 $this->testPage->doEditContent(
new WikitextContent( __METHOD__ ), __METHOD__ );
600 $rev2 = $this->testPage->getRevision();
602 # @todo find out if this should be true
603 # $this->assertTrue( $rev2->isCurrent() );
606 $this->assertFalse( $rev1x->isCurrent() );
609 $this->assertTrue( $rev2x->isCurrent() );
616 $oldestRevision = $this->testPage->getOldestRevision();
617 $latestRevision = $this->testPage->getLatest();
619 $this->assertNull( $oldestRevision->getPrevious() );
621 $this->testPage->doEditContent(
new WikitextContent( __METHOD__ ), __METHOD__ );
622 $newRevision = $this->testPage->getRevision();
624 $this->assertNotNull( $newRevision->getPrevious() );
625 $this->assertEquals( $latestRevision, $newRevision->getPrevious()->getId() );
632 $rev1 = $this->testPage->getRevision();
634 $this->assertNull( $rev1->getNext() );
636 $this->testPage->doEditContent(
new WikitextContent( __METHOD__ ), __METHOD__ );
637 $rev2 = $this->testPage->getRevision();
639 $this->assertNotNull( $rev1->getNext() );
640 $this->assertEquals( $rev2->getId(), $rev1->getNext()->getId() );
647 $this->testPage->doEditContent(
new WikitextContent( __METHOD__ ), __METHOD__ );
648 $orig = $this->testPage->getRevision();
653 $this->assertNotEquals( $orig->getId(),
$rev->getId(),
654 'new null revision should have a different id from the original revision' );
655 $this->assertEquals( $orig->getTextId(),
$rev->getTextId(),
656 'new null revision should have the same text id as the original revision' );
657 $this->assertEquals( $orig->getSha1(),
$rev->getSha1(),
658 'new null revision should have the same SHA1 as the original revision' );
659 $this->assertTrue( $orig->getRevisionRecord()->hasSameContent(
$rev->getRevisionRecord() ),
660 'new null revision should have the same content as the original revision' );
661 $this->assertEquals( __METHOD__,
$rev->getContent()->getText() );
671 $this->assertNull(
$rev );
678 $ip =
'2600:387:ed7:947e:8c16:a1ad:dd34:1dd7';
686 $res =
$dbr->select(
'ip_changes',
'*', [
'ipc_rev_id' => $orig->getId() ] );
687 $row =
$res->fetchObject();
689 $this->assertEquals(
IP::toHex( $ip ), $row->ipc_hex );
691 $orig->getTimestamp(),
697 yield
'actually the last edit' => [ 3,
true ];
698 yield
'not the current edit, but still by this user' => [ 2,
true ];
699 yield
'edit by another user' => [ 1,
false ];
700 yield
'first edit, by this user, but another user edited in the mean time' => [ 0,
false ];
711 if ( $userA->getId() === 0 ) {
715 if ( $userB->getId() === 0 ) {
726 'RevisionStorageTest_testUserWasLastToEdit', $ns ) );
727 $page->insertOn( $dbw );
730 'page' => $page->getId(),
732 'title' => $page->getTitle(),
733 'timestamp' =>
'20120101000000',
734 'user' => $userA->getId(),
737 'comment' =>
'edit zero'
742 'page' => $page->getId(),
744 'title' => $page->getTitle(),
745 'timestamp' =>
'20120101000100',
746 'user' => $userA->getId(),
749 'comment' =>
'edit one'
754 'page' => $page->getId(),
755 'title' => $page->getTitle(),
756 'timestamp' =>
'20120101000200',
757 'user' => $userB->getId(),
760 'comment' =>
'edit two'
765 'page' => $page->getId(),
766 'title' => $page->getTitle(),
767 'timestamp' =>
'20120101000300',
768 'user' => $userA->getId(),
771 'comment' =>
'edit three'
776 'page' => $page->getId(),
777 'title' => $page->getTitle(),
778 'timestamp' =>
'20120101000200',
779 'user' => $userA->getId(),
782 'comment' =>
'edit four'
787 $since = $revisions[$sinceIdx]->getTimestamp();
790 $allRows = iterator_to_array( $dbw->select(
792 [
'rev_id',
'rev_timestamp',
'rev_user' =>
$revQuery[
'fields'][
'rev_user'] ],
794 'rev_page' => $page->getId(),
798 [
'ORDER BY' =>
'rev_timestamp ASC',
'LIMIT' => 50 ],
804 $this->assertEquals( $expectedLast, $wasLast );
818 if ( is_string(
$title ) ) {
832 'comment' =>
"testing",
833 'minor_edit' =>
false,
835 'content_format' => $format,
858 $this->assertEquals( $expectedModel,
$rev->getContentModel() );
878 $this->assertEquals( $expectedFormat,
$rev->getContentFormat() );
897 $this->assertEquals( $expectedClass, get_class(
$rev->getContentHandler() ) );
928 $audience, $expectedSerialization
934 $expectedSerialization,
944 'page' => $this->testPage->getId(),
945 'content_model' => $this->testPage->getContentModel(),
949 Wikimedia\suppressWarnings();
951 $this->assertNull(
$rev->getContent(),
952 "getContent() should return null if the revision's text blob could not be loaded." );
955 $this->assertNull(
$rev->getContent(),
956 "getContent() should return null if the revision's text blob could not be loaded." );
958 Wikimedia\restoreWarnings();
974 $this->assertEquals( $expected_size,
$rev->getSize() );
994 $this->assertEquals( $expected_hash,
$rev->getSha1() );
1013 'comment' =>
"testing",
1014 'minor_edit' =>
false,
1025 $this->assertNotSame(
$content, $content2,
"expected a clone" );
1027 $this->assertEquals(
"foo", $content2->getText() );
1029 $content2->setText(
"bla bla" );
1031 $this->assertEquals(
"bar",
$content->getText() );
1044 $this->assertSame(
$content, $content2 );
1051 $rev = $this->testPage->getRevision();
1064 $this->testPage->getRevision(),
1074 $this->testPage->getRevision(),
1077 $this->testPage->getId(),
1078 $this->testPage->getLatest()
1087 $this->testPage->doEditContent(
new WikitextContent( __METHOD__ ), __METHOD__ );
1089 $this->testPage->getRevision()->getPrevious(),
1092 $this->testPage->getId(),
1093 $this->testPage->getRevision()->getPrevious()->getId()
1103 $this->testPage->getRevision(),
1113 $this->testPage->getRevision(),
1116 $this->testPage->getTitle(),
1117 $this->testPage->getLatest()
1126 $this->testPage->doEditContent(
new WikitextContent( __METHOD__ ), __METHOD__ );
1128 $this->testPage->getRevision()->getPrevious(),
1131 $this->testPage->getTitle(),
1132 $this->testPage->getRevision()->getPrevious()->getId()
1142 $this->testPage->getRevision(),
1145 $this->testPage->getTitle(),
1146 $this->testPage->getRevision()->getTimestamp()
1168 $text =
'831jr091jr0921kr21kr0921kjr0921j09rj1';
1169 $textLength = strlen( $text );
1171 $this->testPage->doEditContent(
new WikitextContent( $text ), __METHOD__ );
1172 $rev[1] = $this->testPage->getLatest();
1175 [
$rev[1] => $textLength ],
1187 $textOne =
'831jr091jr0921kr21kr0921kjr0921j09rj1';
1188 $textOneLength = strlen( $textOne );
1189 $textTwo =
'831jr091jr092121j09rj1';
1190 $textTwoLength = strlen( $textTwo );
1192 $this->testPage->doEditContent(
new WikitextContent( $textOne ), __METHOD__ );
1193 $rev[1] = $this->testPage->getLatest();
1194 $this->testPage->doEditContent(
new WikitextContent( $textTwo ), __METHOD__ );
1195 $rev[2] = $this->testPage->getLatest();
1198 [
$rev[1] => $textOneLength,
$rev[2] => $textTwoLength ],
1211 $this->testPage->getTitle()->equals(
1212 $this->testPage->getRevision()->getTitle()
1221 $rev =
new Revision( [
'id' => $this->testPage->getLatest() ] );
1223 $this->testPage->getTitle()->equals(
1236 $this->testPage->doEditContent(
1243 $rev = $this->testPage->getRevision();
1245 $this->assertSame(
true,
$rev->isMinor() );
1252 $this->testPage->doEditContent(
1257 $rev = $this->testPage->getRevision();
1259 $this->assertSame(
false,
$rev->isMinor() );
1268 $this->testPage->doEditContent(
1272 $rev = $this->testPage->getRevision();
1274 $this->assertInternalType(
'string',
$rev->getTimestamp() );
1275 $this->assertTrue( strlen(
$rev->getTimestamp() ) == strlen(
'YYYYMMDDHHMMSS' ) );
1276 $this->assertContains( substr( $testTimestamp, 0, 10 ),
$rev->getTimestamp() );
1286 $this->testPage->doEditContent(
1293 $rev = $this->testPage->getRevision();
1295 $this->assertSame( $sysop->getId(),
$rev->getUser() );
1296 $this->assertSame( $sysop->getName(),
$rev->getUserText() );
1303 $rev = $this->testPage->getRevision();
1315 $rev = $this->testPage->getRevision();
1317 $this->assertSame( 0,
$rev->getVisibility() );
1324 $expectedSummary =
'goatlicious summary';
1326 $this->testPage->doEditContent(
1330 $rev = $this->testPage->getRevision();
1332 $this->assertSame( $expectedSummary,
$rev->getComment() );
1339 $this->testPage->doEditContent(
new WikitextContent( __METHOD__ ), __METHOD__ );
1340 $rev = $this->testPage->getRevision();
1342 $this->assertGreaterThan( 0,
$rev->isUnpatrolled() );
1343 $this->assertSame(
$rev->getRecentChange()->getAttribute(
'rc_id' ),
$rev->isUnpatrolled() );
1352 $this->testPage->doEditContent(
1359 $rev = $this->testPage->getRevision();
1361 $this->assertSame( 0,
$rev->isUnpatrolled() );
1374 $expectedText =
'testSimpleContentGetters in Revision. Goats love MCR...';
1375 $expectedSummary =
'goatlicious testSimpleContentGetters summary';
1377 $this->testPage->doEditContent(
1381 $rev = $this->testPage->getRevision();
1383 $this->assertSame( $expectedText,
$rev->getContent()->getText() );
1384 $this->assertSame( $expectedText,
$rev->getSerializedData() );
1385 $this->assertSame( $this->testPage->getContentModel(),
$rev->getContentModel() );
1386 $this->assertSame( $this->testPage->getContent()->getDefaultFormat(),
$rev->getContentFormat() );
1387 $this->assertSame( $this->testPage->getContentHandler(),
$rev->getContentHandler() );
1401 $cache->setMockTime( $now );
1404 $this->testPage->doEditContent(
new WikitextContent( __METHOD__ ), __METHOD__ );
1405 $rev = $this->testPage->getRevision();
1408 $key =
$cache->makeGlobalKey(
1409 RevisionStore::ROW_CACHE_KEY,
1415 $this->assertFalse(
$cache->get( $key ) );
1423 $cachedRow =
$cache->get( $key );
1424 $this->assertNotFalse( $cachedRow );
1425 $this->assertEquals(
$rev->getId(), $cachedRow->rev_id );
1431 $this->testPage->doEditContent(
new WikitextContent( __METHOD__ ), __METHOD__ );
1432 $rev = $this->testPage->getRevision();
1434 $pageId = $this->testPage->getId();
1447 yield [ 0, 0, [],
null,
true ];
1486 'wgGroupPermissions',
1489 'deletedtext' =>
true,
1490 'deletedhistory' =>
true,
1493 'viewsuppressed' =>
true,
1494 'suppressrevision' =>
true,
1517 yield [ 0, 0, [],
true ];
1537 public function testUserCan( $bitField, $field, $userGroups, $expected ) {
1539 'wgGroupPermissions',
1542 'deletedtext' =>
true,
1543 'deletedhistory' =>
true,
1546 'viewsuppressed' =>
true,
1547 'suppressrevision' =>
true,
1552 $revision =
new Revision( [
'deleted' => $bitField ], 0, $this->testPage->getTitle() );
1556 $revision->userCan( $field,
$user )
1564 'slot_revision_id' => 42,
1565 'slot_content_id' => 1,
1566 'content_address' =>
'tt:789',
1568 'role_name' => SlotRecord::MAIN,
1574 $rec->setSlot( $slot );
1576 yield [ $rec, 789 ];
1584 $rev =
new Revision( $spec, 0, $this->testPage->getTitle() );
1585 $this->assertSame( $expected,
$rev->getTextId() );
1599 $rev = $this->testPage->getRevisionRecord();
1602 $queryInfo[
'tables'] = array_merge( $queryInfo[
'tables'], $queryInfoExtra[
'tables'] ?? [] );
1603 $queryInfo[
'fields'] = array_merge( $queryInfo[
'fields'], $queryInfoExtra[
'fields'] ?? [] );
1604 $queryInfo[
'joins'] = array_merge( $queryInfo[
'joins'], $queryInfoExtra[
'joins'] ?? [] );
1606 $conds = [
'rev_id' =>
$rev->getId() ];
1607 $row = $this->db->selectRow(
1608 $queryInfo[
'tables'],
1609 $queryInfo[
'fields'],
1616 $expected =
$rev->getContent( SlotRecord::MAIN )->serialize();
1618 $this->
hideDeprecated(
'Revision::getRevisionText (MCR without SCHEMA_COMPAT_WRITE_OLD)' );