MediaWiki REL1_31
RevisionTest.php
Go to the documentation of this file.
1<?php
2
13
19
20 public function provideConstructFromArray() {
21 yield 'with text' => [
22 [
23 'text' => 'hello world.',
24 'content_model' => CONTENT_MODEL_JAVASCRIPT
25 ],
26 ];
27 yield 'with content' => [
28 [
29 'content' => new JavaScriptContent( 'hellow world.' )
30 ],
31 ];
32 // FIXME: test with and without user ID, and with a user object.
33 // We can't prepare that here though, since we don't yet have a dummy DB
34 }
35
40 public function getMockTitle( $model = CONTENT_MODEL_WIKITEXT ) {
41 $mock = $this->getMockBuilder( Title::class )
42 ->disableOriginalConstructor()
43 ->getMock();
44 $mock->expects( $this->any() )
45 ->method( 'getNamespace' )
46 ->will( $this->returnValue( $this->getDefaultWikitextNS() ) );
47 $mock->expects( $this->any() )
48 ->method( 'getPrefixedText' )
49 ->will( $this->returnValue( 'RevisionTest' ) );
50 $mock->expects( $this->any() )
51 ->method( 'getDBkey' )
52 ->will( $this->returnValue( 'RevisionTest' ) );
53 $mock->expects( $this->any() )
54 ->method( 'getArticleID' )
55 ->will( $this->returnValue( 23 ) );
56 $mock->expects( $this->any() )
57 ->method( 'getContentModel' )
58 ->will( $this->returnValue( $model ) );
59
60 return $mock;
61 }
62
68 public function testConstructFromArray( $rowArray ) {
69 $rev = new Revision( $rowArray, 0, $this->getMockTitle() );
70 $this->assertNotNull( $rev->getContent(), 'no content object available' );
71 $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContent()->getModel() );
72 $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContentModel() );
73 }
74
79 public function testConstructFromEmptyArray() {
80 $rev = new Revision( [], 0, $this->getMockTitle() );
81 $this->assertNull( $rev->getContent(), 'no content object should be available' );
82 }
83
89 Wikimedia\suppressWarnings();
90 $rev = new Revision( [ 'page' => 77777777 ] );
91 $this->assertSame( 77777777, $rev->getPage() );
92 Wikimedia\restoreWarnings();
93 }
94
96 yield 'no user defaults to wgUser' => [
97 [
98 'content' => new JavaScriptContent( 'hello world.' ),
99 ],
100 null,
101 null,
102 ];
103 yield 'user text and id' => [
104 [
105 'content' => new JavaScriptContent( 'hello world.' ),
106 'user_text' => 'SomeTextUserName',
107 'user' => 99,
108
109 ],
110 99,
111 'SomeTextUserName',
112 ];
113 yield 'user text only' => [
114 [
115 'content' => new JavaScriptContent( 'hello world.' ),
116 'user_text' => '111.111.111.111',
117 ],
118 0,
119 '111.111.111.111',
120 ];
121 }
122
133 array $rowArray,
134 $expectedUserId,
135 $expectedUserName
136 ) {
137 $testUser = $this->getTestUser()->getUser();
138 $this->setMwGlobals( 'wgUser', $testUser );
139 if ( $expectedUserId === null ) {
140 $expectedUserId = $testUser->getId();
141 }
142 if ( $expectedUserName === null ) {
143 $expectedUserName = $testUser->getName();
144 }
145
146 $rev = new Revision( $rowArray, 0, $this->getMockTitle() );
147 $this->assertEquals( $expectedUserId, $rev->getUser() );
148 $this->assertEquals( $expectedUserName, $rev->getUserText() );
149 }
150
152 yield 'content and text_id both not empty' => [
153 [
154 'content' => new WikitextContent( 'GOAT' ),
155 'text_id' => 'someid',
156 ],
157 new MWException( "Text already stored in external store (id someid), " .
158 "can't serialize content object" )
159 ];
160 yield 'with bad content object (class)' => [
161 [ 'content' => new stdClass() ],
162 new MWException( 'content field must contain a Content object.' )
163 ];
164 yield 'with bad content object (string)' => [
165 [ 'content' => 'ImAGoat' ],
166 new MWException( 'content field must contain a Content object.' )
167 ];
168 yield 'bad row format' => [
169 'imastring, not a row',
170 new InvalidArgumentException(
171 '$row must be a row object, an associative array, or a RevisionRecord'
172 )
173 ];
174 }
175
181 public function testConstructFromArrayThrowsExceptions( $rowArray, Exception $expectedException ) {
182 $this->setExpectedException(
183 get_class( $expectedException ),
184 $expectedException->getMessage(),
185 $expectedException->getCode()
186 );
187 new Revision( $rowArray, 0, $this->getMockTitle() );
188 }
189
194 public function testConstructFromNothing() {
195 $this->setExpectedException(
196 InvalidArgumentException::class
197 );
198 new Revision( [] );
199 }
200
201 public function provideConstructFromRow() {
202 yield 'Full construction' => [
203 [
204 'rev_id' => '42',
205 'rev_page' => '23',
206 'rev_text_id' => '2',
207 'rev_timestamp' => '20171017114835',
208 'rev_user_text' => '127.0.0.1',
209 'rev_user' => '0',
210 'rev_minor_edit' => '0',
211 'rev_deleted' => '0',
212 'rev_len' => '46',
213 'rev_parent_id' => '1',
214 'rev_sha1' => 'rdqbbzs3pkhihgbs8qf2q9jsvheag5z',
215 'rev_comment_text' => 'Goat Comment!',
216 'rev_comment_data' => null,
217 'rev_comment_cid' => null,
218 'rev_content_format' => 'GOATFORMAT',
219 'rev_content_model' => 'GOATMODEL',
220 ],
221 function ( RevisionTest $testCase, Revision $rev ) {
222 $testCase->assertSame( 42, $rev->getId() );
223 $testCase->assertSame( 23, $rev->getPage() );
224 $testCase->assertSame( 2, $rev->getTextId() );
225 $testCase->assertSame( '20171017114835', $rev->getTimestamp() );
226 $testCase->assertSame( '127.0.0.1', $rev->getUserText() );
227 $testCase->assertSame( 0, $rev->getUser() );
228 $testCase->assertSame( false, $rev->isMinor() );
229 $testCase->assertSame( false, $rev->isDeleted( Revision::DELETED_TEXT ) );
230 $testCase->assertSame( 46, $rev->getSize() );
231 $testCase->assertSame( 1, $rev->getParentId() );
232 $testCase->assertSame( 'rdqbbzs3pkhihgbs8qf2q9jsvheag5z', $rev->getSha1() );
233 $testCase->assertSame( 'Goat Comment!', $rev->getComment() );
234 $testCase->assertSame( 'GOATFORMAT', $rev->getContentFormat() );
235 $testCase->assertSame( 'GOATMODEL', $rev->getContentModel() );
236 }
237 ];
238 yield 'default field values' => [
239 [
240 'rev_id' => '42',
241 'rev_page' => '23',
242 'rev_text_id' => '2',
243 'rev_timestamp' => '20171017114835',
244 'rev_user_text' => '127.0.0.1',
245 'rev_user' => '0',
246 'rev_minor_edit' => '0',
247 'rev_deleted' => '0',
248 'rev_comment_text' => 'Goat Comment!',
249 'rev_comment_data' => null,
250 'rev_comment_cid' => null,
251 ],
252 function ( RevisionTest $testCase, Revision $rev ) {
253 // parent ID may be null
254 $testCase->assertSame( null, $rev->getParentId(), 'revision id' );
255
256 // given fields
257 $testCase->assertSame( $rev->getTimestamp(), '20171017114835', 'timestamp' );
258 $testCase->assertSame( $rev->getUserText(), '127.0.0.1', 'user name' );
259 $testCase->assertSame( $rev->getUser(), 0, 'user id' );
260 $testCase->assertSame( $rev->getComment(), 'Goat Comment!' );
261 $testCase->assertSame( false, $rev->isMinor(), 'minor edit' );
262 $testCase->assertSame( 0, $rev->getVisibility(), 'visibility flags' );
263
264 // computed fields
265 $testCase->assertNotNull( $rev->getSize(), 'size' );
266 $testCase->assertNotNull( $rev->getSha1(), 'hash' );
267
268 // NOTE: model and format will be detected based on the namespace of the (mock) title
269 $testCase->assertSame( 'text/x-wiki', $rev->getContentFormat(), 'format' );
270 $testCase->assertSame( 'wikitext', $rev->getContentModel(), 'model' );
271 }
272 ];
273 }
274
280 public function testConstructFromRow( array $arrayData, $assertions ) {
281 $data = 'Hello goat.'; // needs to match model and format
282
283 $blobStore = $this->getMockBuilder( SqlBlobStore::class )
284 ->disableOriginalConstructor()
285 ->getMock();
286
287 $blobStore->method( 'getBlob' )
288 ->will( $this->returnValue( $data ) );
289
290 $blobStore->method( 'getTextIdFromAddress' )
291 ->will( $this->returnCallback(
292 function ( $address ) {
293 // Turn "tt:1234" into 12345.
294 // Note that this must be functional so we can test getTextId().
295 // Ideally, we'd un-mock getTextIdFromAddress and use its actual implementation.
296 $parts = explode( ':', $address );
297 return (int)array_pop( $parts );
298 }
299 ) );
300
301 // Note override internal service, so RevisionStore uses it as well.
302 $this->setService( 'BlobStoreFactory', $this->mockBlobStoreFactory( $blobStore ) );
303
304 $row = (object)$arrayData;
305 $rev = new Revision( $row, 0, $this->getMockTitle() );
306 $assertions( $this, $rev );
307 }
308
314 $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', MIGRATION_OLD );
315 $this->overrideMwServices();
316 Wikimedia\suppressWarnings();
317 $rev = new Revision( (object)[ 'rev_page' => 77777777 ] );
318 $this->assertSame( 77777777, $rev->getPage() );
319 Wikimedia\restoreWarnings();
320 }
321
322 public function provideGetRevisionText() {
323 yield 'Generic test' => [
324 'This is a goat of revision text.',
325 [
326 'old_flags' => '',
327 'old_text' => 'This is a goat of revision text.',
328 ],
329 ];
330 }
331
332 public function provideGetId() {
333 yield [
334 [],
335 null
336 ];
337 yield [
338 [ 'id' => 998 ],
339 998
340 ];
341 }
342
347 public function testGetId( $rowArray, $expectedId ) {
348 $rev = new Revision( $rowArray, 0, $this->getMockTitle() );
349 $this->assertEquals( $expectedId, $rev->getId() );
350 }
351
352 public function provideSetId() {
353 yield [ '123', 123 ];
354 yield [ 456, 456 ];
355 }
356
361 public function testSetId( $input, $expected ) {
362 $rev = new Revision( [], 0, $this->getMockTitle() );
363 $rev->setId( $input );
364 $this->assertSame( $expected, $rev->getId() );
365 }
366
367 public function provideSetUserIdAndName() {
368 yield [ '123', 123, 'GOaT' ];
369 yield [ 456, 456, 'GOaT' ];
370 }
371
376 public function testSetUserIdAndName( $inputId, $expectedId, $name ) {
377 $rev = new Revision( [], 0, $this->getMockTitle() );
378 $rev->setUserIdAndName( $inputId, $name );
379 $this->assertSame( $expectedId, $rev->getUser( Revision::RAW ) );
380 $this->assertEquals( $name, $rev->getUserText( Revision::RAW ) );
381 }
382
383 public function provideGetTextId() {
384 yield [ [], null ];
385 yield [ [ 'text_id' => '123' ], 123 ];
386 yield [ [ 'text_id' => 456 ], 456 ];
387 }
388
393 public function testGetTextId( $rowArray, $expected ) {
394 $rev = new Revision( $rowArray, 0, $this->getMockTitle() );
395 $this->assertSame( $expected, $rev->getTextId() );
396 }
397
398 public function provideGetParentId() {
399 yield [ [], null ];
400 yield [ [ 'parent_id' => '123' ], 123 ];
401 yield [ [ 'parent_id' => 456 ], 456 ];
402 }
403
408 public function testGetParentId( $rowArray, $expected ) {
409 $rev = new Revision( $rowArray, 0, $this->getMockTitle() );
410 $this->assertSame( $expected, $rev->getParentId() );
411 }
412
417 public function testGetRevisionText( $expected, $rowData, $prefix = 'old_', $wiki = false ) {
418 $this->assertEquals(
419 $expected,
420 Revision::getRevisionText( (object)$rowData, $prefix, $wiki ) );
421 }
422
424 yield 'Generic gzip test' => [
425 'This is a small goat of revision text.',
426 [
427 'old_flags' => 'gzip',
428 'old_text' => gzdeflate( 'This is a small goat of revision text.' ),
429 ],
430 ];
431 }
432
437 public function testGetRevisionWithZlibExtension( $expected, $rowData ) {
438 $this->checkPHPExtension( 'zlib' );
439 $this->testGetRevisionText( $expected, $rowData );
440 }
441
442 private function getWANObjectCache() {
443 return new WANObjectCache( [ 'cache' => new HashBagOStuff() ] );
444 }
445
449 private function getBlobStore() {
451 $lb = $this->getMockBuilder( LoadBalancer::class )
452 ->disableOriginalConstructor()
453 ->getMock();
454
455 $cache = $this->getWANObjectCache();
456
457 $blobStore = new SqlBlobStore( $lb, $cache );
458 return $blobStore;
459 }
460
461 private function mockBlobStoreFactory( $blobStore ) {
463 $factory = $this->getMockBuilder( BlobStoreFactory::class )
464 ->disableOriginalConstructor()
465 ->getMock();
466 $factory->expects( $this->any() )
467 ->method( 'newBlobStore' )
468 ->willReturn( $blobStore );
469 $factory->expects( $this->any() )
470 ->method( 'newSqlBlobStore' )
471 ->willReturn( $blobStore );
472 return $factory;
473 }
474
478 private function getRevisionStore() {
480 $lb = $this->getMockBuilder( LoadBalancer::class )
481 ->disableOriginalConstructor()
482 ->getMock();
483
484 $cache = $this->getWANObjectCache();
485
486 $blobStore = new RevisionStore(
487 $lb,
488 $this->getBlobStore(),
489 $cache,
490 MediaWikiServices::getInstance()->getCommentStore(),
491 MediaWikiServices::getInstance()->getActorMigration()
492 );
493 return $blobStore;
494 }
495
497 yield 'Utf8Native' => [
498 "Wiki est l'\xc3\xa9cole superieur !",
499 'fr',
500 'iso-8859-1',
501 [
502 'old_flags' => 'utf-8',
503 'old_text' => "Wiki est l'\xc3\xa9cole superieur !",
504 ]
505 ];
506 yield 'Utf8Legacy' => [
507 "Wiki est l'\xc3\xa9cole superieur !",
508 'fr',
509 'iso-8859-1',
510 [
511 'old_flags' => '',
512 'old_text' => "Wiki est l'\xe9cole superieur !",
513 ]
514 ];
515 }
516
521 public function testGetRevisionWithLegacyEncoding( $expected, $lang, $encoding, $rowData ) {
522 $blobStore = $this->getBlobStore();
523 $blobStore->setLegacyEncoding( $encoding, Language::factory( $lang ) );
524 $this->setService( 'BlobStoreFactory', $this->mockBlobStoreFactory( $blobStore ) );
525
526 $this->testGetRevisionText( $expected, $rowData );
527 }
528
535 yield 'Utf8NativeGzip' => [
536 "Wiki est l'\xc3\xa9cole superieur !",
537 'fr',
538 'iso-8859-1',
539 [
540 'old_flags' => 'gzip,utf-8',
541 'old_text' => gzdeflate( "Wiki est l'\xc3\xa9cole superieur !" ),
542 ]
543 ];
544 yield 'Utf8LegacyGzip' => [
545 "Wiki est l'\xc3\xa9cole superieur !",
546 'fr',
547 'iso-8859-1',
548 [
549 'old_flags' => 'gzip',
550 'old_text' => gzdeflate( "Wiki est l'\xe9cole superieur !" ),
551 ]
552 ];
553 }
554
559 public function testGetRevisionWithGzipAndLegacyEncoding( $expected, $lang, $encoding, $rowData ) {
560 $this->checkPHPExtension( 'zlib' );
561
562 $blobStore = $this->getBlobStore();
563 $blobStore->setLegacyEncoding( $encoding, Language::factory( $lang ) );
564 $this->setService( 'BlobStoreFactory', $this->mockBlobStoreFactory( $blobStore ) );
565
566 $this->testGetRevisionText( $expected, $rowData );
567 }
568
573 $row = new stdClass;
574 $row->old_text = "Wiki est l'\xc3\xa9cole superieur !";
575 $row->old_flags = Revision::compressRevisionText( $row->old_text );
576 $this->assertTrue( false !== strpos( $row->old_flags, 'utf-8' ),
577 "Flags should contain 'utf-8'" );
578 $this->assertFalse( false !== strpos( $row->old_flags, 'gzip' ),
579 "Flags should not contain 'gzip'" );
580 $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !",
581 $row->old_text, "Direct check" );
582 $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !",
583 Revision::getRevisionText( $row ), "getRevisionText" );
584 }
585
590 $this->checkPHPExtension( 'zlib' );
591
592 $blobStore = $this->getBlobStore();
593 $blobStore->setCompressBlobs( true );
594 $this->setService( 'BlobStoreFactory', $this->mockBlobStoreFactory( $blobStore ) );
595
596 $row = new stdClass;
597 $row->old_text = "Wiki est l'\xc3\xa9cole superieur !";
598 $row->old_flags = Revision::compressRevisionText( $row->old_text );
599 $this->assertTrue( false !== strpos( $row->old_flags, 'utf-8' ),
600 "Flags should contain 'utf-8'" );
601 $this->assertTrue( false !== strpos( $row->old_flags, 'gzip' ),
602 "Flags should contain 'gzip'" );
603 $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !",
604 gzinflate( $row->old_text ), "Direct check" );
605 $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !",
606 Revision::getRevisionText( $row ), "getRevisionText" );
607 }
608
612 public function testLoadFromTitle() {
613 $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', MIGRATION_OLD );
614 $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', MIGRATION_OLD );
615 $this->overrideMwServices();
616 $title = $this->getMockTitle();
617
618 $conditions = [
619 'rev_id=page_latest',
620 'page_namespace' => $title->getNamespace(),
621 'page_title' => $title->getDBkey()
622 ];
623
624 $row = (object)[
625 'rev_id' => '42',
626 'rev_page' => $title->getArticleID(),
627 'rev_text_id' => '2',
628 'rev_timestamp' => '20171017114835',
629 'rev_user_text' => '127.0.0.1',
630 'rev_user' => '0',
631 'rev_minor_edit' => '0',
632 'rev_deleted' => '0',
633 'rev_len' => '46',
634 'rev_parent_id' => '1',
635 'rev_sha1' => 'rdqbbzs3pkhihgbs8qf2q9jsvheag5z',
636 'rev_comment_text' => 'Goat Comment!',
637 'rev_comment_data' => null,
638 'rev_comment_cid' => null,
639 'rev_content_format' => 'GOATFORMAT',
640 'rev_content_model' => 'GOATMODEL',
641 ];
642
643 $db = $this->getMock( IDatabase::class );
644 $db->expects( $this->any() )
645 ->method( 'getDomainId' )
646 ->will( $this->returnValue( wfWikiID() ) );
647 $db->expects( $this->once() )
648 ->method( 'selectRow' )
649 ->with(
650 $this->equalTo( [ 'revision', 'page', 'user' ] ),
651 // We don't really care about the fields are they come from the selectField methods
652 $this->isType( 'array' ),
653 $this->equalTo( $conditions ),
654 // Method name
655 $this->stringContains( 'fetchRevisionRowFromConds' ),
656 // We don't really care about the options here
657 $this->isType( 'array' ),
658 // We don't really care about the join conds are they come from the joinCond methods
659 $this->isType( 'array' )
660 )
661 ->willReturn( $row );
662
663 $revision = Revision::loadFromTitle( $db, $title );
664
665 $this->assertEquals( $title->getArticleID(), $revision->getTitle()->getArticleID() );
666 $this->assertEquals( $row->rev_id, $revision->getId() );
667 $this->assertEquals( $row->rev_len, $revision->getSize() );
668 $this->assertEquals( $row->rev_sha1, $revision->getSha1() );
669 $this->assertEquals( $row->rev_parent_id, $revision->getParentId() );
670 $this->assertEquals( $row->rev_timestamp, $revision->getTimestamp() );
671 $this->assertEquals( $row->rev_comment_text, $revision->getComment() );
672 $this->assertEquals( $row->rev_user_text, $revision->getUserText() );
673 }
674
676 yield '(no legacy encoding), false in false out' => [ false, false, [], false ];
677 yield '(no legacy encoding), empty in empty out' => [ false, '', [], '' ];
678 yield '(no legacy encoding), empty in empty out' => [ false, 'A', [], 'A' ];
679 yield '(no legacy encoding), string in with gzip flag returns string' => [
680 // gzip string below generated with gzdeflate( 'AAAABBAAA' )
681 false, "sttttr\002\022\000", [ 'gzip' ], 'AAAABBAAA',
682 ];
683 yield '(no legacy encoding), string in with object flag returns false' => [
684 // gzip string below generated with serialize( 'JOJO' )
685 false, "s:4:\"JOJO\";", [ 'object' ], false,
686 ];
687 yield '(no legacy encoding), serialized object in with object flag returns string' => [
688 false,
689 // Using a TitleValue object as it has a getText method (which is needed)
690 serialize( new TitleValue( 0, 'HHJJDDFF' ) ),
691 [ 'object' ],
692 'HHJJDDFF',
693 ];
694 yield '(no legacy encoding), serialized object in with object & gzip flag returns string' => [
695 false,
696 // Using a TitleValue object as it has a getText method (which is needed)
697 gzdeflate( serialize( new TitleValue( 0, '8219JJJ840' ) ) ),
698 [ 'object', 'gzip' ],
699 '8219JJJ840',
700 ];
701 yield '(ISO-8859-1 encoding), string in string out' => [
702 'ISO-8859-1',
703 iconv( 'utf-8', 'ISO-8859-1', "1®Àþ1" ),
704 [],
705 '1®Àþ1',
706 ];
707 yield '(ISO-8859-1 encoding), serialized object in with gzip flags returns string' => [
708 'ISO-8859-1',
709 gzdeflate( iconv( 'utf-8', 'ISO-8859-1', "4®Àþ4" ) ),
710 [ 'gzip' ],
711 '4®Àþ4',
712 ];
713 yield '(ISO-8859-1 encoding), serialized object in with object flags returns string' => [
714 'ISO-8859-1',
715 serialize( new TitleValue( 0, iconv( 'utf-8', 'ISO-8859-1', "3®Àþ3" ) ) ),
716 [ 'object' ],
717 '3®Àþ3',
718 ];
719 yield '(ISO-8859-1 encoding), serialized object in with object & gzip flags returns string' => [
720 'ISO-8859-1',
721 gzdeflate( serialize( new TitleValue( 0, iconv( 'utf-8', 'ISO-8859-1', "2®Àþ2" ) ) ) ),
722 [ 'gzip', 'object' ],
723 '2®Àþ2',
724 ];
725 }
726
736 public function testDecompressRevisionText( $legacyEncoding, $text, $flags, $expected ) {
737 $blobStore = $this->getBlobStore();
738 if ( $legacyEncoding ) {
739 $blobStore->setLegacyEncoding( $legacyEncoding, Language::factory( 'en' ) );
740 }
741
742 $this->setService( 'BlobStoreFactory', $this->mockBlobStoreFactory( $blobStore ) );
743 $this->assertSame(
744 $expected,
745 Revision::decompressRevisionText( $text, $flags )
746 );
747 }
748
753 $this->assertFalse( Revision::getRevisionText( new stdClass() ) );
754 }
755
757 yield 'Just text' => [
758 (object)[ 'old_text' => 'SomeText' ],
759 'old_',
760 'SomeText'
761 ];
762 // gzip string below generated with gzdeflate( 'AAAABBAAA' )
763 yield 'gzip text' => [
764 (object)[
765 'old_text' => "sttttr\002\022\000",
766 'old_flags' => 'gzip'
767 ],
768 'old_',
769 'AAAABBAAA'
770 ];
771 yield 'gzip text and different prefix' => [
772 (object)[
773 'jojo_text' => "sttttr\002\022\000",
774 'jojo_flags' => 'gzip'
775 ],
776 'jojo_',
777 'AAAABBAAA'
778 ];
779 }
780
786 $row,
787 $prefix,
788 $expected
789 ) {
790 $this->assertSame( $expected, Revision::getRevisionText( $row, $prefix ) );
791 }
792
794 yield 'Just some text' => [ 'someNonUrlText' ];
795 yield 'No second URL part' => [ 'someProtocol://' ];
796 }
797
803 $text
804 ) {
805 $this->assertFalse(
806 Revision::getRevisionText(
807 (object)[
808 'old_text' => $text,
809 'old_flags' => 'external',
810 ]
811 )
812 );
813 }
814
819 $this->setService(
820 'ExternalStoreFactory',
821 new ExternalStoreFactory( [ 'ForTesting' ] )
822 );
823 $this->assertSame(
824 'AAAABBAAA',
825 Revision::getRevisionText(
826 (object)[
827 'old_text' => 'ForTesting://cluster1/12345',
828 'old_flags' => 'external,gzip',
829 ]
830 )
831 );
832 }
833
838 $cache = $this->getWANObjectCache();
839 $this->setService( 'MainWANObjectCache', $cache );
840
841 $this->setService(
842 'ExternalStoreFactory',
843 new ExternalStoreFactory( [ 'ForTesting' ] )
844 );
845
846 $lb = $this->getMockBuilder( LoadBalancer::class )
847 ->disableOriginalConstructor()
848 ->getMock();
849
850 $blobStore = new SqlBlobStore( $lb, $cache );
851 $this->setService( 'BlobStoreFactory', $this->mockBlobStoreFactory( $blobStore ) );
852
853 $this->assertSame(
854 'AAAABBAAA',
855 Revision::getRevisionText(
856 (object)[
857 'old_text' => 'ForTesting://cluster1/12345',
858 'old_flags' => 'external,gzip',
859 'old_id' => '7777',
860 ]
861 )
862 );
863
864 $cacheKey = $cache->makeKey( 'revisiontext', 'textid', 'tt:7777' );
865 $this->assertSame( 'AAAABBAAA', $cache->get( $cacheKey ) );
866 }
867
871 public function testUserJoinCond() {
872 $this->hideDeprecated( 'Revision::userJoinCond' );
873 $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', MIGRATION_OLD );
874 $this->overrideMwServices();
875 $this->assertEquals(
876 [ 'LEFT JOIN', [ 'rev_user != 0', 'user_id = rev_user' ] ],
877 Revision::userJoinCond()
878 );
879 }
880
884 public function testPageJoinCond() {
885 $this->hideDeprecated( 'Revision::pageJoinCond' );
886 $this->assertEquals(
887 [ 'INNER JOIN', [ 'page_id = rev_page' ] ],
888 Revision::pageJoinCond()
889 );
890 }
891
893 $mockStore = $this->getMockBuilder( CommentStore::class )
894 ->disableOriginalConstructor()
895 ->getMock();
896 $mockStore->expects( $this->any() )
897 ->method( 'getFields' )
898 ->willReturn( [ 'commentstore' => 'fields' ] );
899 $mockStore->expects( $this->any() )
900 ->method( 'getJoin' )
901 ->willReturn( [
902 'tables' => [ 'commentstore' => 'table' ],
903 'fields' => [ 'commentstore' => 'field' ],
904 'joins' => [ 'commentstore' => 'join' ],
905 ] );
906 $this->setService( 'CommentStore', $mockStore );
907
908 $mockStore = $this->getMockBuilder( ActorMigration::class )
909 ->disableOriginalConstructor()
910 ->getMock();
911 $mockStore->expects( $this->any() )
912 ->method( 'getJoin' )
913 ->willReturnCallback( function ( $key ) {
914 $p = strtok( $key, '_' );
915 return [
916 'tables' => [ 'actormigration' => 'table' ],
917 'fields' => [
918 $p . '_user' => 'actormigration_user',
919 $p . '_user_text' => 'actormigration_user_text',
920 $p . '_actor' => 'actormigration_actor',
921 ],
922 'joins' => [ 'actormigration' => 'join' ],
923 ];
924 } );
925 $this->setService( 'ActorMigration', $mockStore );
926 }
927
928 public function provideSelectFields() {
929 yield [
930 true,
931 [
932 'rev_id',
933 'rev_page',
934 'rev_text_id',
935 'rev_timestamp',
936 'rev_user_text',
937 'rev_user',
938 'rev_actor' => 'NULL',
939 'rev_minor_edit',
940 'rev_deleted',
941 'rev_len',
942 'rev_parent_id',
943 'rev_sha1',
944 'commentstore' => 'fields',
945 'rev_content_format',
946 'rev_content_model',
947 ]
948 ];
949 yield [
950 false,
951 [
952 'rev_id',
953 'rev_page',
954 'rev_text_id',
955 'rev_timestamp',
956 'rev_user_text',
957 'rev_user',
958 'rev_actor' => 'NULL',
959 'rev_minor_edit',
960 'rev_deleted',
961 'rev_len',
962 'rev_parent_id',
963 'rev_sha1',
964 'commentstore' => 'fields',
965 ]
966 ];
967 }
968
973 public function testSelectFields( $contentHandlerUseDB, $expected ) {
974 $this->hideDeprecated( 'Revision::selectFields' );
975 $this->setMwGlobals( 'wgContentHandlerUseDB', $contentHandlerUseDB );
976 $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', MIGRATION_OLD );
978 $this->assertEquals( $expected, Revision::selectFields() );
979 }
980
981 public function provideSelectArchiveFields() {
982 yield [
983 true,
984 [
985 'ar_id',
986 'ar_page_id',
987 'ar_rev_id',
988 'ar_text_id',
989 'ar_timestamp',
990 'ar_user_text',
991 'ar_user',
992 'ar_actor' => 'NULL',
993 'ar_minor_edit',
994 'ar_deleted',
995 'ar_len',
996 'ar_parent_id',
997 'ar_sha1',
998 'commentstore' => 'fields',
999 'ar_content_format',
1000 'ar_content_model',
1001 ]
1002 ];
1003 yield [
1004 false,
1005 [
1006 'ar_id',
1007 'ar_page_id',
1008 'ar_rev_id',
1009 'ar_text_id',
1010 'ar_timestamp',
1011 'ar_user_text',
1012 'ar_user',
1013 'ar_actor' => 'NULL',
1014 'ar_minor_edit',
1015 'ar_deleted',
1016 'ar_len',
1017 'ar_parent_id',
1018 'ar_sha1',
1019 'commentstore' => 'fields',
1020 ]
1021 ];
1022 }
1023
1028 public function testSelectArchiveFields( $contentHandlerUseDB, $expected ) {
1029 $this->hideDeprecated( 'Revision::selectArchiveFields' );
1030 $this->setMwGlobals( 'wgContentHandlerUseDB', $contentHandlerUseDB );
1031 $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', MIGRATION_OLD );
1033 $this->assertEquals( $expected, Revision::selectArchiveFields() );
1034 }
1035
1039 public function testSelectTextFields() {
1040 $this->hideDeprecated( 'Revision::selectTextFields' );
1041 $this->assertEquals(
1042 [
1043 'old_text',
1044 'old_flags',
1045 ],
1046 Revision::selectTextFields()
1047 );
1048 }
1049
1053 public function testSelectPageFields() {
1054 $this->hideDeprecated( 'Revision::selectPageFields' );
1055 $this->assertEquals(
1056 [
1057 'page_namespace',
1058 'page_title',
1059 'page_id',
1060 'page_latest',
1061 'page_is_redirect',
1062 'page_len',
1063 ],
1064 Revision::selectPageFields()
1065 );
1066 }
1067
1071 public function testSelectUserFields() {
1072 $this->hideDeprecated( 'Revision::selectUserFields' );
1073 $this->assertEquals(
1074 [
1075 'user_name',
1076 ],
1077 Revision::selectUserFields()
1078 );
1079 }
1080
1081 public function provideGetArchiveQueryInfo() {
1082 yield 'wgContentHandlerUseDB false' => [
1083 [
1084 'wgContentHandlerUseDB' => false,
1085 ],
1086 [
1087 'tables' => [
1088 'archive',
1089 'commentstore' => 'table',
1090 'actormigration' => 'table',
1091 ],
1092 'fields' => [
1093 'ar_id',
1094 'ar_page_id',
1095 'ar_namespace',
1096 'ar_title',
1097 'ar_rev_id',
1098 'ar_text_id',
1099 'ar_timestamp',
1100 'ar_minor_edit',
1101 'ar_deleted',
1102 'ar_len',
1103 'ar_parent_id',
1104 'ar_sha1',
1105 'commentstore' => 'field',
1106 'ar_user' => 'actormigration_user',
1107 'ar_user_text' => 'actormigration_user_text',
1108 'ar_actor' => 'actormigration_actor',
1109 ],
1110 'joins' => [ 'commentstore' => 'join', 'actormigration' => 'join' ],
1111 ]
1112 ];
1113 yield 'wgContentHandlerUseDB true' => [
1114 [
1115 'wgContentHandlerUseDB' => true,
1116 ],
1117 [
1118 'tables' => [
1119 'archive',
1120 'commentstore' => 'table',
1121 'actormigration' => 'table',
1122 ],
1123 'fields' => [
1124 'ar_id',
1125 'ar_page_id',
1126 'ar_namespace',
1127 'ar_title',
1128 'ar_rev_id',
1129 'ar_text_id',
1130 'ar_timestamp',
1131 'ar_minor_edit',
1132 'ar_deleted',
1133 'ar_len',
1134 'ar_parent_id',
1135 'ar_sha1',
1136 'commentstore' => 'field',
1137 'ar_user' => 'actormigration_user',
1138 'ar_user_text' => 'actormigration_user_text',
1139 'ar_actor' => 'actormigration_actor',
1140 'ar_content_format',
1141 'ar_content_model',
1142 ],
1143 'joins' => [ 'commentstore' => 'join', 'actormigration' => 'join' ],
1144 ]
1145 ];
1146 }
1147
1152 public function testGetArchiveQueryInfo( $globals, $expected ) {
1153 $this->setMwGlobals( $globals );
1155
1156 $revisionStore = $this->getRevisionStore();
1157 $revisionStore->setContentHandlerUseDB( $globals['wgContentHandlerUseDB'] );
1158 $this->setService( 'RevisionStore', $revisionStore );
1159 $this->assertEquals(
1160 $expected,
1161 Revision::getArchiveQueryInfo()
1162 );
1163 }
1164
1165 public function provideGetQueryInfo() {
1166 yield 'wgContentHandlerUseDB false, opts none' => [
1167 [
1168 'wgContentHandlerUseDB' => false,
1169 ],
1170 [],
1171 [
1172 'tables' => [ 'revision', 'commentstore' => 'table', 'actormigration' => 'table' ],
1173 'fields' => [
1174 'rev_id',
1175 'rev_page',
1176 'rev_text_id',
1177 'rev_timestamp',
1178 'rev_minor_edit',
1179 'rev_deleted',
1180 'rev_len',
1181 'rev_parent_id',
1182 'rev_sha1',
1183 'commentstore' => 'field',
1184 'rev_user' => 'actormigration_user',
1185 'rev_user_text' => 'actormigration_user_text',
1186 'rev_actor' => 'actormigration_actor',
1187 ],
1188 'joins' => [ 'commentstore' => 'join', 'actormigration' => 'join' ],
1189 ],
1190 ];
1191 yield 'wgContentHandlerUseDB false, opts page' => [
1192 [
1193 'wgContentHandlerUseDB' => false,
1194 ],
1195 [ 'page' ],
1196 [
1197 'tables' => [ 'revision', 'commentstore' => 'table', 'actormigration' => 'table', 'page' ],
1198 'fields' => [
1199 'rev_id',
1200 'rev_page',
1201 'rev_text_id',
1202 'rev_timestamp',
1203 'rev_minor_edit',
1204 'rev_deleted',
1205 'rev_len',
1206 'rev_parent_id',
1207 'rev_sha1',
1208 'commentstore' => 'field',
1209 'rev_user' => 'actormigration_user',
1210 'rev_user_text' => 'actormigration_user_text',
1211 'rev_actor' => 'actormigration_actor',
1212 'page_namespace',
1213 'page_title',
1214 'page_id',
1215 'page_latest',
1216 'page_is_redirect',
1217 'page_len',
1218 ],
1219 'joins' => [
1220 'page' => [
1221 'INNER JOIN',
1222 [ 'page_id = rev_page' ],
1223 ],
1224 'commentstore' => 'join',
1225 'actormigration' => 'join',
1226 ],
1227 ],
1228 ];
1229 yield 'wgContentHandlerUseDB false, opts user' => [
1230 [
1231 'wgContentHandlerUseDB' => false,
1232 ],
1233 [ 'user' ],
1234 [
1235 'tables' => [ 'revision', 'commentstore' => 'table', 'actormigration' => 'table', 'user' ],
1236 'fields' => [
1237 'rev_id',
1238 'rev_page',
1239 'rev_text_id',
1240 'rev_timestamp',
1241 'rev_minor_edit',
1242 'rev_deleted',
1243 'rev_len',
1244 'rev_parent_id',
1245 'rev_sha1',
1246 'commentstore' => 'field',
1247 'rev_user' => 'actormigration_user',
1248 'rev_user_text' => 'actormigration_user_text',
1249 'rev_actor' => 'actormigration_actor',
1250 'user_name',
1251 ],
1252 'joins' => [
1253 'user' => [
1254 'LEFT JOIN',
1255 [
1256 'actormigration_user != 0',
1257 'user_id = actormigration_user',
1258 ],
1259 ],
1260 'commentstore' => 'join',
1261 'actormigration' => 'join',
1262 ],
1263 ],
1264 ];
1265 yield 'wgContentHandlerUseDB false, opts text' => [
1266 [
1267 'wgContentHandlerUseDB' => false,
1268 ],
1269 [ 'text' ],
1270 [
1271 'tables' => [ 'revision', 'commentstore' => 'table', 'actormigration' => 'table', 'text' ],
1272 'fields' => [
1273 'rev_id',
1274 'rev_page',
1275 'rev_text_id',
1276 'rev_timestamp',
1277 'rev_minor_edit',
1278 'rev_deleted',
1279 'rev_len',
1280 'rev_parent_id',
1281 'rev_sha1',
1282 'commentstore' => 'field',
1283 'rev_user' => 'actormigration_user',
1284 'rev_user_text' => 'actormigration_user_text',
1285 'rev_actor' => 'actormigration_actor',
1286 'old_text',
1287 'old_flags',
1288 ],
1289 'joins' => [
1290 'text' => [
1291 'INNER JOIN',
1292 [ 'rev_text_id=old_id' ],
1293 ],
1294 'commentstore' => 'join',
1295 'actormigration' => 'join',
1296 ],
1297 ],
1298 ];
1299 yield 'wgContentHandlerUseDB false, opts 3' => [
1300 [
1301 'wgContentHandlerUseDB' => false,
1302 ],
1303 [ 'text', 'page', 'user' ],
1304 [
1305 'tables' => [
1306 'revision', 'commentstore' => 'table', 'actormigration' => 'table', 'page', 'user', 'text'
1307 ],
1308 'fields' => [
1309 'rev_id',
1310 'rev_page',
1311 'rev_text_id',
1312 'rev_timestamp',
1313 'rev_minor_edit',
1314 'rev_deleted',
1315 'rev_len',
1316 'rev_parent_id',
1317 'rev_sha1',
1318 'commentstore' => 'field',
1319 'rev_user' => 'actormigration_user',
1320 'rev_user_text' => 'actormigration_user_text',
1321 'rev_actor' => 'actormigration_actor',
1322 'page_namespace',
1323 'page_title',
1324 'page_id',
1325 'page_latest',
1326 'page_is_redirect',
1327 'page_len',
1328 'user_name',
1329 'old_text',
1330 'old_flags',
1331 ],
1332 'joins' => [
1333 'page' => [
1334 'INNER JOIN',
1335 [ 'page_id = rev_page' ],
1336 ],
1337 'user' => [
1338 'LEFT JOIN',
1339 [
1340 'actormigration_user != 0',
1341 'user_id = actormigration_user',
1342 ],
1343 ],
1344 'text' => [
1345 'INNER JOIN',
1346 [ 'rev_text_id=old_id' ],
1347 ],
1348 'commentstore' => 'join',
1349 'actormigration' => 'join',
1350 ],
1351 ],
1352 ];
1353 yield 'wgContentHandlerUseDB true, opts none' => [
1354 [
1355 'wgContentHandlerUseDB' => true,
1356 ],
1357 [],
1358 [
1359 'tables' => [ 'revision', 'commentstore' => 'table', 'actormigration' => 'table' ],
1360 'fields' => [
1361 'rev_id',
1362 'rev_page',
1363 'rev_text_id',
1364 'rev_timestamp',
1365 'rev_minor_edit',
1366 'rev_deleted',
1367 'rev_len',
1368 'rev_parent_id',
1369 'rev_sha1',
1370 'commentstore' => 'field',
1371 'rev_user' => 'actormigration_user',
1372 'rev_user_text' => 'actormigration_user_text',
1373 'rev_actor' => 'actormigration_actor',
1374 'rev_content_format',
1375 'rev_content_model',
1376 ],
1377 'joins' => [ 'commentstore' => 'join', 'actormigration' => 'join' ],
1378 ],
1379 ];
1380 }
1381
1386 public function testGetQueryInfo( $globals, $options, $expected ) {
1387 $this->setMwGlobals( $globals );
1389
1390 $revisionStore = $this->getRevisionStore();
1391 $revisionStore->setContentHandlerUseDB( $globals['wgContentHandlerUseDB'] );
1392 $this->setService( 'RevisionStore', $revisionStore );
1393
1394 $this->assertEquals(
1395 $expected,
1396 Revision::getQueryInfo( $options )
1397 );
1398 }
1399
1403 public function testGetSize() {
1404 $title = $this->getMockTitle();
1405
1406 $rec = new MutableRevisionRecord( $title );
1407 $rev = new Revision( $rec, 0, $title );
1408
1409 $this->assertSame( 0, $rev->getSize(), 'Size of no slots is 0' );
1410
1411 $rec->setSize( 13 );
1412 $this->assertSame( 13, $rev->getSize() );
1413 }
1414
1418 public function testGetSize_failure() {
1419 $title = $this->getMockTitle();
1420
1421 $rec = $this->getMockBuilder( RevisionRecord::class )
1422 ->disableOriginalConstructor()
1423 ->getMock();
1424
1425 $rec->method( 'getSize' )
1426 ->willThrowException( new RevisionAccessException( 'Oops!' ) );
1427
1428 $rev = new Revision( $rec, 0, $title );
1429 $this->assertNull( $rev->getSize() );
1430 }
1431
1435 public function testGetSha1() {
1436 $title = $this->getMockTitle();
1437
1438 $rec = new MutableRevisionRecord( $title );
1439 $rev = new Revision( $rec, 0, $title );
1440
1441 $emptyHash = SlotRecord::base36Sha1( '' );
1442 $this->assertSame( $emptyHash, $rev->getSha1(), 'Sha1 of no slots is hash of empty string' );
1443
1444 $rec->setSha1( 'deadbeef' );
1445 $this->assertSame( 'deadbeef', $rev->getSha1() );
1446 }
1447
1451 public function testGetSha1_failure() {
1452 $title = $this->getMockTitle();
1453
1454 $rec = $this->getMockBuilder( RevisionRecord::class )
1455 ->disableOriginalConstructor()
1456 ->getMock();
1457
1458 $rec->method( 'getSha1' )
1459 ->willThrowException( new RevisionAccessException( 'Oops!' ) );
1460
1461 $rev = new Revision( $rec, 0, $title );
1462 $this->assertNull( $rev->getSha1() );
1463 }
1464
1468 public function testGetContent() {
1469 $title = $this->getMockTitle();
1470
1471 $rec = new MutableRevisionRecord( $title );
1472 $rev = new Revision( $rec, 0, $title );
1473
1474 $this->assertNull( $rev->getContent(), 'Content of no slots is null' );
1475
1476 $content = new TextContent( 'Hello Kittens!' );
1477 $rec->setContent( 'main', $content );
1478 $this->assertSame( $content, $rev->getContent() );
1479 }
1480
1484 public function testGetContent_failure() {
1485 $title = $this->getMockTitle();
1486
1487 $rec = $this->getMockBuilder( RevisionRecord::class )
1488 ->disableOriginalConstructor()
1489 ->getMock();
1490
1491 $rec->method( 'getContent' )
1492 ->willThrowException( new RevisionAccessException( 'Oops!' ) );
1493
1494 $rev = new Revision( $rec, 0, $title );
1495 $this->assertNull( $rev->getContent() );
1496 }
1497
1498}
serialize()
they could even be mouse clicks or menu items whatever suits your program You should also get your if any
Definition COPYING.txt:326
wfWikiID()
Get an ASCII string identifying this wiki This is used as a prefix in memcached keys.
Simple store for keeping values in an associative array for the current process.
Content for JavaScript pages.
MediaWiki exception.
getDefaultWikitextNS()
Returns the ID of a namespace that defaults to Wikitext.
Database $db
Primary database.
overrideMwServices(Config $configOverrides=null, array $services=[])
Stashes the global instance of MediaWikiServices, and installs a new one, allowing test cases to over...
setMwGlobals( $pairs, $value=null)
Sets a global, maintaining a stashed version of the previous global to be restored in tearDown.
hideDeprecated( $function)
Don't throw a warning if $function is deprecated and called later.
checkPHPExtension( $extName)
Check if $extName is a loaded PHP extension, will skip the test whenever it is not loaded.
setService( $name, $object)
Sets a service, maintaining a stashed version of the previous service to be restored in tearDown.
static getTestUser( $groups=[])
Convenience method for getting an immutable test user.
MediaWikiServices is the service locator for the application scope of MediaWiki.
Service for instantiating BlobStores.
Mutable RevisionRecord implementation, for building new revision entries programmatically.
Exception representing a failure to look up a revision.
Page revision base class.
Service for looking up page revisions.
Value object representing a content slot associated with a page revision.
Service for storing and loading Content objects.
Test cases in RevisionTest should not interact with the Database.
testConstructFromEmptyArray()
Revision::__construct \MediaWiki\Storage\RevisionStore::newMutableRevisionFromArray.
testSetUserIdAndName( $inputId, $expectedId, $name)
provideSetUserIdAndName Revision::setUserIdAndName
provideConstructFromArray()
testUserJoinCond()
Revision::userJoinCond.
testGetRevisionWithGzipAndLegacyEncoding( $expected, $lang, $encoding, $rowData)
Revision::getRevisionText provideGetRevisionTextWithGzipAndLegacyEncoding.
testSelectUserFields()
Revision::selectUserFields.
testConstructFromArray( $rowArray)
provideConstructFromArray Revision::__construct \MediaWiki\Storage\RevisionStore::newMutableRevisionF...
testGetParentId( $rowArray, $expected)
provideGetParentId Revision::getParentId()
testGetId( $rowArray, $expectedId)
provideGetId Revision::getId
testGetSize()
Revision::getSize.
testConstructFromRowWithBadPageId()
Revision::__construct \MediaWiki\Storage\RevisionStore::newMutableRevisionFromArray.
overrideCommentStoreAndActorMigration()
testSetId( $input, $expected)
provideSetId Revision::setId
testSelectPageFields()
Revision::selectPageFields.
testGetRevisionWithZlibExtension( $expected, $rowData)
Revision::getRevisionText provideGetRevisionTextWithZlibExtension.
provideGetRevisionTextWithLegacyEncoding()
testConstructFromArrayWithBadPageId()
Revision::__construct \MediaWiki\Storage\RevisionStore::newMutableRevisionFromArray.
testSelectTextFields()
Revision::selectTextFields.
testGetSize_failure()
Revision::getSize.
mockBlobStoreFactory( $blobStore)
provideDecompressRevisionText()
provideConstructFromArrayThrowsExceptions()
testConstructFromRow(array $arrayData, $assertions)
provideConstructFromRow Revision::__construct \MediaWiki\Storage\RevisionStore::newMutableRevisionFro...
testConstructFromArrayThrowsExceptions( $rowArray, Exception $expectedException)
provideConstructFromArrayThrowsExceptions Revision::__construct \MediaWiki\Storage\RevisionStore::new...
provideGetRevisionTextWithZlibExtension()
testGetRevisionText( $expected, $rowData, $prefix='old_', $wiki=false)
Revision::getRevisionText provideGetRevisionText.
testGetTextId( $rowArray, $expected)
provideGetTextId Revision::getTextId()
testGetArchiveQueryInfo( $globals, $expected)
Revision::getArchiveQueryInfo provideGetArchiveQueryInfo.
testGetSha1()
Revision::getSha1.
testCompressRevisionTextUtf8()
Revision::compressRevisionText.
testGetSha1_failure()
Revision::getSha1.
testGetRevisionText_returnsDecompressedTextFieldWhenNotExternal( $row, $prefix, $expected)
provideTestGetRevisionText_returnsDecompressedTextFieldWhenNotExternal Revision::getRevisionText
provideConstructFromArray_userSetAsExpected()
testGetContent()
Revision::getContent.
testConstructFromArray_userSetAsExpected(array $rowArray, $expectedUserId, $expectedUserName)
provideConstructFromArray_userSetAsExpected Revision::__construct \MediaWiki\Storage\RevisionStore::n...
testGetRevisionWithLegacyEncoding( $expected, $lang, $encoding, $rowData)
Revision::getRevisionText provideGetRevisionTextWithLegacyEncoding.
provideTestGetRevisionText_returnsDecompressedTextFieldWhenNotExternal()
provideGetRevisionTextWithGzipAndLegacyEncoding()
testGetRevisionText_returnsFalseWhenNoTextField()
Revision::getRevisionText.
testDecompressRevisionText( $legacyEncoding, $text, $flags, $expected)
provideDecompressRevisionText Revision::decompressRevisionText
getMockTitle( $model=CONTENT_MODEL_WIKITEXT)
testGetContent_failure()
Revision::getContent.
testSelectFields( $contentHandlerUseDB, $expected)
provideSelectFields Revision::selectFields
testLoadFromTitle()
Revision::loadFromTitle.
testGetRevisionText_external_returnsFalseWhenNotEnoughUrlParts( $text)
provideTestGetRevisionText_external_returnsFalseWhenNotEnoughUrlParts Revision::getRevisionText
testGetQueryInfo( $globals, $options, $expected)
Revision::getQueryInfo provideGetQueryInfo.
testGetRevisionText_external_noOldId()
Revision::getRevisionText.
testPageJoinCond()
Revision::pageJoinCond.
testSelectArchiveFields( $contentHandlerUseDB, $expected)
provideSelectArchiveFields Revision::selectArchiveFields
provideTestGetRevisionText_external_returnsFalseWhenNotEnoughUrlParts()
testCompressRevisionTextUtf8Gzip()
Revision::compressRevisionText.
testConstructFromNothing()
Revision::__construct \MediaWiki\Storage\RevisionStore::newMutableRevisionFromArray.
testGetRevisionText_external_oldId()
Revision::getRevisionText.
Content object implementation for representing flat text.
Represents a page (or page fragment) title within MediaWiki.
Multi-datacenter aware caching interface.
Database connection, tracking, load balancing, and transaction manager for a cluster.
Content object for wiki text pages.
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped & $options
Definition hooks.txt:2001
presenting them properly to the user as errors is done by the caller return true use this to change the list i e etc $rev
Definition hooks.txt:1777
processing should stop and the error should be shown to the user * false
Definition hooks.txt:187
globals will be eliminated from MediaWiki replaced by an application object which would be passed to constructors Whether that would be an convenient solution remains to be but certainly PHP makes such object oriented programming models easier than they were in previous versions For the time being MediaWiki programmers will have to work in an environment with some global context At the time of globals were initialised on startup by MediaWiki of these were configuration which are documented in DefaultSettings php There is no comprehensive documentation for the remaining however some of the most important ones are listed below They are typically initialised either in index php or in Setup php For a description of the see design txt $wgTitle Title object created from the request URL $wgOut OutputPage object for HTTP response $wgUser User object for the user associated with the current request $wgLang Language object selected by user preferences $wgContLang Language object associated with the wiki being viewed $wgParser Parser object Parser extensions register their hooks here $wgRequest WebRequest object
Definition globals.txt:64
const CONTENT_MODEL_WIKITEXT
Definition Defines.php:245
const MIGRATION_OLD
Definition Defines.php:302
const CONTENT_MODEL_JAVASCRIPT
Definition Defines.php:246
Basic database interface for live and lazy-loaded relation database handles.
Definition IDatabase.php:38
$cache
Definition mcc.php:33
if(is_array($mode)) switch( $mode) $input
if(!isset( $args[0])) $lang