Merge "RevisionStoreDbTestBase, remove redundant needsDB override"
[lhc/web/wiklou.git] / tests / phpunit / includes / Storage / MutableRevisionRecordTest.php
1 <?php
2
3 namespace MediaWiki\Tests\Storage;
4
5 use CommentStoreComment;
6 use InvalidArgumentException;
7 use MediaWiki\Storage\MutableRevisionRecord;
8 use MediaWiki\Storage\MutableRevisionSlots;
9 use MediaWiki\Storage\RevisionAccessException;
10 use MediaWiki\Storage\RevisionRecord;
11 use MediaWiki\Storage\RevisionSlotsUpdate;
12 use MediaWiki\Storage\SlotRecord;
13 use MediaWiki\User\UserIdentityValue;
14 use MediaWikiTestCase;
15 use TextContent;
16 use Title;
17 use User;
18 use WikitextContent;
19
20 /**
21 * @covers \MediaWiki\Storage\MutableRevisionRecord
22 * @covers \MediaWiki\Storage\RevisionRecord
23 */
24 class MutableRevisionRecordTest extends MediaWikiTestCase {
25
26 use RevisionRecordTests;
27
28 /**
29 * @param array $rowOverrides
30 *
31 * @return MutableRevisionRecord
32 */
33 protected function newRevision( array $rowOverrides = [] ) {
34 $title = Title::newFromText( 'Dummy' );
35 $title->resetArticleID( 17 );
36
37 $user = new UserIdentityValue( 11, 'Tester', 0 );
38 $comment = CommentStoreComment::newUnsavedComment( 'Hello World' );
39
40 $record = new MutableRevisionRecord( $title );
41
42 if ( isset( $rowOverrides['rev_deleted'] ) ) {
43 $record->setVisibility( $rowOverrides['rev_deleted'] );
44 }
45
46 if ( isset( $rowOverrides['rev_id'] ) ) {
47 $record->setId( $rowOverrides['rev_id'] );
48 }
49
50 if ( isset( $rowOverrides['rev_page'] ) ) {
51 $record->setPageId( $rowOverrides['rev_page'] );
52 }
53
54 $record->setContent( 'main', new TextContent( 'Lorem Ipsum' ) );
55 $record->setComment( $comment );
56 $record->setUser( $user );
57 $record->setTimestamp( '20101010000000' );
58
59 return $record;
60 }
61
62 public function provideConstructor() {
63 $title = Title::newFromText( 'Dummy' );
64 $title->resetArticleID( 17 );
65
66 yield [
67 $title,
68 'acmewiki'
69 ];
70 }
71
72 /**
73 * @dataProvider provideConstructor
74 *
75 * @param Title $title
76 * @param bool $wikiId
77 */
78 public function testConstructorAndGetters(
79 Title $title,
80 $wikiId = false
81 ) {
82 $rec = new MutableRevisionRecord( $title, $wikiId );
83
84 $this->assertSame( $title, $rec->getPageAsLinkTarget(), 'getPageAsLinkTarget' );
85 $this->assertSame( $wikiId, $rec->getWikiId(), 'getWikiId' );
86 }
87
88 public function provideConstructorFailure() {
89 $title = Title::newFromText( 'Dummy' );
90 $title->resetArticleID( 17 );
91
92 yield 'not a wiki id' => [
93 $title,
94 null
95 ];
96 }
97
98 /**
99 * @dataProvider provideConstructorFailure
100 *
101 * @param Title $title
102 * @param bool $wikiId
103 */
104 public function testConstructorFailure(
105 Title $title,
106 $wikiId = false
107 ) {
108 $this->setExpectedException( InvalidArgumentException::class );
109 new MutableRevisionRecord( $title, $wikiId );
110 }
111
112 public function testSetGetId() {
113 $record = new MutableRevisionRecord( Title::newFromText( 'Foo' ) );
114 $this->assertNull( $record->getId() );
115 $record->setId( 888 );
116 $this->assertSame( 888, $record->getId() );
117 }
118
119 public function testSetGetUser() {
120 $record = new MutableRevisionRecord( Title::newFromText( 'Foo' ) );
121 $user = $this->getTestSysop()->getUser();
122 $this->assertNull( $record->getUser() );
123 $record->setUser( $user );
124 $this->assertSame( $user, $record->getUser() );
125 }
126
127 public function testSetGetPageId() {
128 $record = new MutableRevisionRecord( Title::newFromText( 'Foo' ) );
129 $this->assertSame( 0, $record->getPageId() );
130 $record->setPageId( 999 );
131 $this->assertSame( 999, $record->getPageId() );
132 }
133
134 public function testSetGetParentId() {
135 $record = new MutableRevisionRecord( Title::newFromText( 'Foo' ) );
136 $this->assertNull( $record->getParentId() );
137 $record->setParentId( 100 );
138 $this->assertSame( 100, $record->getParentId() );
139 }
140
141 public function testGetMainContentWhenEmpty() {
142 $record = new MutableRevisionRecord( Title::newFromText( 'Foo' ) );
143 $this->setExpectedException( RevisionAccessException::class );
144 $this->assertNull( $record->getContent( 'main' ) );
145 }
146
147 public function testSetGetMainContent() {
148 $record = new MutableRevisionRecord( Title::newFromText( 'Foo' ) );
149 $content = new WikitextContent( 'Badger' );
150 $record->setContent( 'main', $content );
151 $this->assertSame( $content, $record->getContent( 'main' ) );
152 }
153
154 public function testGetSlotWhenEmpty() {
155 $record = new MutableRevisionRecord( Title::newFromText( 'Foo' ) );
156 $this->assertFalse( $record->hasSlot( 'main' ) );
157
158 $this->setExpectedException( RevisionAccessException::class );
159 $record->getSlot( 'main' );
160 }
161
162 public function testSetGetSlot() {
163 $record = new MutableRevisionRecord( Title::newFromText( 'Foo' ) );
164 $slot = SlotRecord::newUnsaved(
165 'main',
166 new WikitextContent( 'x' )
167 );
168 $record->setSlot( $slot );
169 $this->assertTrue( $record->hasSlot( 'main' ) );
170 $this->assertSame( $slot, $record->getSlot( 'main' ) );
171 }
172
173 public function testSetGetMinor() {
174 $record = new MutableRevisionRecord( Title::newFromText( 'Foo' ) );
175 $this->assertFalse( $record->isMinor() );
176 $record->setMinorEdit( true );
177 $this->assertSame( true, $record->isMinor() );
178 }
179
180 public function testSetGetTimestamp() {
181 $record = new MutableRevisionRecord( Title::newFromText( 'Foo' ) );
182 $this->assertNull( $record->getTimestamp() );
183 $record->setTimestamp( '20180101010101' );
184 $this->assertSame( '20180101010101', $record->getTimestamp() );
185 }
186
187 public function testSetGetVisibility() {
188 $record = new MutableRevisionRecord( Title::newFromText( 'Foo' ) );
189 $this->assertSame( 0, $record->getVisibility() );
190 $record->setVisibility( RevisionRecord::DELETED_USER );
191 $this->assertSame( RevisionRecord::DELETED_USER, $record->getVisibility() );
192 }
193
194 public function testSetGetSha1() {
195 $record = new MutableRevisionRecord( Title::newFromText( 'Foo' ) );
196 $this->assertSame( 'phoiac9h4m842xq45sp7s6u21eteeq1', $record->getSha1() );
197 $record->setSha1( 'someHash' );
198 $this->assertSame( 'someHash', $record->getSha1() );
199 }
200
201 public function testGetSlots() {
202 $record = new MutableRevisionRecord( Title::newFromText( 'Foo' ) );
203 $this->assertInstanceOf( MutableRevisionSlots::class, $record->getSlots() );
204 }
205
206 public function testSetGetSize() {
207 $record = new MutableRevisionRecord( Title::newFromText( 'Foo' ) );
208 $this->assertSame( 0, $record->getSize() );
209 $record->setSize( 775 );
210 $this->assertSame( 775, $record->getSize() );
211 }
212
213 public function testSetGetComment() {
214 $record = new MutableRevisionRecord( Title::newFromText( 'Foo' ) );
215 $comment = new CommentStoreComment( 1, 'foo' );
216 $this->assertNull( $record->getComment() );
217 $record->setComment( $comment );
218 $this->assertSame( $comment, $record->getComment() );
219 }
220
221 public function testSimpleGetOriginalAndInheritedSlots() {
222 $record = new MutableRevisionRecord( Title::newFromText( 'Foo' ) );
223 $mainSlot = new SlotRecord(
224 (object)[
225 'slot_id' => 1,
226 'slot_revision_id' => null, // unsaved
227 'slot_content_id' => 1,
228 'content_address' => null, // touched
229 'model_name' => 'x',
230 'role_name' => 'main',
231 'slot_origin' => null // touched
232 ],
233 new WikitextContent( 'main' )
234 );
235 $auxSlot = new SlotRecord(
236 (object)[
237 'slot_id' => 2,
238 'slot_revision_id' => null, // unsaved
239 'slot_content_id' => 1,
240 'content_address' => 'foo', // inherited
241 'model_name' => 'x',
242 'role_name' => 'aux',
243 'slot_origin' => 1 // inherited
244 ],
245 new WikitextContent( 'aux' )
246 );
247
248 $record->setSlot( $mainSlot );
249 $record->setSlot( $auxSlot );
250
251 $this->assertSame( [ 'main' ], $record->getOriginalSlots()->getSlotRoles() );
252 $this->assertSame( $mainSlot, $record->getOriginalSlots()->getSlot( 'main' ) );
253
254 $this->assertSame( [ 'aux' ], $record->getInheritedSlots()->getSlotRoles() );
255 $this->assertSame( $auxSlot, $record->getInheritedSlots()->getSlot( 'aux' ) );
256 }
257
258 public function testSimpleremoveSlot() {
259 $record = new MutableRevisionRecord( Title::newFromText( 'Foo' ) );
260
261 $a = new WikitextContent( 'a' );
262 $b = new WikitextContent( 'b' );
263
264 $record->inheritSlot( SlotRecord::newSaved( 7, 3, 'a', SlotRecord::newUnsaved( 'a', $a ) ) );
265 $record->inheritSlot( SlotRecord::newSaved( 7, 4, 'b', SlotRecord::newUnsaved( 'b', $b ) ) );
266
267 $record->removeSlot( 'b' );
268
269 $this->assertTrue( $record->hasSlot( 'a' ) );
270 $this->assertFalse( $record->hasSlot( 'b' ) );
271 }
272
273 public function testApplyUpdate() {
274 $update = new RevisionSlotsUpdate();
275
276 $a = new WikitextContent( 'a' );
277 $b = new WikitextContent( 'b' );
278 $c = new WikitextContent( 'c' );
279 $x = new WikitextContent( 'x' );
280
281 $update->modifyContent( 'b', $x );
282 $update->modifyContent( 'c', $x );
283 $update->removeSlot( 'c' );
284 $update->removeSlot( 'd' );
285
286 $record = new MutableRevisionRecord( Title::newFromText( 'Foo' ) );
287 $record->inheritSlot( SlotRecord::newSaved( 7, 3, 'a', SlotRecord::newUnsaved( 'a', $a ) ) );
288 $record->inheritSlot( SlotRecord::newSaved( 7, 4, 'b', SlotRecord::newUnsaved( 'b', $b ) ) );
289 $record->inheritSlot( SlotRecord::newSaved( 7, 5, 'c', SlotRecord::newUnsaved( 'c', $c ) ) );
290
291 $record->applyUpdate( $update );
292
293 $this->assertEquals( [ 'b' ], array_keys( $record->getOriginalSlots()->getSlots() ) );
294 $this->assertEquals( $a, $record->getSlot( 'a' )->getContent() );
295 $this->assertEquals( $x, $record->getSlot( 'b' )->getContent() );
296 $this->assertFalse( $record->hasSlot( 'c' ) );
297 }
298
299 public function provideNotReadyForInsertion() {
300 /** @var Title $title */
301 $title = $this->getMock( Title::class );
302
303 /** @var User $user */
304 $user = $this->getMock( User::class );
305
306 /** @var CommentStoreComment $comment */
307 $comment = $this->getMockBuilder( CommentStoreComment::class )
308 ->disableOriginalConstructor()
309 ->getMock();
310
311 $content = new TextContent( 'Test' );
312
313 $rev = new MutableRevisionRecord( $title );
314 yield 'empty' => [ $rev ];
315
316 $rev = new MutableRevisionRecord( $title );
317 $rev->setContent( 'main', $content );
318 $rev->setUser( $user );
319 $rev->setComment( $comment );
320 yield 'no timestamp' => [ $rev ];
321
322 $rev = new MutableRevisionRecord( $title );
323 $rev->setUser( $user );
324 $rev->setComment( $comment );
325 $rev->setTimestamp( '20101010000000' );
326 yield 'no content' => [ $rev ];
327
328 $rev = new MutableRevisionRecord( $title );
329 $rev->setContent( 'main', $content );
330 $rev->setComment( $comment );
331 $rev->setTimestamp( '20101010000000' );
332 yield 'no user' => [ $rev ];
333
334 $rev = new MutableRevisionRecord( $title );
335 $rev->setUser( $user );
336 $rev->setContent( 'main', $content );
337 $rev->setTimestamp( '20101010000000' );
338 yield 'no comment' => [ $rev ];
339 }
340
341 /**
342 * @dataProvider provideNotReadyForInsertion
343 */
344 public function testNotReadyForInsertion( $rev ) {
345 $this->assertFalse( $rev->isReadyForInsertion() );
346 }
347 }