MediaWiki  1.31.0
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(
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 
572  public function testCompressRevisionTextUtf8() {
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 
675  public function provideDecompressRevisionText() {
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(
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',
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',
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' ] ],
878  );
879  }
880 
884  public function testPageJoinCond() {
885  $this->hideDeprecated( 'Revision::pageJoinCond' );
886  $this->assertEquals(
887  [ 'INNER JOIN', [ 'page_id = rev_page' ] ],
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  ],
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  ],
1065  );
1066  }
1067 
1071  public function testSelectUserFields() {
1072  $this->hideDeprecated( 'Revision::selectUserFields' );
1073  $this->assertEquals(
1074  [
1075  'user_name',
1076  ],
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,
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,
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 }
RevisionTest\testSetId
testSetId( $input, $expected)
provideSetId Revision::setId
Definition: RevisionTest.php:361
RevisionTest\testGetSha1
testGetSha1()
Revision::getSha1.
Definition: RevisionTest.php:1435
RevisionTest\testGetArchiveQueryInfo
testGetArchiveQueryInfo( $globals, $expected)
Revision::getArchiveQueryInfo provideGetArchiveQueryInfo.
Definition: RevisionTest.php:1152
RevisionTest\testConstructFromEmptyArray
testConstructFromEmptyArray()
Revision::__construct \MediaWiki\Storage\RevisionStore::newMutableRevisionFromArray.
Definition: RevisionTest.php:79
object
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:25
RevisionTest\provideGetTextId
provideGetTextId()
Definition: RevisionTest.php:383
MediaWiki\Storage\RevisionStore
Service for looking up page revisions.
Definition: RevisionStore.php:68
false
processing should stop and the error should be shown to the user * false
Definition: hooks.txt:187
RevisionTest\provideDecompressRevisionText
provideDecompressRevisionText()
Definition: RevisionTest.php:675
RevisionTest\testGetTextId
testGetTextId( $rowArray, $expected)
provideGetTextId Revision::getTextId()
Definition: RevisionTest.php:393
Revision\pageJoinCond
static pageJoinCond()
Return the value of a select() page conds array for the page table.
Definition: Revision.php:340
RevisionTest\provideGetArchiveQueryInfo
provideGetArchiveQueryInfo()
Definition: RevisionTest.php:1081
HashBagOStuff
Simple store for keeping values in an associative array for the current process.
Definition: HashBagOStuff.php:31
MediaWikiTestCase\getTestUser
static getTestUser( $groups=[])
Convenience method for getting an immutable test user.
Definition: MediaWikiTestCase.php:153
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:33
RevisionTest\testSelectArchiveFields
testSelectArchiveFields( $contentHandlerUseDB, $expected)
provideSelectArchiveFields Revision::selectArchiveFields
Definition: RevisionTest.php:1028
RevisionTest\testConstructFromArray_userSetAsExpected
testConstructFromArray_userSetAsExpected(array $rowArray, $expectedUserId, $expectedUserName)
provideConstructFromArray_userSetAsExpected Revision::__construct \MediaWiki\Storage\RevisionStore::n...
Definition: RevisionTest.php:132
MediaWiki\Storage\SqlBlobStore
Service for storing and loading Content objects.
Definition: SqlBlobStore.php:50
RevisionTest\testGetRevisionText_external_oldId
testGetRevisionText_external_oldId()
Revision::getRevisionText.
Definition: RevisionTest.php:837
RevisionTest\provideSelectArchiveFields
provideSelectArchiveFields()
Definition: RevisionTest.php:981
RevisionTest\testConstructFromArrayThrowsExceptions
testConstructFromArrayThrowsExceptions( $rowArray, Exception $expectedException)
provideConstructFromArrayThrowsExceptions Revision::__construct \MediaWiki\Storage\RevisionStore::new...
Definition: RevisionTest.php:181
use
as see the revision history and available at free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to use
Definition: MIT-LICENSE.txt:10
RevisionTest\testUserJoinCond
testUserJoinCond()
Revision::userJoinCond.
Definition: RevisionTest.php:871
RevisionTest\provideSelectFields
provideSelectFields()
Definition: RevisionTest.php:928
RevisionTest\testGetRevisionText_returnsFalseWhenNoTextField
testGetRevisionText_returnsFalseWhenNoTextField()
Revision::getRevisionText.
Definition: RevisionTest.php:752
serialize
serialize()
Definition: ApiMessage.php:184
RevisionTest\provideGetRevisionTextWithZlibExtension
provideGetRevisionTextWithZlibExtension()
Definition: RevisionTest.php:423
Revision\getRevisionText
static getRevisionText( $row, $prefix='old_', $wiki=false)
Get revision text associated with an old or archive row.
Definition: Revision.php:1055
Revision\getArchiveQueryInfo
static getArchiveQueryInfo()
Return the tables, fields, and join conditions to be selected to create a new archived revision objec...
Definition: Revision.php:506
RevisionTest\testConstructFromRowWithBadPageId
testConstructFromRowWithBadPageId()
Revision::__construct \MediaWiki\Storage\RevisionStore::newMutableRevisionFromArray.
Definition: RevisionTest.php:313
$name
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:302
RevisionTest\testGetSize_failure
testGetSize_failure()
Revision::getSize.
Definition: RevisionTest.php:1418
CONTENT_MODEL_WIKITEXT
const CONTENT_MODEL_WIKITEXT
Definition: Defines.php:236
RevisionTest\testGetRevisionWithGzipAndLegacyEncoding
testGetRevisionWithGzipAndLegacyEncoding( $expected, $lang, $encoding, $rowData)
Revision::getRevisionText provideGetRevisionTextWithGzipAndLegacyEncoding.
Definition: RevisionTest.php:559
RevisionTest\testGetQueryInfo
testGetQueryInfo( $globals, $options, $expected)
Revision::getQueryInfo provideGetQueryInfo.
Definition: RevisionTest.php:1386
RevisionTest\testSelectFields
testSelectFields( $contentHandlerUseDB, $expected)
provideSelectFields Revision::selectFields
Definition: RevisionTest.php:973
php
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
RevisionTest\provideConstructFromArray
provideConstructFromArray()
Definition: RevisionTest.php:20
Wikimedia\Rdbms\IDatabase
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:38
RevisionTest\provideTestGetRevisionText_external_returnsFalseWhenNotEnoughUrlParts
provideTestGetRevisionText_external_returnsFalseWhenNotEnoughUrlParts()
Definition: RevisionTest.php:793
RevisionTest\provideGetQueryInfo
provideGetQueryInfo()
Definition: RevisionTest.php:1165
Revision\selectTextFields
static selectTextFields()
Return the list of text fields that should be selected to read the revision text.
Definition: Revision.php:443
MediaWikiTestCase\overrideMwServices
overrideMwServices(Config $configOverrides=null, array $services=[])
Stashes the global instance of MediaWikiServices, and installs a new one, allowing test cases to over...
Definition: MediaWikiTestCase.php:845
RevisionTest\mockBlobStoreFactory
mockBlobStoreFactory( $blobStore)
Definition: RevisionTest.php:461
RevisionTest\testPageJoinCond
testPageJoinCond()
Revision::pageJoinCond.
Definition: RevisionTest.php:884
Revision
Definition: Revision.php:41
RevisionTest\testCompressRevisionTextUtf8Gzip
testCompressRevisionTextUtf8Gzip()
Revision::compressRevisionText.
Definition: RevisionTest.php:589
RevisionTest\getWANObjectCache
getWANObjectCache()
Definition: RevisionTest.php:442
RevisionTest\provideGetRevisionText
provideGetRevisionText()
Definition: RevisionTest.php:322
RevisionTest\provideGetParentId
provideGetParentId()
Definition: RevisionTest.php:398
Revision\getQueryInfo
static getQueryInfo( $options=[])
Return the tables, fields, and join conditions to be selected to create a new revision object.
Definition: Revision.php:492
MWException
MediaWiki exception.
Definition: MWException.php:26
$title
namespace and then decline to actually register it file or subcat img or subcat $title
Definition: hooks.txt:934
RevisionTest\testSetUserIdAndName
testSetUserIdAndName( $inputId, $expectedId, $name)
provideSetUserIdAndName Revision::setUserIdAndName
Definition: RevisionTest.php:376
RevisionTest\testGetRevisionWithLegacyEncoding
testGetRevisionWithLegacyEncoding( $expected, $lang, $encoding, $rowData)
Revision::getRevisionText provideGetRevisionTextWithLegacyEncoding.
Definition: RevisionTest.php:521
$input
if(is_array( $mode)) switch( $mode) $input
Definition: postprocess-phan.php:141
MediaWikiTestCase\setMwGlobals
setMwGlobals( $pairs, $value=null)
Sets a global, maintaining a stashed version of the previous global to be restored in tearDown.
Definition: MediaWikiTestCase.php:678
MediaWikiTestCase
Definition: MediaWikiTestCase.php:17
Revision\compressRevisionText
static compressRevisionText(&$text)
If $wgCompressRevisions is enabled, we will compress data.
Definition: Revision.php:1086
RevisionTest\provideGetRevisionTextWithGzipAndLegacyEncoding
provideGetRevisionTextWithGzipAndLegacyEncoding()
Definition: RevisionTest.php:529
MediaWikiTestCase\hideDeprecated
hideDeprecated( $function)
Don't throw a warning if $function is deprecated and called later.
Definition: MediaWikiTestCase.php:1675
RevisionTest\provideConstructFromArrayThrowsExceptions
provideConstructFromArrayThrowsExceptions()
Definition: RevisionTest.php:151
MediaWiki\Storage\BlobStoreFactory
Service for instantiating BlobStores.
Definition: BlobStoreFactory.php:35
MediaWikiTestCase\getDefaultWikitextNS
getDefaultWikitextNS()
Returns the ID of a namespace that defaults to Wikitext.
Definition: MediaWikiTestCase.php:1912
RevisionTest\testGetContent
testGetContent()
Revision::getContent.
Definition: RevisionTest.php:1468
WikitextContent
Content object for wiki text pages.
Definition: WikitextContent.php:33
RevisionTest
Test cases in RevisionTest should not interact with the Database.
Definition: RevisionTest.php:18
MediaWiki\Storage\RevisionRecord
Page revision base class.
Definition: RevisionRecord.php:44
JavaScriptContent
Content for JavaScript pages.
Definition: JavaScriptContent.php:33
RevisionTest\provideGetRevisionTextWithLegacyEncoding
provideGetRevisionTextWithLegacyEncoding()
Definition: RevisionTest.php:496
MIGRATION_OLD
const MIGRATION_OLD
Definition: Defines.php:293
Wikimedia\Rdbms\LoadBalancer
Database connection, tracking, load balancing, and transaction manager for a cluster.
Definition: LoadBalancer.php:40
Revision\selectPageFields
static selectPageFields()
Return the list of page fields that should be selected from page table.
Definition: Revision.php:456
RevisionTest\testGetSize
testGetSize()
Revision::getSize.
Definition: RevisionTest.php:1403
ExternalStoreFactory
Definition: ExternalStoreFactory.php:9
any
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
wfWikiID()
Get an ASCII string identifying this wiki This is used as a prefix in memcached keys.
Definition: GlobalFunctions.php:2751
RevisionTest\provideSetUserIdAndName
provideSetUserIdAndName()
Definition: RevisionTest.php:367
Revision\selectArchiveFields
static selectArchiveFields()
Return the list of revision fields that should be selected to create a new revision from an archive r...
Definition: Revision.php:397
MediaWiki\Storage\RevisionAccessException
Exception representing a failure to look up a revision.
Definition: RevisionAccessException.php:32
RevisionTest\provideConstructFromArray_userSetAsExpected
provideConstructFromArray_userSetAsExpected()
Definition: RevisionTest.php:95
WANObjectCache
Multi-datacenter aware caching interface.
Definition: WANObjectCache.php:87
RevisionTest\testSelectPageFields
testSelectPageFields()
Revision::selectPageFields.
Definition: RevisionTest.php:1053
RevisionTest\testDecompressRevisionText
testDecompressRevisionText( $legacyEncoding, $text, $flags, $expected)
provideDecompressRevisionText Revision::decompressRevisionText
Definition: RevisionTest.php:736
RevisionTest\testConstructFromRow
testConstructFromRow(array $arrayData, $assertions)
provideConstructFromRow Revision::__construct \MediaWiki\Storage\RevisionStore::newMutableRevisionFro...
Definition: RevisionTest.php:280
RevisionTest\testConstructFromArray
testConstructFromArray( $rowArray)
provideConstructFromArray Revision::__construct \MediaWiki\Storage\RevisionStore::newMutableRevisionF...
Definition: RevisionTest.php:68
Revision\RAW
const RAW
Definition: Revision.php:57
RevisionTest\testGetRevisionText_external_noOldId
testGetRevisionText_external_noOldId()
Revision::getRevisionText.
Definition: RevisionTest.php:818
RevisionTest\testGetContent_failure
testGetContent_failure()
Revision::getContent.
Definition: RevisionTest.php:1484
RevisionTest\testSelectTextFields
testSelectTextFields()
Revision::selectTextFields.
Definition: RevisionTest.php:1039
RevisionTest\testGetRevisionText_returnsDecompressedTextFieldWhenNotExternal
testGetRevisionText_returnsDecompressedTextFieldWhenNotExternal( $row, $prefix, $expected)
provideTestGetRevisionText_returnsDecompressedTextFieldWhenNotExternal Revision::getRevisionText
Definition: RevisionTest.php:785
RevisionTest\overrideCommentStoreAndActorMigration
overrideCommentStoreAndActorMigration()
Definition: RevisionTest.php:892
TextContent
Content object implementation for representing flat text.
Definition: TextContent.php:35
RevisionTest\testSelectUserFields
testSelectUserFields()
Revision::selectUserFields.
Definition: RevisionTest.php:1071
RevisionTest\testGetRevisionText
testGetRevisionText( $expected, $rowData, $prefix='old_', $wiki=false)
Revision::getRevisionText provideGetRevisionText.
Definition: RevisionTest.php:417
RevisionTest\provideTestGetRevisionText_returnsDecompressedTextFieldWhenNotExternal
provideTestGetRevisionText_returnsDecompressedTextFieldWhenNotExternal()
Definition: RevisionTest.php:756
RevisionTest\testConstructFromArrayWithBadPageId
testConstructFromArrayWithBadPageId()
Revision::__construct \MediaWiki\Storage\RevisionStore::newMutableRevisionFromArray.
Definition: RevisionTest.php:88
RevisionTest\testGetRevisionText_external_returnsFalseWhenNotEnoughUrlParts
testGetRevisionText_external_returnsFalseWhenNotEnoughUrlParts( $text)
provideTestGetRevisionText_external_returnsFalseWhenNotEnoughUrlParts Revision::getRevisionText
Definition: RevisionTest.php:802
MediaWiki\Storage\MutableRevisionRecord
Mutable RevisionRecord implementation, for building new revision entries programmatically.
Definition: MutableRevisionRecord.php:39
$cache
$cache
Definition: mcc.php:33
$options
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:1987
RevisionTest\testConstructFromNothing
testConstructFromNothing()
Revision::__construct \MediaWiki\Storage\RevisionStore::newMutableRevisionFromArray.
Definition: RevisionTest.php:194
RevisionTest\testGetId
testGetId( $rowArray, $expectedId)
provideGetId Revision::getId
Definition: RevisionTest.php:347
$rev
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:1767
MediaWiki\Storage\SlotRecord
Value object representing a content slot associated with a page revision.
Definition: SlotRecord.php:38
RevisionTest\testLoadFromTitle
testLoadFromTitle()
Revision::loadFromTitle.
Definition: RevisionTest.php:612
RevisionTest\provideSetId
provideSetId()
Definition: RevisionTest.php:352
Revision\userJoinCond
static userJoinCond()
Return the value of a select() JOIN conds array for the user table.
Definition: Revision.php:317
RevisionTest\testGetSha1_failure
testGetSha1_failure()
Revision::getSha1.
Definition: RevisionTest.php:1451
MediaWikiTestCase\checkPHPExtension
checkPHPExtension( $extName)
Check if $extName is a loaded PHP extension, will skip the test whenever it is not loaded.
Definition: MediaWikiTestCase.php:1989
Language\factory
static factory( $code)
Get a cached or new language object for a given language code.
Definition: Language.php:183
class
you have access to all of the normal MediaWiki so you can get a DB use the etc For full docs on the Maintenance class
Definition: maintenance.txt:52
CONTENT_MODEL_JAVASCRIPT
const CONTENT_MODEL_JAVASCRIPT
Definition: Defines.php:237
Revision\selectUserFields
static selectUserFields()
Return the list of user fields that should be selected from user table.
Definition: Revision.php:473
RevisionTest\provideGetId
provideGetId()
Definition: RevisionTest.php:332
RevisionTest\getRevisionStore
getRevisionStore()
Definition: RevisionTest.php:478
MediaWikiServices
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency MediaWikiServices
Definition: injection.txt:23
Revision\selectFields
static selectFields()
Return the list of revision fields that should be selected to create a new revision.
Definition: Revision.php:351
Revision\decompressRevisionText
static decompressRevisionText( $text, $flags)
Re-converts revision text according to it's flags.
Definition: Revision.php:1097
Revision\loadFromTitle
static loadFromTitle( $db, $title, $id=0)
Load either the current, or a specified, revision that's attached to a given page.
Definition: Revision.php:273
RevisionTest\getBlobStore
getBlobStore()
Definition: RevisionTest.php:449
MediaWikiTestCase\setService
setService( $name, $object)
Sets a service, maintaining a stashed version of the previous service to be restored in tearDown.
Definition: MediaWikiTestCase.php:628
RevisionTest\provideConstructFromRow
provideConstructFromRow()
Definition: RevisionTest.php:201
Revision\DELETED_TEXT
const DELETED_TEXT
Definition: Revision.php:47
RevisionTest\getMockTitle
getMockTitle( $model=CONTENT_MODEL_WIKITEXT)
Definition: RevisionTest.php:40
MediaWikiTestCase\$db
Database $db
Primary database.
Definition: MediaWikiTestCase.php:57
RevisionTest\testCompressRevisionTextUtf8
testCompressRevisionTextUtf8()
Revision::compressRevisionText.
Definition: RevisionTest.php:572
RevisionTest\testGetRevisionWithZlibExtension
testGetRevisionWithZlibExtension( $expected, $rowData)
Revision::getRevisionText provideGetRevisionTextWithZlibExtension.
Definition: RevisionTest.php:437
array
the array() calling protocol came about after MediaWiki 1.4rc1.
RevisionTest\testGetParentId
testGetParentId( $rowArray, $expected)
provideGetParentId Revision::getParentId()
Definition: RevisionTest.php:408
TitleValue
Represents a page (or page fragment) title within MediaWiki.
Definition: TitleValue.php:35