3 namespace MediaWiki\Tests\Storage
;
5 use CommentStoreComment
;
6 use InvalidArgumentException
;
7 use MediaWiki\Storage\RevisionRecord
;
8 use MediaWiki\Storage\RevisionSlots
;
9 use MediaWiki\Storage\RevisionStoreRecord
;
10 use MediaWiki\Storage\SlotRecord
;
11 use MediaWiki\User\UserIdentity
;
12 use MediaWiki\User\UserIdentityValue
;
13 use MediaWikiTestCase
;
18 * @covers \MediaWiki\Storage\RevisionStoreRecord
19 * @covers \MediaWiki\Storage\RevisionRecord
21 class RevisionStoreRecordTest
extends MediaWikiTestCase
{
23 use RevisionRecordTests
;
26 * @param array $rowOverrides
28 * @return RevisionStoreRecord
30 protected function newRevision( array $rowOverrides = [] ) {
31 $title = Title
::newFromText( 'Dummy' );
32 $title->resetArticleID( 17 );
34 $user = new UserIdentityValue( 11, 'Tester', 0 );
35 $comment = CommentStoreComment
::newUnsavedComment( 'Hello World' );
37 $main = SlotRecord
::newUnsaved( 'main', new TextContent( 'Lorem Ipsum' ) );
38 $aux = SlotRecord
::newUnsaved( 'aux', new TextContent( 'Frumious Bandersnatch' ) );
39 $slots = new RevisionSlots( [ $main, $aux ] );
43 'rev_page' => strval( $title->getArticleID() ),
44 'rev_timestamp' => '20200101000000',
46 'rev_minor_edit' => 0,
47 'rev_parent_id' => '5',
48 'rev_len' => $slots->computeSize(),
49 'rev_sha1' => $slots->computeSha1(),
50 'page_latest' => '18',
53 $row = array_merge( $row, $rowOverrides );
55 return new RevisionStoreRecord( $title, $user, $comment, (object)$row, $slots );
58 public function provideConstructor() {
59 $title = Title
::newFromText( 'Dummy' );
60 $title->resetArticleID( 17 );
62 $user = new UserIdentityValue( 11, 'Tester', 0 );
63 $comment = CommentStoreComment
::newUnsavedComment( 'Hello World' );
65 $main = SlotRecord
::newUnsaved( 'main', new TextContent( 'Lorem Ipsum' ) );
66 $aux = SlotRecord
::newUnsaved( 'aux', new TextContent( 'Frumious Bandersnatch' ) );
67 $slots = new RevisionSlots( [ $main, $aux ] );
71 'rev_page' => strval( $title->getArticleID() ),
72 'rev_timestamp' => '20200101000000',
74 'rev_minor_edit' => 0,
75 'rev_parent_id' => '5',
76 'rev_len' => $slots->computeSize(),
77 'rev_sha1' => $slots->computeSha1(),
78 'page_latest' => '18',
92 $row['rev_minor_edit'] = '1';
93 $row['rev_deleted'] = strval( RevisionRecord
::DELETED_USER
);
95 yield
'minor deleted' => [
104 $row['page_latest'] = $row['rev_id'];
115 unset( $row['rev_parent'] );
117 yield
'no parent' => [
126 $row['rev_len'] = null;
127 $row['rev_sha1'] = '';
129 yield
'rev_len is null, rev_sha1 is ""' => [
138 yield
'no length, no hash' => [
139 Title
::newFromText( 'DummyDoesNotExist' ),
148 * @dataProvider provideConstructor
150 * @param Title $title
151 * @param UserIdentity $user
152 * @param CommentStoreComment $comment
154 * @param RevisionSlots $slots
155 * @param bool $wikiId
157 public function testConstructorAndGetters(
160 CommentStoreComment
$comment,
162 RevisionSlots
$slots,
165 $rec = new RevisionStoreRecord( $title, $user, $comment, $row, $slots, $wikiId );
167 $this->assertSame( $title, $rec->getPageAsLinkTarget(), 'getPageAsLinkTarget' );
168 $this->assertSame( $user, $rec->getUser( RevisionRecord
::RAW
), 'getUser' );
169 $this->assertSame( $comment, $rec->getComment(), 'getComment' );
171 $this->assertSame( $slots, $rec->getSlots(), 'getSlots' );
172 $this->assertSame( $slots->getSlotRoles(), $rec->getSlotRoles(), 'getSlotRoles' );
173 $this->assertSame( $slots->getSlots(), $rec->getSlots()->getSlots(), 'getSlots' );
174 $this->assertSame( $wikiId, $rec->getWikiId(), 'getWikiId' );
176 $this->assertSame( (int)$row->rev_id
, $rec->getId(), 'getId' );
177 $this->assertSame( (int)$row->rev_page
, $rec->getPageId(), 'getId' );
178 $this->assertSame( $row->rev_timestamp
, $rec->getTimestamp(), 'getTimestamp' );
179 $this->assertSame( (int)$row->rev_deleted
, $rec->getVisibility(), 'getVisibility' );
180 $this->assertSame( (bool)$row->rev_minor_edit
, $rec->isMinor(), 'getIsMinor' );
182 if ( isset( $row->rev_parent_id
) ) {
183 $this->assertSame( (int)$row->rev_parent_id
, $rec->getParentId(), 'getParentId' );
185 $this->assertSame( 0, $rec->getParentId(), 'getParentId' );
188 if ( isset( $row->rev_len
) ) {
189 $this->assertSame( (int)$row->rev_len
, $rec->getSize(), 'getSize' );
191 $this->assertSame( $slots->computeSize(), $rec->getSize(), 'getSize' );
194 if ( !empty( $row->rev_sha1
) ) {
195 $this->assertSame( $row->rev_sha1
, $rec->getSha1(), 'getSha1' );
197 $this->assertSame( $slots->computeSha1(), $rec->getSha1(), 'getSha1' );
200 if ( isset( $row->page_latest
) ) {
202 (int)$row->rev_id
=== (int)$row->page_latest
,
215 public function provideConstructorFailure() {
216 $title = Title
::newFromText( 'Dummy' );
217 $title->resetArticleID( 17 );
219 $user = new UserIdentityValue( 11, 'Tester', 0 );
221 $comment = CommentStoreComment
::newUnsavedComment( 'Hello World' );
223 $main = SlotRecord
::newUnsaved( 'main', new TextContent( 'Lorem Ipsum' ) );
224 $aux = SlotRecord
::newUnsaved( 'aux', new TextContent( 'Frumious Bandersnatch' ) );
225 $slots = new RevisionSlots( [ $main, $aux ] );
229 'rev_page' => strval( $title->getArticleID() ),
230 'rev_timestamp' => '20200101000000',
232 'rev_minor_edit' => 0,
233 'rev_parent_id' => '5',
234 'rev_len' => $slots->computeSize(),
235 'rev_sha1' => $slots->computeSha1(),
236 'page_latest' => '18',
239 yield
'not a row' => [
249 $row['rev_timestamp'] = 'kittens';
251 yield
'bad timestamp' => [
260 $row['rev_page'] = 99;
262 yield
'page ID mismatch' => [
272 yield
'bad wiki' => [
283 * @dataProvider provideConstructorFailure
285 * @param Title $title
286 * @param UserIdentity $user
287 * @param CommentStoreComment $comment
289 * @param RevisionSlots $slots
290 * @param bool $wikiId
292 public function testConstructorFailure(
295 CommentStoreComment
$comment,
297 RevisionSlots
$slots,
300 $this->setExpectedException( InvalidArgumentException
::class );
301 new RevisionStoreRecord( $title, $user, $comment, $row, $slots, $wikiId );
304 public function provideIsCurrent() {
322 * @dataProvider provideIsCurrent
324 public function testIsCurrent( $row, $current ) {
325 $rev = $this->newRevision( $row );
327 $this->assertSame( $current, $rev->isCurrent(), 'isCurrent()' );
330 public function provideGetSlot_audience_latest() {
331 return $this->provideAudienceCheckData( RevisionRecord
::DELETED_TEXT
);
335 * @dataProvider provideGetSlot_audience_latest
337 public function testGetSlot_audience_latest( $visibility, $groups, $userCan, $publicCan ) {
338 $this->forceStandardPermissions();
340 $user = $this->getTestUser( $groups )->getUser();
341 $rev = $this->newRevision(
343 'rev_deleted' => $visibility,
345 'page_latest' => 11, // revision is current
349 // NOTE: slot meta-data is never suppressed, just the content is!
350 $this->assertNotNull( $rev->getSlot( 'main', RevisionRecord
::RAW
), 'raw can' );
351 $this->assertNotNull( $rev->getSlot( 'main', RevisionRecord
::FOR_PUBLIC
), 'public can' );
353 $this->assertNotNull(
354 $rev->getSlot( 'main', RevisionRecord
::FOR_THIS_USER
, $user ),
358 $rev->getSlot( 'main', RevisionRecord
::RAW
)->getContent();
359 // NOTE: the content of the current revision is never suppressed!
360 // Check that getContent() doesn't throw SuppressedDataException
361 $rev->getSlot( 'main', RevisionRecord
::FOR_PUBLIC
)->getContent();
362 $rev->getSlot( 'main', RevisionRecord
::FOR_THIS_USER
, $user )->getContent();