MediaWiki  master
RevisionStorageTest.php
Go to the documentation of this file.
00001 <?php
00002 
00013 class RevisionStorageTest extends MediaWikiTestCase {
00014 
00018         var $the_page;
00019 
00020         function  __construct( $name = null, array $data = array(), $dataName = '' ) {
00021                 parent::__construct( $name, $data, $dataName );
00022 
00023                 $this->tablesUsed = array_merge( $this->tablesUsed,
00024                                                  array( 'page',
00025                                                       'revision',
00026                                                       'text',
00027 
00028                                                       'recentchanges',
00029                                                       'logging',
00030 
00031                                                       'page_props',
00032                                                       'pagelinks',
00033                                                       'categorylinks',
00034                                                       'langlinks',
00035                                                       'externallinks',
00036                                                       'imagelinks',
00037                                                       'templatelinks',
00038                                                       'iwlinks' ) );
00039         }
00040 
00041         public function setUp() {
00042                 global $wgExtraNamespaces, $wgNamespaceContentModels, $wgContentHandlers, $wgContLang;
00043 
00044                 parent::setUp();
00045 
00046                 $wgExtraNamespaces[ 12312 ] = 'Dummy';
00047                 $wgExtraNamespaces[ 12313 ] = 'Dummy_talk';
00048 
00049                 $wgNamespaceContentModels[ 12312 ] = 'DUMMY';
00050                 $wgContentHandlers[ 'DUMMY' ] = 'DummyContentHandlerForTesting';
00051 
00052                 MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache
00053                 $wgContLang->resetNamespaces(); # reset namespace cache
00054                 if ( !$this->the_page ) {
00055                         $this->the_page = $this->createPage( 'RevisionStorageTest_the_page', "just a dummy page", CONTENT_MODEL_WIKITEXT );
00056                 }
00057         }
00058 
00059         public function tearDown() {
00060                 global $wgExtraNamespaces, $wgNamespaceContentModels, $wgContentHandlers, $wgContLang;
00061 
00062                 parent::tearDown();
00063 
00064                 unset( $wgExtraNamespaces[ 12312 ] );
00065                 unset( $wgExtraNamespaces[ 12313 ] );
00066 
00067                 unset( $wgNamespaceContentModels[ 12312 ] );
00068                 unset( $wgContentHandlers[ 'DUMMY' ] );
00069 
00070                 MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache
00071                 $wgContLang->resetNamespaces(); # reset namespace cache
00072         }
00073 
00074         protected function makeRevision( $props = null ) {
00075                 if ( $props === null ) $props = array();
00076 
00077                 if ( !isset( $props['content'] ) && !isset( $props['text'] ) ) $props['text'] = 'Lorem Ipsum';
00078                 if ( !isset( $props['comment'] ) ) $props['comment'] = 'just a test';
00079                 if ( !isset( $props['page'] ) ) $props['page'] = $this->the_page->getId();
00080 
00081                 $rev = new Revision( $props );
00082 
00083                 $dbw = wfgetDB( DB_MASTER );
00084                 $rev->insertOn( $dbw );
00085 
00086                 return $rev;
00087         }
00088 
00089         protected function createPage( $page, $text, $model = null ) {
00090                 if ( is_string( $page ) ) {
00091                         if ( !preg_match( '/:/', $page ) &&
00092                                 ( $model === null || $model === CONTENT_MODEL_WIKITEXT ) ) {
00093 
00094                                 $ns = $this->getDefaultWikitextNS();
00095                                 $page = MWNamespace::getCanonicalName( $ns ) . ':' . $page;
00096                         }
00097 
00098                         $page = Title::newFromText( $page );
00099                 }
00100 
00101                 if ( $page instanceof Title ) {
00102                         $page = new WikiPage( $page );
00103                 }
00104 
00105                 if ( $page->exists() ) {
00106                         $page->doDeleteArticle( "done" );
00107                 }
00108 
00109                 $content = ContentHandler::makeContent( $text, $page->getTitle(), $model );
00110                 $page->doEditContent( $content, "testing", EDIT_NEW );
00111 
00112                 return $page;
00113         }
00114 
00115         protected function assertRevEquals( Revision $orig, Revision $rev = null ) {
00116                 $this->assertNotNull( $rev, 'missing revision' );
00117 
00118                 $this->assertEquals( $orig->getId(), $rev->getId() );
00119                 $this->assertEquals( $orig->getPage(), $rev->getPage() );
00120                 $this->assertEquals( $orig->getTimestamp(), $rev->getTimestamp() );
00121                 $this->assertEquals( $orig->getUser(), $rev->getUser() );
00122                 $this->assertEquals( $orig->getContentModel(), $rev->getContentModel() );
00123                 $this->assertEquals( $orig->getContentFormat(), $rev->getContentFormat() );
00124                 $this->assertEquals( $orig->getSha1(), $rev->getSha1() );
00125         }
00126 
00130         public function testConstructFromRow()
00131         {
00132                 $orig = $this->makeRevision();
00133 
00134                 $dbr = wfgetDB( DB_SLAVE );
00135                 $res = $dbr->select( 'revision', '*', array( 'rev_id' => $orig->getId() ) );
00136                 $this->assertTrue( is_object( $res ), 'query failed' );
00137 
00138                 $row = $res->fetchObject();
00139                 $res->free();
00140 
00141                 $rev = new Revision( $row );
00142 
00143                 $this->assertRevEquals( $orig, $rev );
00144         }
00145 
00149         public function testNewFromRow()
00150         {
00151                 $orig = $this->makeRevision();
00152 
00153                 $dbr = wfgetDB( DB_SLAVE );
00154                 $res = $dbr->select( 'revision', '*', array( 'rev_id' => $orig->getId() ) );
00155                 $this->assertTrue( is_object( $res ), 'query failed' );
00156 
00157                 $row = $res->fetchObject();
00158                 $res->free();
00159 
00160                 $rev = Revision::newFromRow( $row );
00161 
00162                 $this->assertRevEquals( $orig, $rev );
00163         }
00164 
00165 
00169         public function testNewFromArchiveRow()
00170         {
00171                 $page = $this->createPage( 'RevisionStorageTest_testNewFromArchiveRow', 'Lorem Ipsum', CONTENT_MODEL_WIKITEXT );
00172                 $orig = $page->getRevision();
00173                 $page->doDeleteArticle( 'test Revision::newFromArchiveRow' );
00174 
00175                 $dbr = wfgetDB( DB_SLAVE );
00176                 $res = $dbr->select( 'archive', '*', array( 'ar_rev_id' => $orig->getId() ) );
00177                 $this->assertTrue( is_object( $res ), 'query failed' );
00178 
00179                 $row = $res->fetchObject();
00180                 $res->free();
00181 
00182                 $rev = Revision::newFromArchiveRow( $row );
00183 
00184                 $this->assertRevEquals( $orig, $rev );
00185         }
00186 
00190         public function testNewFromId()
00191         {
00192                 $orig = $this->makeRevision();
00193 
00194                 $rev = Revision::newFromId( $orig->getId() );
00195 
00196                 $this->assertRevEquals( $orig, $rev );
00197         }
00198 
00202         public function testFetchRevision()
00203         {
00204                 $page = $this->createPage( 'RevisionStorageTest_testFetchRevision', 'one', CONTENT_MODEL_WIKITEXT );
00205                 $id1 = $page->getRevision()->getId();
00206 
00207                 $page->doEditContent( new WikitextContent( 'two' ), 'second rev' );
00208                 $id2 = $page->getRevision()->getId();
00209 
00210                 $res = Revision::fetchRevision( $page->getTitle() );
00211 
00212                 #note: order is unspecified
00213                 $rows = array();
00214                 while ( ( $row = $res->fetchObject() ) ) {
00215                         $rows[ $row->rev_id ]= $row;
00216                 }
00217 
00218                 $row = $res->fetchObject();
00219                 $this->assertEquals( 1, count($rows), 'expected exactly one revision' );
00220                 $this->assertArrayHasKey( $id2, $rows, 'missing revision with id ' . $id2 );
00221         }
00222 
00226         public function testSelectFields()
00227         {
00228                 global $wgContentHandlerUseDB;
00229 
00230                 $fields = Revision::selectFields();
00231 
00232                 $this->assertTrue( in_array( 'rev_id', $fields ), 'missing rev_id in list of fields');
00233                 $this->assertTrue( in_array( 'rev_page', $fields ), 'missing rev_page in list of fields');
00234                 $this->assertTrue( in_array( 'rev_timestamp', $fields ), 'missing rev_timestamp in list of fields');
00235                 $this->assertTrue( in_array( 'rev_user', $fields ), 'missing rev_user in list of fields');
00236 
00237                 if ( $wgContentHandlerUseDB ) {
00238                         $this->assertTrue( in_array( 'rev_content_model', $fields ),
00239                                                                 'missing rev_content_model in list of fields');
00240                         $this->assertTrue( in_array( 'rev_content_format', $fields ),
00241                                                                 'missing rev_content_format in list of fields');
00242                 }
00243         }
00244 
00248         public function testGetPage()
00249         {
00250                 $page = $this->the_page;
00251 
00252                 $orig = $this->makeRevision( array( 'page' => $page->getId() ) );
00253                 $rev = Revision::newFromId( $orig->getId() );
00254 
00255                 $this->assertEquals( $page->getId(), $rev->getPage() );
00256         }
00257 
00261         public function testGetText()
00262         {
00263                 $this->hideDeprecated( 'Revision::getText' );
00264 
00265                 $orig = $this->makeRevision( array( 'text' => 'hello hello.' ) );
00266                 $rev = Revision::newFromId( $orig->getId() );
00267 
00268                 $this->assertEquals( 'hello hello.', $rev->getText() );
00269         }
00270 
00274         public function testGetContent()
00275         {
00276                 $orig = $this->makeRevision( array( 'text' => 'hello hello.' ) );
00277                 $rev = Revision::newFromId( $orig->getId() );
00278 
00279                 $this->assertEquals( 'hello hello.', $rev->getContent()->getNativeData() );
00280         }
00281 
00285         public function testRevText()
00286         {
00287                 $this->hideDeprecated( 'Revision::revText' );
00288                 $orig = $this->makeRevision( array( 'text' => 'hello hello rev.' ) );
00289                 $rev = Revision::newFromId( $orig->getId() );
00290 
00291                 $this->assertEquals( 'hello hello rev.', $rev->revText() );
00292         }
00293 
00297         public function testGetRawText()
00298         {
00299                 $this->hideDeprecated( 'Revision::getRawText' );
00300 
00301                 $orig = $this->makeRevision( array( 'text' => 'hello hello raw.' ) );
00302                 $rev = Revision::newFromId( $orig->getId() );
00303 
00304                 $this->assertEquals( 'hello hello raw.', $rev->getRawText() );
00305         }
00306 
00310         public function testGetContentModel()
00311         {
00312                 global $wgContentHandlerUseDB;
00313 
00314                 if ( !$wgContentHandlerUseDB ) {
00315                         $this->markTestSkipped( '$wgContentHandlerUseDB is disabled' );
00316                 }
00317 
00318                 $orig = $this->makeRevision( array( 'text' => 'hello hello.',
00319                                                                                         'content_model' => CONTENT_MODEL_JAVASCRIPT ) );
00320                 $rev = Revision::newFromId( $orig->getId() );
00321 
00322                 $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContentModel() );
00323         }
00324 
00328         public function testGetContentFormat()
00329         {
00330                 global $wgContentHandlerUseDB;
00331 
00332                 if ( !$wgContentHandlerUseDB ) {
00333                         $this->markTestSkipped( '$wgContentHandlerUseDB is disabled' );
00334                 }
00335 
00336                 $orig = $this->makeRevision( array( 'text' => 'hello hello.',
00337                                                                                         'content_model' => CONTENT_MODEL_JAVASCRIPT,
00338                                                                                         'content_format' => CONTENT_FORMAT_JAVASCRIPT ) );
00339                 $rev = Revision::newFromId( $orig->getId() );
00340 
00341                 $this->assertEquals( CONTENT_FORMAT_JAVASCRIPT, $rev->getContentFormat() );
00342         }
00343 
00347         public function testIsCurrent()
00348         {
00349                 $page = $this->createPage( 'RevisionStorageTest_testIsCurrent', 'Lorem Ipsum', CONTENT_MODEL_WIKITEXT );
00350                 $rev1 = $page->getRevision();
00351 
00352                 # @todo: find out if this should be true
00353                 # $this->assertTrue( $rev1->isCurrent() );
00354 
00355                 $rev1x = Revision::newFromId( $rev1->getId() );
00356                 $this->assertTrue( $rev1x->isCurrent() );
00357 
00358                 $page->doEditContent( ContentHandler::makeContent( 'Bla bla', $page->getTitle(), CONTENT_MODEL_WIKITEXT ), 'second rev' );
00359                 $rev2 = $page->getRevision();
00360 
00361                 # @todo: find out if this should be true
00362                 # $this->assertTrue( $rev2->isCurrent() );
00363 
00364                 $rev1x = Revision::newFromId( $rev1->getId() );
00365                 $this->assertFalse( $rev1x->isCurrent() );
00366 
00367                 $rev2x = Revision::newFromId( $rev2->getId() );
00368                 $this->assertTrue( $rev2x->isCurrent() );
00369         }
00370 
00374         public function testGetPrevious()
00375         {
00376                 $page = $this->createPage( 'RevisionStorageTest_testGetPrevious', 'Lorem Ipsum testGetPrevious', CONTENT_MODEL_WIKITEXT );
00377                 $rev1 = $page->getRevision();
00378 
00379                 $this->assertNull( $rev1->getPrevious() );
00380 
00381                 $page->doEditContent( ContentHandler::makeContent( 'Bla bla', $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
00382                                                                 'second rev testGetPrevious' );
00383                 $rev2 = $page->getRevision();
00384 
00385                 $this->assertNotNull( $rev2->getPrevious() );
00386                 $this->assertEquals( $rev1->getId(), $rev2->getPrevious()->getId() );
00387         }
00388 
00392         public function testGetNext()
00393         {
00394                 $page = $this->createPage( 'RevisionStorageTest_testGetNext', 'Lorem Ipsum testGetNext', CONTENT_MODEL_WIKITEXT );
00395                 $rev1 = $page->getRevision();
00396 
00397                 $this->assertNull( $rev1->getNext() );
00398 
00399                 $page->doEditContent( ContentHandler::makeContent( 'Bla bla', $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
00400                                                                 'second rev testGetNext' );
00401                 $rev2 = $page->getRevision();
00402 
00403                 $this->assertNotNull( $rev1->getNext() );
00404                 $this->assertEquals( $rev2->getId(), $rev1->getNext()->getId() );
00405         }
00406 
00410         public function testNewNullRevision()
00411         {
00412                 $page = $this->createPage( 'RevisionStorageTest_testNewNullRevision', 'some testing text', CONTENT_MODEL_WIKITEXT );
00413                 $orig = $page->getRevision();
00414 
00415                 $dbw = wfGetDB( DB_MASTER );
00416                 $rev = Revision::newNullRevision( $dbw, $page->getId(), 'a null revision', false );
00417 
00418                 $this->assertNotEquals( $orig->getId(), $rev->getId(),
00419                                                                 'new null revision shold have a different id from the original revision' );
00420                 $this->assertEquals( $orig->getTextId(), $rev->getTextId(),
00421                                                                 'new null revision shold have the same text id as the original revision' );
00422                 $this->assertEquals( 'some testing text', $rev->getContent()->getNativeData() );
00423         }
00424 
00425         public static function provideUserWasLastToEdit() {
00426                 return array(
00427                         array( #0
00428                                 3, true, # actually the last edit
00429                         ),
00430                         array( #1
00431                                 2, true, # not the current edit, but still by this user
00432                         ),
00433                         array( #2
00434                                 1, false, # edit by another user
00435                         ),
00436                         array( #3
00437                                 0, false, # first edit, by this user, but another user edited in the mean time
00438                         ),
00439                 );
00440         }
00441 
00445         public function testUserWasLastToEdit( $sinceIdx, $expectedLast ) {
00446                 $userA = \User::newFromName( "RevisionStorageTest_userA" );
00447                 $userB = \User::newFromName( "RevisionStorageTest_userB" );
00448 
00449                 if ( $userA->getId() === 0 ) {
00450                         $userA = \User::createNew( $userA->getName() );
00451                 }
00452 
00453                 if ( $userB->getId() === 0 ) {
00454                         $userB = \User::createNew( $userB->getName() );
00455                 }
00456 
00457                 $ns = $this->getDefaultWikitextNS();
00458 
00459                 $dbw = wfGetDB( DB_MASTER );
00460                 $revisions = array();
00461 
00462                 // create revisions -----------------------------
00463                 $page = WikiPage::factory( Title::newFromText(
00464                         'RevisionStorageTest_testUserWasLastToEdit', $ns ) );
00465 
00466                 # zero
00467                 $revisions[0] = new Revision( array(
00468                         'page' => $page->getId(),
00469                         'title' => $page->getTitle(), // we need the title to determine the page's default content model
00470                         'timestamp' => '20120101000000',
00471                         'user' => $userA->getId(),
00472                         'text' => 'zero',
00473                         'content_model' => CONTENT_MODEL_WIKITEXT,
00474                         'summary' => 'edit zero'
00475                 ) );
00476                 $revisions[0]->insertOn( $dbw );
00477 
00478                 # one
00479                 $revisions[1] = new Revision( array(
00480                         'page' => $page->getId(),
00481                         'title' => $page->getTitle(), // still need the title, because $page->getId() is 0 (there's no entry in the page table)
00482                         'timestamp' => '20120101000100',
00483                         'user' => $userA->getId(),
00484                         'text' => 'one',
00485                         'content_model' => CONTENT_MODEL_WIKITEXT,
00486                         'summary' => 'edit one'
00487                 ) );
00488                 $revisions[1]->insertOn( $dbw );
00489 
00490                 # two
00491                 $revisions[2] = new Revision( array(
00492                         'page' => $page->getId(),
00493                         'title' => $page->getTitle(),
00494                         'timestamp' => '20120101000200',
00495                         'user' => $userB->getId(),
00496                         'text' => 'two',
00497                         'content_model' => CONTENT_MODEL_WIKITEXT,
00498                         'summary' => 'edit two'
00499                 ) );
00500                 $revisions[2]->insertOn( $dbw );
00501 
00502                 # three
00503                 $revisions[3] = new Revision( array(
00504                         'page' => $page->getId(),
00505                         'title' => $page->getTitle(),
00506                         'timestamp' => '20120101000300',
00507                         'user' => $userA->getId(),
00508                         'text' => 'three',
00509                         'content_model' => CONTENT_MODEL_WIKITEXT,
00510                         'summary' => 'edit three'
00511                 ) );
00512                 $revisions[3]->insertOn( $dbw );
00513 
00514                 # four
00515                 $revisions[4] = new Revision( array(
00516                         'page' => $page->getId(),
00517                         'title' => $page->getTitle(),
00518                         'timestamp' => '20120101000200',
00519                         'user' => $userA->getId(),
00520                         'text' => 'zero',
00521                         'content_model' => CONTENT_MODEL_WIKITEXT,
00522                         'summary' => 'edit four'
00523                 ) );
00524                 $revisions[4]->insertOn( $dbw );
00525 
00526                 // test it ---------------------------------
00527                 $since = $revisions[ $sinceIdx ]->getTimestamp();
00528 
00529                 $wasLast = Revision::userWasLastToEdit( $dbw, $page->getId(), $userA->getId(), $since );
00530 
00531                 $this->assertEquals( $expectedLast, $wasLast );
00532         }
00533 }