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