MediaWiki  REL1_31
RevisionDbTestBase.php
Go to the documentation of this file.
1 <?php
6 
13 abstract class RevisionDbTestBase extends MediaWikiTestCase {
14 
18  private $testPage;
19 
20  public function __construct( $name = null, array $data = [], $dataName = '' ) {
21  parent::__construct( $name, $data, $dataName );
22 
23  $this->tablesUsed = array_merge( $this->tablesUsed,
24  [
25  'page',
26  'revision',
27  'ip_changes',
28  'text',
29  'archive',
30 
31  'recentchanges',
32  'logging',
33 
34  'page_props',
35  'pagelinks',
36  'categorylinks',
37  'langlinks',
38  'externallinks',
39  'imagelinks',
40  'templatelinks',
41  'iwlinks'
42  ]
43  );
44  }
45 
46  protected function setUp() {
48 
49  parent::setUp();
50 
52  'wgExtraNamespaces',
53  [
54  12312 => 'Dummy',
55  12313 => 'Dummy_talk',
56  ]
57  );
58 
60  'wgNamespaceContentModels',
61  [
63  ]
64  );
65 
67  'wgContentHandlers',
68  [
69  DummyContentForTesting::MODEL_ID => 'DummyContentHandlerForTesting',
70  RevisionTestModifyableContent::MODEL_ID => 'RevisionTestModifyableContentHandler',
71  ]
72  );
73 
74  $this->setMwGlobals( 'wgContentHandlerUseDB', $this->getContentHandlerUseDB() );
75 
77  // Reset namespace cache
78  $wgContLang->resetNamespaces();
79 
80  if ( !$this->testPage ) {
85  $this->testPage = $this->createPage( __CLASS__, __CLASS__ );
86  }
87  }
88 
89  protected function tearDown() {
91 
92  parent::tearDown();
93 
95  // Reset namespace cache
96  $wgContLang->resetNamespaces();
97  }
98 
99  abstract protected function getContentHandlerUseDB();
100 
101  private function makeRevisionWithProps( $props = null ) {
102  if ( $props === null ) {
103  $props = [];
104  }
105 
106  if ( !isset( $props['content'] ) && !isset( $props['text'] ) ) {
107  $props['text'] = 'Lorem Ipsum';
108  }
109 
110  if ( !isset( $props['user_text'] ) ) {
111  $user = $this->getTestUser()->getUser();
112  $props['user_text'] = $user->getName();
113  $props['user'] = $user->getId();
114  }
115 
116  if ( !isset( $props['user'] ) ) {
117  $props['user'] = 0;
118  }
119 
120  if ( !isset( $props['comment'] ) ) {
121  $props['comment'] = 'just a test';
122  }
123 
124  if ( !isset( $props['page'] ) ) {
125  $props['page'] = $this->testPage->getId();
126  }
127 
128  if ( !isset( $props['content_model'] ) ) {
129  $props['content_model'] = CONTENT_MODEL_WIKITEXT;
130  }
131 
132  $rev = new Revision( $props );
133 
134  $dbw = wfGetDB( DB_MASTER );
135  $rev->insertOn( $dbw );
136 
137  return $rev;
138  }
139 
147  private function createPage( $titleString, $text, $model = null ) {
148  if ( !preg_match( '/:/', $titleString ) &&
149  ( $model === null || $model === CONTENT_MODEL_WIKITEXT )
150  ) {
151  $ns = $this->getDefaultWikitextNS();
152  $titleString = MWNamespace::getCanonicalName( $ns ) . ':' . $titleString;
153  }
154 
155  $title = Title::newFromText( $titleString );
156  $wikipage = new WikiPage( $title );
157 
158  // Delete the article if it already exists
159  if ( $wikipage->exists() ) {
160  $wikipage->doDeleteArticle( "done" );
161  }
162 
163  $content = ContentHandler::makeContent( $text, $title, $model );
164  $wikipage->doEditContent( $content, __METHOD__, EDIT_NEW );
165 
166  return $wikipage;
167  }
168 
169  private function assertRevEquals( Revision $orig, Revision $rev = null ) {
170  $this->assertNotNull( $rev, 'missing revision' );
171 
172  $this->assertEquals( $orig->getId(), $rev->getId() );
173  $this->assertEquals( $orig->getPage(), $rev->getPage() );
174  $this->assertEquals( $orig->getTimestamp(), $rev->getTimestamp() );
175  $this->assertEquals( $orig->getUser(), $rev->getUser() );
176  $this->assertEquals( $orig->getContentModel(), $rev->getContentModel() );
177  $this->assertEquals( $orig->getContentFormat(), $rev->getContentFormat() );
178  $this->assertEquals( $orig->getSha1(), $rev->getSha1() );
179  }
180 
184  public function testGetRecentChange() {
185  $rev = $this->testPage->getRevision();
186  $recentChange = $rev->getRecentChange();
187 
188  // Make sure various attributes look right / the correct entry has been retrieved.
189  $this->assertEquals( $rev->getTimestamp(), $recentChange->getAttribute( 'rc_timestamp' ) );
190  $this->assertEquals(
191  $rev->getTitle()->getNamespace(),
192  $recentChange->getAttribute( 'rc_namespace' )
193  );
194  $this->assertEquals(
195  $rev->getTitle()->getDBkey(),
196  $recentChange->getAttribute( 'rc_title' )
197  );
198  $this->assertEquals( $rev->getUser(), $recentChange->getAttribute( 'rc_user' ) );
199  $this->assertEquals( $rev->getUserText(), $recentChange->getAttribute( 'rc_user_text' ) );
200  $this->assertEquals( $rev->getComment(), $recentChange->getAttribute( 'rc_comment' ) );
201  $this->assertEquals( $rev->getPage(), $recentChange->getAttribute( 'rc_cur_id' ) );
202  $this->assertEquals( $rev->getId(), $recentChange->getAttribute( 'rc_this_oldid' ) );
203  }
204 
208  public function testInsertOn_success() {
209  $parentId = $this->testPage->getLatest();
210 
211  // If an ExternalStore is set don't use it.
212  $this->setMwGlobals( 'wgDefaultExternalStore', false );
213 
214  $rev = new Revision( [
215  'page' => $this->testPage->getId(),
216  'title' => $this->testPage->getTitle(),
217  'text' => 'Revision Text',
218  'comment' => 'Revision comment',
219  ] );
220 
221  $revId = $rev->insertOn( wfGetDB( DB_MASTER ) );
222 
223  $this->assertInternalType( 'integer', $revId );
224  $this->assertSame( $revId, $rev->getId() );
225 
226  // getTextId() must be an int!
227  $this->assertInternalType( 'integer', $rev->getTextId() );
228 
229  $mainSlot = $rev->getRevisionRecord()->getSlot( 'main', RevisionRecord::RAW );
230 
231  // we currently only support storage in the text table
232  $textId = MediaWikiServices::getInstance()
233  ->getBlobStore()
234  ->getTextIdFromAddress( $mainSlot->getAddress() );
235 
236  $this->assertSelect(
237  'text',
238  [ 'old_id', 'old_text' ],
239  "old_id = $textId",
240  [ [ strval( $textId ), 'Revision Text' ] ]
241  );
242  $this->assertSelect(
243  'revision',
244  [
245  'rev_id',
246  'rev_page',
247  'rev_text_id',
248  'rev_minor_edit',
249  'rev_deleted',
250  'rev_len',
251  'rev_parent_id',
252  'rev_sha1',
253  ],
254  "rev_id = {$rev->getId()}",
255  [ [
256  strval( $rev->getId() ),
257  strval( $this->testPage->getId() ),
258  strval( $textId ),
259  '0',
260  '0',
261  '13',
262  strval( $parentId ),
263  's0ngbdoxagreuf2vjtuxzwdz64n29xm',
264  ] ]
265  );
266  }
267 
271  public function testInsertOn_exceptionOnNoPage() {
272  // If an ExternalStore is set don't use it.
273  $this->setMwGlobals( 'wgDefaultExternalStore', false );
274  $this->setExpectedException(
276  "rev_page field must not be 0!"
277  );
278 
279  $title = Title::newFromText( 'Nonexistant-' . __METHOD__ );
280  $rev = new Revision( [], 0, $title );
281 
282  $rev->insertOn( wfGetDB( DB_MASTER ) );
283  }
284 
288  public function testNewFromTitle_withoutId() {
289  $latestRevId = $this->testPage->getLatest();
290 
291  $rev = Revision::newFromTitle( $this->testPage->getTitle() );
292 
293  $this->assertTrue( $this->testPage->getTitle()->equals( $rev->getTitle() ) );
294  $this->assertEquals( $latestRevId, $rev->getId() );
295  }
296 
300  public function testNewFromTitle_withId() {
301  $latestRevId = $this->testPage->getLatest();
302 
303  $rev = Revision::newFromTitle( $this->testPage->getTitle(), $latestRevId );
304 
305  $this->assertTrue( $this->testPage->getTitle()->equals( $rev->getTitle() ) );
306  $this->assertEquals( $latestRevId, $rev->getId() );
307  }
308 
312  public function testNewFromTitle_withBadId() {
313  $latestRevId = $this->testPage->getLatest();
314 
315  $rev = Revision::newFromTitle( $this->testPage->getTitle(), $latestRevId + 1 );
316 
317  $this->assertNull( $rev );
318  }
319 
323  public function testNewFromRow() {
324  $orig = $this->makeRevisionWithProps();
325 
326  $dbr = wfGetDB( DB_REPLICA );
328  $res = $dbr->select( $revQuery['tables'], $revQuery['fields'], [ 'rev_id' => $orig->getId() ],
329  __METHOD__, [], $revQuery['joins'] );
330  $this->assertTrue( is_object( $res ), 'query failed' );
331 
332  $row = $res->fetchObject();
333  $res->free();
334 
335  $rev = Revision::newFromRow( $row );
336 
337  $this->assertRevEquals( $orig, $rev );
338  }
339 
340  public function provideNewFromArchiveRow() {
341  yield [
342  function ( $f ) {
343  return $f;
344  },
345  ];
346  yield [
347  function ( $f ) {
348  return $f + [ 'ar_namespace', 'ar_title' ];
349  },
350  ];
351  yield [
352  function ( $f ) {
353  unset( $f['ar_text_id'] );
354  return $f;
355  },
356  ];
357  yield [
358  function ( $f ) {
359  unset( $f['ar_page_id'] );
360  return $f;
361  },
362  ];
363  yield [
364  function ( $f ) {
365  unset( $f['ar_parent_id'] );
366  return $f;
367  },
368  ];
369  yield [
370  function ( $f ) {
371  unset( $f['ar_rev_id'] );
372  return $f;
373  },
374  ];
375  yield [
376  function ( $f ) {
377  unset( $f['ar_sha1'] );
378  return $f;
379  },
380  ];
381  }
382 
387  public function testNewFromArchiveRow( $selectModifier ) {
388  $services = MediaWikiServices::getInstance();
389 
390  $store = new RevisionStore(
391  $services->getDBLoadBalancer(),
392  $services->getService( '_SqlBlobStore' ),
393  $services->getMainWANObjectCache(),
394  $services->getCommentStore(),
395  $services->getActorMigration()
396  );
397 
398  $store->setContentHandlerUseDB( $this->getContentHandlerUseDB() );
399  $this->setService( 'RevisionStore', $store );
400 
401  $page = $this->createPage(
402  'RevisionStorageTest_testNewFromArchiveRow',
403  'Lorem Ipsum',
405  );
406  $orig = $page->getRevision();
407  $page->doDeleteArticle( 'test Revision::newFromArchiveRow' );
408 
409  $dbr = wfGetDB( DB_REPLICA );
410  $arQuery = Revision::getArchiveQueryInfo();
411  $arQuery['fields'] = $selectModifier( $arQuery['fields'] );
412  $res = $dbr->select(
413  $arQuery['tables'], $arQuery['fields'], [ 'ar_rev_id' => $orig->getId() ],
414  __METHOD__, [], $arQuery['joins']
415  );
416  $this->assertTrue( is_object( $res ), 'query failed' );
417 
418  $row = $res->fetchObject();
419  $res->free();
420 
421  // MCR migration note: $row is now required to contain ar_title and ar_namespace.
422  // Alternatively, a Title object can be passed to RevisionStore::newRevisionFromArchiveRow
424 
425  $this->assertRevEquals( $orig, $rev );
426  }
427 
431  public function testNewFromArchiveRowOverrides() {
432  $page = $this->createPage(
433  'RevisionStorageTest_testNewFromArchiveRow',
434  'Lorem Ipsum',
436  );
437  $orig = $page->getRevision();
438  $page->doDeleteArticle( 'test Revision::newFromArchiveRow' );
439 
440  $dbr = wfGetDB( DB_REPLICA );
441  $arQuery = Revision::getArchiveQueryInfo();
442  $res = $dbr->select(
443  $arQuery['tables'], $arQuery['fields'], [ 'ar_rev_id' => $orig->getId() ],
444  __METHOD__, [], $arQuery['joins']
445  );
446  $this->assertTrue( is_object( $res ), 'query failed' );
447 
448  $row = $res->fetchObject();
449  $res->free();
450 
451  $rev = Revision::newFromArchiveRow( $row, [ 'comment_text' => 'SOMEOVERRIDE' ] );
452 
453  $this->assertNotEquals( $orig->getComment(), $rev->getComment() );
454  $this->assertEquals( 'SOMEOVERRIDE', $rev->getComment() );
455  }
456 
460  public function testNewFromId() {
461  $orig = $this->testPage->getRevision();
462  $rev = Revision::newFromId( $orig->getId() );
463  $this->assertRevEquals( $orig, $rev );
464  }
465 
469  public function testNewFromPageId() {
470  $rev = Revision::newFromPageId( $this->testPage->getId() );
471  $this->assertRevEquals(
472  $this->testPage->getRevision(),
473  $rev
474  );
475  }
476 
480  public function testNewFromPageIdWithLatestId() {
482  $this->testPage->getId(),
483  $this->testPage->getLatest()
484  );
485  $this->assertRevEquals(
486  $this->testPage->getRevision(),
487  $rev
488  );
489  }
490 
495  $content = new WikitextContent( __METHOD__ );
496  $this->testPage->doEditContent( $content, __METHOD__ );
498  $this->testPage->getId(),
499  $this->testPage->getRevision()->getPrevious()->getId()
500  );
501  $this->assertRevEquals(
502  $this->testPage->getRevision()->getPrevious(),
503  $rev
504  );
505  }
506 
510  public function testFetchRevision() {
511  // Hidden process cache assertion below
512  $this->testPage->getRevision()->getId();
513 
514  $this->testPage->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ );
515  $id = $this->testPage->getRevision()->getId();
516 
517  $this->hideDeprecated( 'Revision::fetchRevision' );
518  $res = Revision::fetchRevision( $this->testPage->getTitle() );
519 
520  # note: order is unspecified
521  $rows = [];
522  while ( ( $row = $res->fetchObject() ) ) {
523  $rows[$row->rev_id] = $row;
524  }
525 
526  $this->assertEmpty( $rows, 'expected empty set' );
527  }
528 
532  public function testGetPage() {
533  $page = $this->testPage;
534 
535  $orig = $this->makeRevisionWithProps( [ 'page' => $page->getId() ] );
536  $rev = Revision::newFromId( $orig->getId() );
537 
538  $this->assertEquals( $page->getId(), $rev->getPage() );
539  }
540 
544  public function testIsCurrent() {
545  $rev1 = $this->testPage->getRevision();
546 
547  # @todo find out if this should be true
548  # $this->assertTrue( $rev1->isCurrent() );
549 
550  $rev1x = Revision::newFromId( $rev1->getId() );
551  $this->assertTrue( $rev1x->isCurrent() );
552 
553  $this->testPage->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ );
554  $rev2 = $this->testPage->getRevision();
555 
556  # @todo find out if this should be true
557  # $this->assertTrue( $rev2->isCurrent() );
558 
559  $rev1x = Revision::newFromId( $rev1->getId() );
560  $this->assertFalse( $rev1x->isCurrent() );
561 
562  $rev2x = Revision::newFromId( $rev2->getId() );
563  $this->assertTrue( $rev2x->isCurrent() );
564  }
565 
569  public function testGetPrevious() {
570  $oldestRevision = $this->testPage->getOldestRevision();
571  $latestRevision = $this->testPage->getLatest();
572 
573  $this->assertNull( $oldestRevision->getPrevious() );
574 
575  $this->testPage->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ );
576  $newRevision = $this->testPage->getRevision();
577 
578  $this->assertNotNull( $newRevision->getPrevious() );
579  $this->assertEquals( $latestRevision, $newRevision->getPrevious()->getId() );
580  }
581 
585  public function testGetNext() {
586  $rev1 = $this->testPage->getRevision();
587 
588  $this->assertNull( $rev1->getNext() );
589 
590  $this->testPage->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ );
591  $rev2 = $this->testPage->getRevision();
592 
593  $this->assertNotNull( $rev1->getNext() );
594  $this->assertEquals( $rev2->getId(), $rev1->getNext()->getId() );
595  }
596 
600  public function testNewNullRevision() {
601  $this->testPage->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ );
602  $orig = $this->testPage->getRevision();
603 
604  $dbw = wfGetDB( DB_MASTER );
605  $rev = Revision::newNullRevision( $dbw, $this->testPage->getId(), 'a null revision', false );
606 
607  $this->assertNotEquals( $orig->getId(), $rev->getId(),
608  'new null revision should have a different id from the original revision' );
609  $this->assertEquals( $orig->getTextId(), $rev->getTextId(),
610  'new null revision should have the same text id as the original revision' );
611  $this->assertEquals( $orig->getSha1(), $rev->getSha1(),
612  'new null revision should have the same SHA1 as the original revision' );
613  $this->assertTrue( $orig->getRevisionRecord()->hasSameContent( $rev->getRevisionRecord() ),
614  'new null revision should have the same content as the original revision' );
615  $this->assertEquals( __METHOD__, $rev->getContent()->getNativeData() );
616  }
617 
621  public function testNewNullRevision_badPage() {
622  $dbw = wfGetDB( DB_MASTER );
623  $rev = Revision::newNullRevision( $dbw, -1, 'a null revision', false );
624 
625  $this->assertNull( $rev );
626  }
627 
631  public function testInsertOn() {
632  $ip = '2600:387:ed7:947e:8c16:a1ad:dd34:1dd7';
633 
634  $orig = $this->makeRevisionWithProps( [
635  'user_text' => $ip
636  ] );
637 
638  // Make sure the revision was copied to ip_changes
639  $dbr = wfGetDB( DB_REPLICA );
640  $res = $dbr->select( 'ip_changes', '*', [ 'ipc_rev_id' => $orig->getId() ] );
641  $row = $res->fetchObject();
642 
643  $this->assertEquals( IP::toHex( $ip ), $row->ipc_hex );
644  $this->assertEquals(
645  $orig->getTimestamp(),
646  wfTimestamp( TS_MW, $row->ipc_rev_timestamp )
647  );
648  }
649 
650  public static function provideUserWasLastToEdit() {
651  yield 'actually the last edit' => [ 3, true ];
652  yield 'not the current edit, but still by this user' => [ 2, true ];
653  yield 'edit by another user' => [ 1, false ];
654  yield 'first edit, by this user, but another user edited in the mean time' => [ 0, false ];
655  }
656 
661  public function testUserWasLastToEdit( $sinceIdx, $expectedLast ) {
662  $userA = User::newFromName( "RevisionStorageTest_userA" );
663  $userB = User::newFromName( "RevisionStorageTest_userB" );
664 
665  if ( $userA->getId() === 0 ) {
666  $userA = User::createNew( $userA->getName() );
667  }
668 
669  if ( $userB->getId() === 0 ) {
670  $userB = User::createNew( $userB->getName() );
671  }
672 
673  $ns = $this->getDefaultWikitextNS();
674 
675  $dbw = wfGetDB( DB_MASTER );
676  $revisions = [];
677 
678  // create revisions -----------------------------
680  'RevisionStorageTest_testUserWasLastToEdit', $ns ) );
681  $page->insertOn( $dbw );
682 
683  $revisions[0] = new Revision( [
684  'page' => $page->getId(),
685  // we need the title to determine the page's default content model
686  'title' => $page->getTitle(),
687  'timestamp' => '20120101000000',
688  'user' => $userA->getId(),
689  'text' => 'zero',
690  'content_model' => CONTENT_MODEL_WIKITEXT,
691  'comment' => 'edit zero'
692  ] );
693  $revisions[0]->insertOn( $dbw );
694 
695  $revisions[1] = new Revision( [
696  'page' => $page->getId(),
697  // still need the title, because $page->getId() is 0 (there's no entry in the page table)
698  'title' => $page->getTitle(),
699  'timestamp' => '20120101000100',
700  'user' => $userA->getId(),
701  'text' => 'one',
702  'content_model' => CONTENT_MODEL_WIKITEXT,
703  'comment' => 'edit one'
704  ] );
705  $revisions[1]->insertOn( $dbw );
706 
707  $revisions[2] = new Revision( [
708  'page' => $page->getId(),
709  'title' => $page->getTitle(),
710  'timestamp' => '20120101000200',
711  'user' => $userB->getId(),
712  'text' => 'two',
713  'content_model' => CONTENT_MODEL_WIKITEXT,
714  'comment' => 'edit two'
715  ] );
716  $revisions[2]->insertOn( $dbw );
717 
718  $revisions[3] = new Revision( [
719  'page' => $page->getId(),
720  'title' => $page->getTitle(),
721  'timestamp' => '20120101000300',
722  'user' => $userA->getId(),
723  'text' => 'three',
724  'content_model' => CONTENT_MODEL_WIKITEXT,
725  'comment' => 'edit three'
726  ] );
727  $revisions[3]->insertOn( $dbw );
728 
729  $revisions[4] = new Revision( [
730  'page' => $page->getId(),
731  'title' => $page->getTitle(),
732  'timestamp' => '20120101000200',
733  'user' => $userA->getId(),
734  'text' => 'zero',
735  'content_model' => CONTENT_MODEL_WIKITEXT,
736  'comment' => 'edit four'
737  ] );
738  $revisions[4]->insertOn( $dbw );
739 
740  // test it ---------------------------------
741  $since = $revisions[$sinceIdx]->getTimestamp();
742 
744  $allRows = iterator_to_array( $dbw->select(
745  $revQuery['tables'],
746  [ 'rev_id', 'rev_timestamp', 'rev_user' => $revQuery['fields']['rev_user'] ],
747  [
748  'rev_page' => $page->getId(),
749  //'rev_timestamp > ' . $dbw->addQuotes( $dbw->timestamp( $since ) )
750  ],
751  __METHOD__,
752  [ 'ORDER BY' => 'rev_timestamp ASC', 'LIMIT' => 50 ],
753  $revQuery['joins']
754  ) );
755 
756  $wasLast = Revision::userWasLastToEdit( $dbw, $page->getId(), $userA->getId(), $since );
757 
758  $this->assertEquals( $expectedLast, $wasLast );
759  }
760 
769  private function newTestRevision( $text, $title = "Test",
770  $model = CONTENT_MODEL_WIKITEXT, $format = null
771  ) {
772  if ( is_string( $title ) ) {
774  }
775 
776  $content = ContentHandler::makeContent( $text, $title, $model, $format );
777 
778  $rev = new Revision(
779  [
780  'id' => 42,
781  'page' => 23,
782  'title' => $title,
783 
784  'content' => $content,
785  'length' => $content->getSize(),
786  'comment' => "testing",
787  'minor_edit' => false,
788 
789  'content_format' => $format,
790  ]
791  );
792 
793  return $rev;
794  }
795 
796  public function provideGetContentModel() {
797  // NOTE: we expect the help namespace to always contain wikitext
798  return [
799  [ 'hello world', 'Help:Hello', null, null, CONTENT_MODEL_WIKITEXT ],
800  [ 'hello world', 'User:hello/there.css', null, null, CONTENT_MODEL_CSS ],
801  [ serialize( 'hello world' ), 'Dummy:Hello', null, null, DummyContentForTesting::MODEL_ID ],
802  ];
803  }
804 
809  public function testGetContentModel( $text, $title, $model, $format, $expectedModel ) {
810  $rev = $this->newTestRevision( $text, $title, $model, $format );
811 
812  $this->assertEquals( $expectedModel, $rev->getContentModel() );
813  }
814 
815  public function provideGetContentFormat() {
816  // NOTE: we expect the help namespace to always contain wikitext
817  return [
818  [ 'hello world', 'Help:Hello', null, null, CONTENT_FORMAT_WIKITEXT ],
819  [ 'hello world', 'Help:Hello', CONTENT_MODEL_CSS, null, CONTENT_FORMAT_CSS ],
820  [ 'hello world', 'User:hello/there.css', null, null, CONTENT_FORMAT_CSS ],
821  [ serialize( 'hello world' ), 'Dummy:Hello', null, null, DummyContentForTesting::MODEL_ID ],
822  ];
823  }
824 
829  public function testGetContentFormat( $text, $title, $model, $format, $expectedFormat ) {
830  $rev = $this->newTestRevision( $text, $title, $model, $format );
831 
832  $this->assertEquals( $expectedFormat, $rev->getContentFormat() );
833  }
834 
835  public function provideGetContentHandler() {
836  // NOTE: we expect the help namespace to always contain wikitext
837  return [
838  [ 'hello world', 'Help:Hello', null, null, WikitextContentHandler::class ],
839  [ 'hello world', 'User:hello/there.css', null, null, CssContentHandler::class ],
840  [ serialize( 'hello world' ), 'Dummy:Hello', null, null, DummyContentHandlerForTesting::class ],
841  ];
842  }
843 
848  public function testGetContentHandler( $text, $title, $model, $format, $expectedClass ) {
849  $rev = $this->newTestRevision( $text, $title, $model, $format );
850 
851  $this->assertEquals( $expectedClass, get_class( $rev->getContentHandler() ) );
852  }
853 
854  public function provideGetContent() {
855  // NOTE: we expect the help namespace to always contain wikitext
856  return [
857  [ 'hello world', 'Help:Hello', null, null, Revision::FOR_PUBLIC, 'hello world' ],
858  [
859  serialize( 'hello world' ),
860  'Hello',
862  null,
864  serialize( 'hello world' )
865  ],
866  [
867  serialize( 'hello world' ),
868  'Dummy:Hello',
869  null,
870  null,
872  serialize( 'hello world' )
873  ],
874  ];
875  }
876 
881  public function testGetContent( $text, $title, $model, $format,
882  $audience, $expectedSerialization
883  ) {
884  $rev = $this->newTestRevision( $text, $title, $model, $format );
885  $content = $rev->getContent( $audience );
886 
887  $this->assertEquals(
888  $expectedSerialization,
889  is_null( $content ) ? null : $content->serialize( $format )
890  );
891  }
892 
896  public function testGetContent_failure() {
897  $rev = new Revision( [
898  'page' => $this->testPage->getId(),
899  'content_model' => $this->testPage->getContentModel(),
900  'text_id' => 123456789, // not in the test DB
901  ] );
902 
903  Wikimedia\suppressWarnings(); // bad text_id will trigger a warning.
904 
905  $this->assertNull( $rev->getContent(),
906  "getContent() should return null if the revision's text blob could not be loaded." );
907 
908  // NOTE: check this twice, once for lazy initialization, and once with the cached value.
909  $this->assertNull( $rev->getContent(),
910  "getContent() should return null if the revision's text blob could not be loaded." );
911 
912  Wikimedia\restoreWarnings();
913  }
914 
915  public function provideGetSize() {
916  return [
917  [ "hello world.", CONTENT_MODEL_WIKITEXT, 12 ],
918  [ serialize( "hello world." ), DummyContentForTesting::MODEL_ID, 12 ],
919  ];
920  }
921 
926  public function testGetSize( $text, $model, $expected_size ) {
927  $rev = $this->newTestRevision( $text, 'RevisionTest_testGetSize', $model );
928  $this->assertEquals( $expected_size, $rev->getSize() );
929  }
930 
931  public function provideGetSha1() {
932  return [
933  [ "hello world.", CONTENT_MODEL_WIKITEXT, Revision::base36Sha1( "hello world." ) ],
934  [
935  serialize( "hello world." ),
937  Revision::base36Sha1( serialize( "hello world." ) )
938  ],
939  ];
940  }
941 
946  public function testGetSha1( $text, $model, $expected_hash ) {
947  $rev = $this->newTestRevision( $text, 'RevisionTest_testGetSha1', $model );
948  $this->assertEquals( $expected_hash, $rev->getSha1() );
949  }
950 
956  public function testGetContentClone() {
957  $content = new RevisionTestModifyableContent( "foo" );
958 
959  $rev = new Revision(
960  [
961  'id' => 42,
962  'page' => 23,
963  'title' => Title::newFromText( "testGetContentClone_dummy" ),
964 
965  'content' => $content,
966  'length' => $content->getSize(),
967  'comment' => "testing",
968  'minor_edit' => false,
969  ]
970  );
971 
973  $content = $rev->getContent( Revision::RAW );
974  $content->setText( "bar" );
975 
977  $content2 = $rev->getContent( Revision::RAW );
978  // content is mutable, expect clone
979  $this->assertNotSame( $content, $content2, "expected a clone" );
980  // clone should contain the original text
981  $this->assertEquals( "foo", $content2->getText() );
982 
983  $content2->setText( "bla bla" );
984  // clones should be independent
985  $this->assertEquals( "bar", $content->getText() );
986  }
987 
992  public function testGetContentUncloned() {
993  $rev = $this->newTestRevision( "hello", "testGetContentUncloned_dummy", CONTENT_MODEL_WIKITEXT );
994  $content = $rev->getContent( Revision::RAW );
995  $content2 = $rev->getContent( Revision::RAW );
996 
997  // for immutable content like wikitext, this should be the same object
998  $this->assertSame( $content, $content2 );
999  }
1000 
1004  public function testLoadFromId() {
1005  $rev = $this->testPage->getRevision();
1006  $this->hideDeprecated( 'Revision::loadFromId' );
1007  $this->assertRevEquals(
1008  $rev,
1009  Revision::loadFromId( wfGetDB( DB_MASTER ), $rev->getId() )
1010  );
1011  }
1012 
1016  public function testLoadFromPageId() {
1017  $this->assertRevEquals(
1018  $this->testPage->getRevision(),
1019  Revision::loadFromPageId( wfGetDB( DB_MASTER ), $this->testPage->getId() )
1020  );
1021  }
1022 
1027  $this->assertRevEquals(
1028  $this->testPage->getRevision(),
1030  wfGetDB( DB_MASTER ),
1031  $this->testPage->getId(),
1032  $this->testPage->getLatest()
1033  )
1034  );
1035  }
1036 
1041  $this->testPage->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ );
1042  $this->assertRevEquals(
1043  $this->testPage->getRevision()->getPrevious(),
1045  wfGetDB( DB_MASTER ),
1046  $this->testPage->getId(),
1047  $this->testPage->getRevision()->getPrevious()->getId()
1048  )
1049  );
1050  }
1051 
1055  public function testLoadFromTitle() {
1056  $this->assertRevEquals(
1057  $this->testPage->getRevision(),
1058  Revision::loadFromTitle( wfGetDB( DB_MASTER ), $this->testPage->getTitle() )
1059  );
1060  }
1061 
1066  $this->assertRevEquals(
1067  $this->testPage->getRevision(),
1069  wfGetDB( DB_MASTER ),
1070  $this->testPage->getTitle(),
1071  $this->testPage->getLatest()
1072  )
1073  );
1074  }
1075 
1080  $this->testPage->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ );
1081  $this->assertRevEquals(
1082  $this->testPage->getRevision()->getPrevious(),
1084  wfGetDB( DB_MASTER ),
1085  $this->testPage->getTitle(),
1086  $this->testPage->getRevision()->getPrevious()->getId()
1087  )
1088  );
1089  }
1090 
1094  public function testLoadFromTimestamp() {
1095  $this->assertRevEquals(
1096  $this->testPage->getRevision(),
1098  wfGetDB( DB_MASTER ),
1099  $this->testPage->getTitle(),
1100  $this->testPage->getRevision()->getTimestamp()
1101  )
1102  );
1103  }
1104 
1108  public function testGetParentLengths_noRevIds() {
1109  $this->assertSame(
1110  [],
1112  wfGetDB( DB_MASTER ),
1113  []
1114  )
1115  );
1116  }
1117 
1121  public function testGetParentLengths_oneRevId() {
1122  $text = '831jr091jr0921kr21kr0921kjr0921j09rj1';
1123  $textLength = strlen( $text );
1124 
1125  $this->testPage->doEditContent( new WikitextContent( $text ), __METHOD__ );
1126  $rev[1] = $this->testPage->getLatest();
1127 
1128  $this->assertSame(
1129  [ $rev[1] => $textLength ],
1131  wfGetDB( DB_MASTER ),
1132  [ $rev[1] ]
1133  )
1134  );
1135  }
1136 
1141  $textOne = '831jr091jr0921kr21kr0921kjr0921j09rj1';
1142  $textOneLength = strlen( $textOne );
1143  $textTwo = '831jr091jr092121j09rj1';
1144  $textTwoLength = strlen( $textTwo );
1145 
1146  $this->testPage->doEditContent( new WikitextContent( $textOne ), __METHOD__ );
1147  $rev[1] = $this->testPage->getLatest();
1148  $this->testPage->doEditContent( new WikitextContent( $textTwo ), __METHOD__ );
1149  $rev[2] = $this->testPage->getLatest();
1150 
1151  $this->assertSame(
1152  [ $rev[1] => $textOneLength, $rev[2] => $textTwoLength ],
1154  wfGetDB( DB_MASTER ),
1155  [ $rev[1], $rev[2] ]
1156  )
1157  );
1158  }
1159 
1164  $this->assertTrue(
1165  $this->testPage->getTitle()->equals(
1166  $this->testPage->getRevision()->getTitle()
1167  )
1168  );
1169  }
1170 
1175  $rev = new Revision( [ 'id' => $this->testPage->getLatest() ] );
1176  $this->assertTrue(
1177  $this->testPage->getTitle()->equals(
1178  $rev->getTitle()
1179  )
1180  );
1181  }
1182 
1186  public function testIsMinor_true() {
1187  // Use a sysop to ensure we can mark edits as minor
1188  $sysop = $this->getTestSysop()->getUser();
1189 
1190  $this->testPage->doEditContent(
1191  new WikitextContent( __METHOD__ ),
1192  __METHOD__,
1193  EDIT_MINOR,
1194  false,
1195  $sysop
1196  );
1197  $rev = $this->testPage->getRevision();
1198 
1199  $this->assertSame( true, $rev->isMinor() );
1200  }
1201 
1205  public function testIsMinor_false() {
1206  $this->testPage->doEditContent(
1207  new WikitextContent( __METHOD__ ),
1208  __METHOD__,
1209  0
1210  );
1211  $rev = $this->testPage->getRevision();
1212 
1213  $this->assertSame( false, $rev->isMinor() );
1214  }
1215 
1219  public function testGetTimestamp() {
1220  $testTimestamp = wfTimestampNow();
1221 
1222  $this->testPage->doEditContent(
1223  new WikitextContent( __METHOD__ ),
1224  __METHOD__
1225  );
1226  $rev = $this->testPage->getRevision();
1227 
1228  $this->assertInternalType( 'string', $rev->getTimestamp() );
1229  $this->assertTrue( strlen( $rev->getTimestamp() ) == strlen( 'YYYYMMDDHHMMSS' ) );
1230  $this->assertContains( substr( $testTimestamp, 0, 10 ), $rev->getTimestamp() );
1231  }
1232 
1237  public function testGetUserAndText() {
1238  $sysop = $this->getTestSysop()->getUser();
1239 
1240  $this->testPage->doEditContent(
1241  new WikitextContent( __METHOD__ ),
1242  __METHOD__,
1243  0,
1244  false,
1245  $sysop
1246  );
1247  $rev = $this->testPage->getRevision();
1248 
1249  $this->assertSame( $sysop->getId(), $rev->getUser() );
1250  $this->assertSame( $sysop->getName(), $rev->getUserText() );
1251  }
1252 
1256  public function testIsDeleted_nothingDeleted() {
1257  $rev = $this->testPage->getRevision();
1258 
1259  $this->assertSame( false, $rev->isDeleted( Revision::DELETED_TEXT ) );
1260  $this->assertSame( false, $rev->isDeleted( Revision::DELETED_COMMENT ) );
1261  $this->assertSame( false, $rev->isDeleted( Revision::DELETED_RESTRICTED ) );
1262  $this->assertSame( false, $rev->isDeleted( Revision::DELETED_USER ) );
1263  }
1264 
1269  $rev = $this->testPage->getRevision();
1270 
1271  $this->assertSame( 0, $rev->getVisibility() );
1272  }
1273 
1277  public function testGetComment_notDeleted() {
1278  $expectedSummary = 'goatlicious summary';
1279 
1280  $this->testPage->doEditContent(
1281  new WikitextContent( __METHOD__ ),
1282  $expectedSummary
1283  );
1284  $rev = $this->testPage->getRevision();
1285 
1286  $this->assertSame( $expectedSummary, $rev->getComment() );
1287  }
1288 
1293  $this->testPage->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ );
1294  $rev = $this->testPage->getRevision();
1295 
1296  $this->assertGreaterThan( 0, $rev->isUnpatrolled() );
1297  $this->assertSame( $rev->getRecentChange()->getAttribute( 'rc_id' ), $rev->isUnpatrolled() );
1298  }
1299 
1304  // This assumes that sysops are auto patrolled
1305  $sysop = $this->getTestSysop()->getUser();
1306  $this->testPage->doEditContent(
1307  new WikitextContent( __METHOD__ ),
1308  __METHOD__,
1309  0,
1310  false,
1311  $sysop
1312  );
1313  $rev = $this->testPage->getRevision();
1314 
1315  $this->assertSame( 0, $rev->isUnpatrolled() );
1316  }
1317 
1327  public function testSimpleContentGetters() {
1328  $expectedText = 'testSimpleContentGetters in Revision. Goats love MCR...';
1329  $expectedSummary = 'goatlicious testSimpleContentGetters summary';
1330 
1331  $this->testPage->doEditContent(
1332  new WikitextContent( $expectedText ),
1333  $expectedSummary
1334  );
1335  $rev = $this->testPage->getRevision();
1336 
1337  $this->assertSame( $expectedText, $rev->getContent()->getNativeData() );
1338  $this->assertSame( $expectedText, $rev->getSerializedData() );
1339  $this->assertSame( $this->testPage->getContentModel(), $rev->getContentModel() );
1340  $this->assertSame( $this->testPage->getContent()->getDefaultFormat(), $rev->getContentFormat() );
1341  $this->assertSame( $this->testPage->getContentHandler(), $rev->getContentHandler() );
1342  }
1343 
1347  public function testNewKnownCurrent() {
1348  // Setup the services
1349  $cache = new WANObjectCache( [ 'cache' => new HashBagOStuff() ] );
1350  $this->setService( 'MainWANObjectCache', $cache );
1351  $db = wfGetDB( DB_MASTER );
1352 
1353  // Get a fresh revision to use during testing
1354  $this->testPage->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ );
1355  $rev = $this->testPage->getRevision();
1356 
1357  // Clear any previous cache for the revision during creation
1358  $key = $cache->makeGlobalKey( 'revision-row-1.29',
1359  $db->getDomainID(),
1360  $rev->getPage(),
1361  $rev->getId()
1362  );
1363  $cache->delete( $key, WANObjectCache::HOLDOFF_NONE );
1364  $this->assertFalse( $cache->get( $key ) );
1365 
1366  // Get the new revision and make sure it is in the cache and correct
1367  $newRev = Revision::newKnownCurrent( $db, $rev->getPage(), $rev->getId() );
1368  $this->assertRevEquals( $rev, $newRev );
1369 
1370  $cachedRow = $cache->get( $key );
1371  $this->assertNotFalse( $cachedRow );
1372  $this->assertEquals( $rev->getId(), $cachedRow->rev_id );
1373  }
1374 
1376  $db = wfGetDB( DB_MASTER );
1377 
1378  $this->testPage->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ );
1379  $rev = $this->testPage->getRevision();
1380 
1381  $pageId = $this->testPage->getId();
1382 
1383  $newRev = Revision::newKnownCurrent( $db, $pageId, $rev->getId() );
1384  $this->assertRevEquals( $rev, $newRev );
1385  }
1386 
1388  $db = wfGetDB( DB_MASTER );
1389 
1390  $this->assertFalse( Revision::newKnownCurrent( $db, 0 ) );
1391  }
1392 
1393  public function provideUserCanBitfield() {
1394  yield [ 0, 0, [], null, true ];
1395  // Bitfields match, user has no permissions
1396  yield [ Revision::DELETED_TEXT, Revision::DELETED_TEXT, [], null, false ];
1398  yield [ Revision::DELETED_USER, Revision::DELETED_USER, [], null, false ];
1400  // Bitfields match, user (admin) does have permissions
1401  yield [ Revision::DELETED_TEXT, Revision::DELETED_TEXT, [ 'sysop' ], null, true ];
1402  yield [ Revision::DELETED_COMMENT, Revision::DELETED_COMMENT, [ 'sysop' ], null, true ];
1403  yield [ Revision::DELETED_USER, Revision::DELETED_USER, [ 'sysop' ], null, true ];
1404  // Bitfields match, user (admin) does not have permissions
1405  yield [ Revision::DELETED_RESTRICTED, Revision::DELETED_RESTRICTED, [ 'sysop' ], null, false ];
1406  // Bitfields match, user (oversight) does have permissions
1407  yield [ Revision::DELETED_RESTRICTED, Revision::DELETED_RESTRICTED, [ 'oversight' ], null, true ];
1408  // Check permissions using the title
1409  yield [
1412  [ 'sysop' ],
1413  Title::newFromText( __METHOD__ ),
1414  true,
1415  ];
1416  yield [
1419  [],
1420  Title::newFromText( __METHOD__ ),
1421  false,
1422  ];
1423  }
1424 
1429  public function testUserCanBitfield( $bitField, $field, $userGroups, $title, $expected ) {
1430  $this->setMwGlobals(
1431  'wgGroupPermissions',
1432  [
1433  'sysop' => [
1434  'deletedtext' => true,
1435  'deletedhistory' => true,
1436  ],
1437  'oversight' => [
1438  'viewsuppressed' => true,
1439  'suppressrevision' => true,
1440  ],
1441  ]
1442  );
1443  $user = $this->getTestUser( $userGroups )->getUser();
1444 
1445  $this->assertSame(
1446  $expected,
1447  Revision::userCanBitfield( $bitField, $field, $user, $title )
1448  );
1449 
1450  // Fallback to $wgUser
1451  $this->setMwGlobals(
1452  'wgUser',
1453  $user
1454  );
1455  $this->assertSame(
1456  $expected,
1457  Revision::userCanBitfield( $bitField, $field, null, $title )
1458  );
1459  }
1460 
1461  public function provideUserCan() {
1462  yield [ 0, 0, [], true ];
1463  // Bitfields match, user has no permissions
1468  // Bitfields match, user (admin) does have permissions
1469  yield [ Revision::DELETED_TEXT, Revision::DELETED_TEXT, [ 'sysop' ], true ];
1470  yield [ Revision::DELETED_COMMENT, Revision::DELETED_COMMENT, [ 'sysop' ], true ];
1471  yield [ Revision::DELETED_USER, Revision::DELETED_USER, [ 'sysop' ], true ];
1472  // Bitfields match, user (admin) does not have permissions
1474  // Bitfields match, user (oversight) does have permissions
1475  yield [ Revision::DELETED_RESTRICTED, Revision::DELETED_RESTRICTED, [ 'oversight' ], true ];
1476  }
1477 
1482  public function testUserCan( $bitField, $field, $userGroups, $expected ) {
1483  $this->setMwGlobals(
1484  'wgGroupPermissions',
1485  [
1486  'sysop' => [
1487  'deletedtext' => true,
1488  'deletedhistory' => true,
1489  ],
1490  'oversight' => [
1491  'viewsuppressed' => true,
1492  'suppressrevision' => true,
1493  ],
1494  ]
1495  );
1496  $user = $this->getTestUser( $userGroups )->getUser();
1497  $revision = new Revision( [ 'deleted' => $bitField ], 0, $this->testPage->getTitle() );
1498 
1499  $this->assertSame(
1500  $expected,
1501  $revision->userCan( $field, $user )
1502  );
1503  }
1504 
1505 }
Revision\FOR_PUBLIC
const FOR_PUBLIC
Definition: Revision.php:55
Revision\newFromArchiveRow
static newFromArchiveRow( $row, $overrides=[])
Make a fake revision object from an archive table row.
Definition: Revision.php:167
$user
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a account $user
Definition: hooks.txt:247
Revision\DELETED_USER
const DELETED_USER
Definition: Revision.php:49
IP\toHex
static toHex( $ip)
Return a zero-padded upper case hexadecimal representation of an IP address.
Definition: IP.php:417
Revision\getTimestamp
getTimestamp()
Definition: Revision.php:1008
Revision\DELETED_RESTRICTED
const DELETED_RESTRICTED
Definition: Revision.php:50
RevisionDbTestBase\assertRevEquals
assertRevEquals(Revision $orig, Revision $rev=null)
Definition: RevisionDbTestBase.php:169
Revision\newKnownCurrent
static newKnownCurrent(IDatabase $db, $pageIdOrTitle, $revId=0)
Load a revision based on a known page ID and current revision ID from the DB.
Definition: Revision.php:1288
Title\newFromText
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:273
MediaWiki\Storage\RevisionStore
Service for looking up page revisions.
Definition: RevisionStore.php:69
RevisionDbTestBase\testGetContent_failure
testGetContent_failure()
Revision::getContent.
Definition: RevisionDbTestBase.php:896
RevisionDbTestBase\testNewFromPageIdWithNotLatestId
testNewFromPageIdWithNotLatestId()
Revision::newFromPageId.
Definition: RevisionDbTestBase.php:494
Revision\DELETED_COMMENT
const DELETED_COMMENT
Definition: Revision.php:48
RevisionDbTestBase\testNewFromArchiveRow
testNewFromArchiveRow( $selectModifier)
provideNewFromArchiveRow Revision::newFromArchiveRow
Definition: RevisionDbTestBase.php:387
RevisionDbTestBase\testSimpleContentGetters
testSimpleContentGetters()
This is a simple blanket test for all simple content getters and is methods to provide some coverage ...
Definition: RevisionDbTestBase.php:1327
use
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
Definition: APACHE-LICENSE-2.0.txt:10
Revision\newFromId
static newFromId( $id, $flags=0)
Load a page revision from a given revision ID number.
Definition: Revision.php:114
RevisionDbTestBase\testUserWasLastToEdit
testUserWasLastToEdit( $sinceIdx, $expectedLast)
Revision::userWasLastToEdit provideUserWasLastToEdit.
Definition: RevisionDbTestBase.php:661
RevisionDbTestBase\testGetTimestamp
testGetTimestamp()
Revision::getTimestamp.
Definition: RevisionDbTestBase.php:1219
Revision\getUser
getUser( $audience=self::FOR_PUBLIC, User $user=null)
Fetch revision's user id if it's available to the specified audience.
Definition: Revision.php:778
$rows
do that in ParserLimitReportFormat instead use this to modify the parameters of the image all existing parser cache entries will be invalid To avoid you ll need to handle that somehow(e.g. with the RejectParserCacheValue hook) because MediaWiki won 't do it for you. & $defaults also a ContextSource after deleting those rows but within the same transaction $rows
Definition: hooks.txt:2783
MediaWikiTestCase\mergeMwGlobalArrayValue
mergeMwGlobalArrayValue( $name, $values)
Merges the given values into a MW global array variable.
Definition: MediaWikiTestCase.php:813
HashBagOStuff
Simple store for keeping values in an associative array for the current process.
Definition: HashBagOStuff.php:31
Revision\userCanBitfield
static userCanBitfield( $bitfield, $field, User $user=null, Title $title=null)
Determine if the current user is allowed to view a particular field of this revision,...
Definition: Revision.php:1205
MediaWikiTestCase\getTestUser
static getTestUser( $groups=[])
Convenience method for getting an immutable test user.
Definition: MediaWikiTestCase.php:153
RevisionDbTestBase\testIsUnpatrolled_returnsZeroIfPatrolled
testIsUnpatrolled_returnsZeroIfPatrolled()
Revision::isUnpatrolled.
Definition: RevisionDbTestBase.php:1303
array
the array() calling protocol came about after MediaWiki 1.4rc1.
RevisionDbTestBase\testLoadFromTitle
testLoadFromTitle()
Revision::loadFromTitle.
Definition: RevisionDbTestBase.php:1055
RevisionDbTestBase\testGetVisibility_nothingDeleted
testGetVisibility_nothingDeleted()
Revision::getVisibility.
Definition: RevisionDbTestBase.php:1268
RevisionDbTestBase\testFetchRevision
testFetchRevision()
Revision::fetchRevision.
Definition: RevisionDbTestBase.php:510
RevisionDbTestBase\testGetPage
testGetPage()
Revision::getPage.
Definition: RevisionDbTestBase.php:532
RevisionDbTestBase\provideGetContentModel
provideGetContentModel()
Definition: RevisionDbTestBase.php:796
CONTENT_MODEL_CSS
const CONTENT_MODEL_CSS
Definition: Defines.php:247
RevisionDbTestBase\testGetContentHandler
testGetContentHandler( $text, $title, $model, $format, $expectedClass)
provideGetContentHandler Revision::getContentHandler
Definition: RevisionDbTestBase.php:848
RevisionDbTestBase\setUp
setUp()
Definition: RevisionDbTestBase.php:46
wfTimestamp
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Definition: GlobalFunctions.php:1980
RevisionDbTestBase\testNewFromTitle_withoutId
testNewFromTitle_withoutId()
Revision::newFromTitle.
Definition: RevisionDbTestBase.php:288
Revision\getPage
getPage()
Get the page ID.
Definition: Revision.php:761
WikiPage
Class representing a MediaWiki article and history.
Definition: WikiPage.php:37
RevisionDbTestBase\provideGetSha1
provideGetSha1()
Definition: RevisionDbTestBase.php:931
serialize
serialize()
Definition: ApiMessage.php:184
User\newFromName
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition: User.php:591
CONTENT_FORMAT_CSS
const CONTENT_FORMAT_CSS
Definition: Defines.php:264
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
$res
$res
Definition: database.txt:21
CONTENT_MODEL_WIKITEXT
const CONTENT_MODEL_WIKITEXT
Definition: Defines.php:245
Revision\newFromPageId
static newFromPageId( $pageId, $revId=0, $flags=0)
Load either the current, or a specified, revision that's attached to a given page ID.
Definition: Revision.php:152
Revision\getSha1
getSha1()
Returns the base36 sha1 of the content in this revision, or null if unknown.
Definition: Revision.php:718
Revision\loadFromId
static loadFromId( $db, $id)
Load a page revision from a given revision ID number.
Definition: Revision.php:238
Revision\getId
getId()
Get revision ID.
Definition: Revision.php:617
RevisionDbTestBase\testGetTitle_fromRevisionWhichWillLoadTheTitle
testGetTitle_fromRevisionWhichWillLoadTheTitle()
Revision::getTitle.
Definition: RevisionDbTestBase.php:1174
Revision\getContentModel
getContentModel()
Returns the content model for the main slot of this revision.
Definition: Revision.php:969
RevisionDbTestBase\testGetContent
testGetContent( $text, $title, $model, $format, $audience, $expectedSerialization)
provideGetContent Revision::getContent
Definition: RevisionDbTestBase.php:881
Revision\base36Sha1
static base36Sha1( $text)
Get the base 36 SHA-1 value for a string of text.
Definition: Revision.php:1140
$revQuery
$revQuery
Definition: testCompression.php:51
RevisionDbTestBase\testIsDeleted_nothingDeleted
testIsDeleted_nothingDeleted()
Revision::isDeleted.
Definition: RevisionDbTestBase.php:1256
RevisionDbTestBase\testGetContentUncloned
testGetContentUncloned()
Tests whether $rev->getContent() returns the same object repeatedly if appropriate.
Definition: RevisionDbTestBase.php:992
true
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 noclasses just before the function returns a value If you return true
Definition: hooks.txt:2006
RevisionDbTestBase\makeRevisionWithProps
makeRevisionWithProps( $props=null)
Definition: RevisionDbTestBase.php:101
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:37
RevisionDbTestBase\testNewKnownCurrent_withPageId
testNewKnownCurrent_withPageId()
Definition: RevisionDbTestBase.php:1375
RevisionDbTestBase\testLoadFromPageIdWithNotLatestRevId
testLoadFromPageIdWithNotLatestRevId()
Revision::loadFromPageId.
Definition: RevisionDbTestBase.php:1040
RevisionDbTestBase\testGetSize
testGetSize( $text, $model, $expected_size)
Revision::getSize provideGetSize.
Definition: RevisionDbTestBase.php:926
RevisionDbTestBase\testNewFromArchiveRowOverrides
testNewFromArchiveRowOverrides()
Revision::newFromArchiveRow.
Definition: RevisionDbTestBase.php:431
User\createNew
static createNew( $name, $params=[])
Add a user to the database, return the user object.
Definition: User.php:4297
RevisionDbTestBase\testLoadFromTitleWithNotLatestRevId
testLoadFromTitleWithNotLatestRevId()
Revision::loadFromTitle.
Definition: RevisionDbTestBase.php:1079
$dbr
$dbr
Definition: testCompression.php:50
RevisionDbTestBase\testNewFromPageId
testNewFromPageId()
Revision::newFromPageId.
Definition: RevisionDbTestBase.php:469
Revision
Definition: Revision.php:41
MWNamespace\clearCaches
static clearCaches()
Clear internal caches.
Definition: MWNamespace.php:76
RevisionDbTestBase\testIsMinor_false
testIsMinor_false()
Revision::isMinor.
Definition: RevisionDbTestBase.php:1205
Revision\newFromTitle
static newFromTitle(LinkTarget $linkTarget, $id=0, $flags=0)
Load either the current, or a specified, revision that's attached to a given link target.
Definition: Revision.php:133
RevisionDbTestBase\testLoadFromTimestamp
testLoadFromTimestamp()
Revision::loadFromTimestamp()
Definition: RevisionDbTestBase.php:1094
RevisionDbTestBase\$testPage
$testPage
Definition: RevisionDbTestBase.php:18
RevisionDbTestBase\testLoadFromId
testLoadFromId()
Revision::loadFromId.
Definition: RevisionDbTestBase.php:1004
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
WikiPage\factory
static factory(Title $title)
Create a WikiPage object of the appropriate class for the given title.
Definition: WikiPage.php:115
RevisionDbTestBase\testGetParentLengths_multipleRevIds
testGetParentLengths_multipleRevIds()
Revision::getParentLengths.
Definition: RevisionDbTestBase.php:1140
RevisionDbTestBase\testNewFromPageIdWithLatestId
testNewFromPageIdWithLatestId()
Revision::newFromPageId.
Definition: RevisionDbTestBase.php:480
RevisionDbTestBase\testGetSha1
testGetSha1( $text, $model, $expected_hash)
Revision::getSha1 provideGetSha1.
Definition: RevisionDbTestBase.php:946
wfGetDB
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
Definition: GlobalFunctions.php:2812
RevisionDbTestBase\testNewNullRevision_badPage
testNewNullRevision_badPage()
Revision::newNullRevision.
Definition: RevisionDbTestBase.php:621
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
RevisionDbTestBase\testNewFromId
testNewFromId()
Revision::newFromId.
Definition: RevisionDbTestBase.php:460
MediaWikiTestCase
Definition: MediaWikiTestCase.php:17
Revision\loadFromPageId
static loadFromPageId( $db, $pageid, $id=0)
Load either the current, or a specified, revision that's attached to a given page.
Definition: Revision.php:256
MediaWikiTestCase\hideDeprecated
hideDeprecated( $function)
Don't throw a warning if $function is deprecated and called later.
Definition: MediaWikiTestCase.php:1675
RevisionDbTestBase\testNewNullRevision
testNewNullRevision()
Revision::newNullRevision.
Definition: RevisionDbTestBase.php:600
RevisionDbTestBase\testNewFromTitle_withBadId
testNewFromTitle_withBadId()
Revision::newFromTitle.
Definition: RevisionDbTestBase.php:312
RevisionDbTestBase\testGetTitle_fromExistingRevision
testGetTitle_fromExistingRevision()
Revision::getTitle.
Definition: RevisionDbTestBase.php:1163
MediaWikiTestCase\assertSelect
assertSelect( $table, $fields, $condition, array $expectedRows, array $options=[], array $join_conds=[])
Asserts that the given database query yields the rows given by $expectedRows.
Definition: MediaWikiTestCase.php:1701
RevisionDbTestBase\testInsertOn_success
testInsertOn_success()
Revision::insertOn.
Definition: RevisionDbTestBase.php:208
RevisionDbTestBase\testGetContentModel
testGetContentModel( $text, $title, $model, $format, $expectedModel)
provideGetContentModel Revision::getContentModel
Definition: RevisionDbTestBase.php:809
$title
namespace and then decline to actually register it file or subcat img or subcat $title
Definition: hooks.txt:964
MediaWikiTestCase\getDefaultWikitextNS
getDefaultWikitextNS()
Returns the ID of a namespace that defaults to Wikitext.
Definition: MediaWikiTestCase.php:1912
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:95
DB_REPLICA
const DB_REPLICA
Definition: defines.php:25
wfTimestampNow
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
Definition: GlobalFunctions.php:2009
DB_MASTER
const DB_MASTER
Definition: defines.php:29
WikitextContent
Content object for wiki text pages.
Definition: WikitextContent.php:33
CONTENT_FORMAT_WIKITEXT
const CONTENT_FORMAT_WIKITEXT
Definition: Defines.php:260
$services
static configuration should be added through ResourceLoaderGetConfigVars instead can be used to get the real title after the basic globals have been set but before ordinary actions take place or wrap services the preferred way to define a new service is the $wgServiceWiringFiles array $services
Definition: hooks.txt:2273
RevisionDbTestBase\testGetComment_notDeleted
testGetComment_notDeleted()
Revision::getComment.
Definition: RevisionDbTestBase.php:1277
ContentHandler\makeContent
static makeContent( $text, Title $title=null, $modelId=null, $format=null)
Convenience function for creating a Content object from a given textual representation.
Definition: ContentHandler.php:129
RevisionDbTestBase
RevisionDbTestBase contains test cases for the Revision class that have Database interactions.
Definition: RevisionDbTestBase.php:13
MediaWiki\Storage\RevisionRecord
Page revision base class.
Definition: RevisionRecord.php:44
RevisionDbTestBase\testLoadFromPageIdWithLatestRevId
testLoadFromPageIdWithLatestRevId()
Revision::loadFromPageId.
Definition: RevisionDbTestBase.php:1026
RevisionDbTestBase\provideGetContentFormat
provideGetContentFormat()
Definition: RevisionDbTestBase.php:815
Revision\userWasLastToEdit
static userWasLastToEdit( $db, $pageId, $userId, $since)
Check if no edits were made by other users since the time a user started editing the page.
Definition: Revision.php:1267
RevisionDbTestBase\testGetRecentChange
testGetRecentChange()
Revision::getRecentChange.
Definition: RevisionDbTestBase.php:184
RevisionDbTestBase\testInsertOn_exceptionOnNoPage
testInsertOn_exceptionOnNoPage()
Revision::insertOn.
Definition: RevisionDbTestBase.php:271
RevisionDbTestBase\createPage
createPage( $titleString, $text, $model=null)
Definition: RevisionDbTestBase.php:147
RevisionDbTestBase\testInsertOn
testInsertOn()
Revision::insertOn.
Definition: RevisionDbTestBase.php:631
Revision\getParentLengths
static getParentLengths( $db, array $revIds)
Do a batched query to get the parent revision lengths.
Definition: Revision.php:519
RevisionDbTestBase\testUserCanBitfield
testUserCanBitfield( $bitField, $field, $userGroups, $title, $expected)
provideUserCanBitfield Revision::userCanBitfield
Definition: RevisionDbTestBase.php:1429
WANObjectCache
Multi-datacenter aware caching interface.
Definition: WANObjectCache.php:87
RevisionDbTestBase\testNewKnownCurrent
testNewKnownCurrent()
Revision::newKnownCurrent.
Definition: RevisionDbTestBase.php:1347
RevisionDbTestBase\testNewFromRow
testNewFromRow()
Revision::newFromRow.
Definition: RevisionDbTestBase.php:323
RevisionDbTestBase\newTestRevision
newTestRevision( $text, $title="Test", $model=CONTENT_MODEL_WIKITEXT, $format=null)
Definition: RevisionDbTestBase.php:769
RevisionDbTestBase\provideNewFromArchiveRow
provideNewFromArchiveRow()
Definition: RevisionDbTestBase.php:340
Revision\newFromRow
static newFromRow( $row)
Definition: Revision.php:218
MediaWikiTestCase\getTestSysop
static getTestSysop()
Convenience method for getting an immutable admin test user.
Definition: MediaWikiTestCase.php:177
Revision\RAW
const RAW
Definition: Revision.php:57
RevisionDbTestBase\testIsUnpatrolled_returnsRecentChangesId
testIsUnpatrolled_returnsRecentChangesId()
Revision::isUnpatrolled.
Definition: RevisionDbTestBase.php:1292
Revision\getContentFormat
getContentFormat()
Returns the content format for the main slot of this revision.
Definition: Revision.php:984
DummyContentForTesting\MODEL_ID
const MODEL_ID
Definition: DummyContentForTesting.php:5
RevisionDbTestBase\testLoadFromTitleWithLatestRevId
testLoadFromTitleWithLatestRevId()
Revision::loadFromTitle.
Definition: RevisionDbTestBase.php:1065
EDIT_NEW
const EDIT_NEW
Definition: Defines.php:162
Revision\fetchRevision
static fetchRevision(LinkTarget $title)
Return a wrapper for a series of database rows to fetch all of a given page's revisions in turn.
Definition: Revision.php:305
$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:1777
RevisionDbTestBase\testNewFromTitle_withId
testNewFromTitle_withId()
Revision::newFromTitle.
Definition: RevisionDbTestBase.php:300
RevisionDbTestBase\testGetContentFormat
testGetContentFormat( $text, $title, $model, $format, $expectedFormat)
provideGetContentFormat Revision::getContentFormat
Definition: RevisionDbTestBase.php:829
RevisionDbTestBase\testGetPrevious
testGetPrevious()
Revision::getPrevious.
Definition: RevisionDbTestBase.php:569
$name
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:302
$cache
$cache
Definition: mcc.php:33
RevisionDbTestBase\tearDown
tearDown()
Definition: RevisionDbTestBase.php:89
RevisionDbTestBase\__construct
__construct( $name=null, array $data=[], $dataName='')
Definition: RevisionDbTestBase.php:20
RevisionDbTestBase\testUserCan
testUserCan( $bitField, $field, $userGroups, $expected)
provideUserCan Revision::userCan
Definition: RevisionDbTestBase.php:1482
MediaWiki\Storage\IncompleteRevisionException
Exception throw when trying to access undefined fields on an incomplete RevisionRecord.
Definition: IncompleteRevisionException.php:30
RevisionDbTestBase\provideUserWasLastToEdit
static provideUserWasLastToEdit()
Definition: RevisionDbTestBase.php:650
RevisionDbTestBase\getContentHandlerUseDB
getContentHandlerUseDB()
RevisionDbTestBase\testLoadFromPageId
testLoadFromPageId()
Revision::loadFromPageId.
Definition: RevisionDbTestBase.php:1016
Revision\loadFromTimestamp
static loadFromTimestamp( $db, $title, $timestamp)
Load the revision for the given title with the given timestamp.
Definition: Revision.php:291
RevisionDbTestBase\testGetNext
testGetNext()
Revision::getNext.
Definition: RevisionDbTestBase.php:585
RevisionDbTestBase\testGetParentLengths_noRevIds
testGetParentLengths_noRevIds()
Revision::getParentLengths.
Definition: RevisionDbTestBase.php:1108
WANObjectCache\HOLDOFF_NONE
const HOLDOFF_NONE
Idiom for delete() for "no hold-off".
Definition: WANObjectCache.php:157
RevisionDbTestBase\provideGetContent
provideGetContent()
Definition: RevisionDbTestBase.php:854
RevisionTestModifyableContent
Definition: RevisionTestModifyableContent.php:3
Revision\newNullRevision
static newNullRevision( $dbw, $pageId, $summary, $minor, $user=null)
Create a new null-revision for insertion into a page's history.
Definition: Revision.php:1159
RevisionDbTestBase\provideGetSize
provideGetSize()
Definition: RevisionDbTestBase.php:915
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:56
EDIT_MINOR
const EDIT_MINOR
Definition: Defines.php:164
RevisionDbTestBase\provideUserCanBitfield
provideUserCanBitfield()
Definition: RevisionDbTestBase.php:1393
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:25
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
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
RevisionDbTestBase\provideUserCan
provideUserCan()
Definition: RevisionDbTestBase.php:1461
RevisionDbTestBase\testNewKnownCurrent_returnsFalseWhenTitleDoesntExist
testNewKnownCurrent_returnsFalseWhenTitleDoesntExist()
Definition: RevisionDbTestBase.php:1387
false
processing should stop and the error should be shown to the user * false
Definition: hooks.txt:187
RevisionDbTestBase\testGetContentClone
testGetContentClone()
Tests whether $rev->getContent() returns a clone when needed.
Definition: RevisionDbTestBase.php:956
RevisionDbTestBase\testIsCurrent
testIsCurrent()
Revision::isCurrent.
Definition: RevisionDbTestBase.php:544
MWNamespace\getCanonicalName
static getCanonicalName( $index)
Returns the canonical (English) name for a given index.
Definition: MWNamespace.php:255
Revision\DELETED_TEXT
const DELETED_TEXT
Definition: Revision.php:47
RevisionDbTestBase\testIsMinor_true
testIsMinor_true()
Revision::isMinor.
Definition: RevisionDbTestBase.php:1186
MediaWikiTestCase\$db
Database $db
Primary database.
Definition: MediaWikiTestCase.php:57
RevisionDbTestBase\provideGetContentHandler
provideGetContentHandler()
Definition: RevisionDbTestBase.php:835
RevisionDbTestBase\testGetUserAndText
testGetUserAndText()
Revision::getUser Revision::getUserText.
Definition: RevisionDbTestBase.php:1237
RevisionDbTestBase\testGetParentLengths_oneRevId
testGetParentLengths_oneRevId()
Revision::getParentLengths.
Definition: RevisionDbTestBase.php:1121
$wgContLang
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as and the content language as $wgContLang
Definition: design.txt:57
RevisionTestModifyableContent\MODEL_ID
const MODEL_ID
Definition: RevisionTestModifyableContent.php:5