MediaWiki
REL1_22
|
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 protected 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 ) { 00076 $props = array(); 00077 } 00078 00079 if ( !isset( $props['content'] ) && !isset( $props['text'] ) ) { 00080 $props['text'] = 'Lorem Ipsum'; 00081 } 00082 00083 if ( !isset( $props['comment'] ) ) { 00084 $props['comment'] = 'just a test'; 00085 } 00086 00087 if ( !isset( $props['page'] ) ) { 00088 $props['page'] = $this->the_page->getId(); 00089 } 00090 00091 $rev = new Revision( $props ); 00092 00093 $dbw = wfgetDB( DB_MASTER ); 00094 $rev->insertOn( $dbw ); 00095 00096 return $rev; 00097 } 00098 00099 protected function createPage( $page, $text, $model = null ) { 00100 if ( is_string( $page ) ) { 00101 if ( !preg_match( '/:/', $page ) && 00102 ( $model === null || $model === CONTENT_MODEL_WIKITEXT ) 00103 ) { 00104 $ns = $this->getDefaultWikitextNS(); 00105 $page = MWNamespace::getCanonicalName( $ns ) . ':' . $page; 00106 } 00107 00108 $page = Title::newFromText( $page ); 00109 } 00110 00111 if ( $page instanceof Title ) { 00112 $page = new WikiPage( $page ); 00113 } 00114 00115 if ( $page->exists() ) { 00116 $page->doDeleteArticle( "done" ); 00117 } 00118 00119 $content = ContentHandler::makeContent( $text, $page->getTitle(), $model ); 00120 $page->doEditContent( $content, "testing", EDIT_NEW ); 00121 00122 return $page; 00123 } 00124 00125 protected function assertRevEquals( Revision $orig, Revision $rev = null ) { 00126 $this->assertNotNull( $rev, 'missing revision' ); 00127 00128 $this->assertEquals( $orig->getId(), $rev->getId() ); 00129 $this->assertEquals( $orig->getPage(), $rev->getPage() ); 00130 $this->assertEquals( $orig->getTimestamp(), $rev->getTimestamp() ); 00131 $this->assertEquals( $orig->getUser(), $rev->getUser() ); 00132 $this->assertEquals( $orig->getContentModel(), $rev->getContentModel() ); 00133 $this->assertEquals( $orig->getContentFormat(), $rev->getContentFormat() ); 00134 $this->assertEquals( $orig->getSha1(), $rev->getSha1() ); 00135 } 00136 00140 public function testConstructFromRow() { 00141 $orig = $this->makeRevision(); 00142 00143 $dbr = wfgetDB( DB_SLAVE ); 00144 $res = $dbr->select( 'revision', '*', array( 'rev_id' => $orig->getId() ) ); 00145 $this->assertTrue( is_object( $res ), 'query failed' ); 00146 00147 $row = $res->fetchObject(); 00148 $res->free(); 00149 00150 $rev = new Revision( $row ); 00151 00152 $this->assertRevEquals( $orig, $rev ); 00153 } 00154 00158 public function testNewFromRow() { 00159 $orig = $this->makeRevision(); 00160 00161 $dbr = wfgetDB( DB_SLAVE ); 00162 $res = $dbr->select( 'revision', '*', array( 'rev_id' => $orig->getId() ) ); 00163 $this->assertTrue( is_object( $res ), 'query failed' ); 00164 00165 $row = $res->fetchObject(); 00166 $res->free(); 00167 00168 $rev = Revision::newFromRow( $row ); 00169 00170 $this->assertRevEquals( $orig, $rev ); 00171 } 00172 00173 00177 public function testNewFromArchiveRow() { 00178 $page = $this->createPage( 'RevisionStorageTest_testNewFromArchiveRow', 'Lorem Ipsum', CONTENT_MODEL_WIKITEXT ); 00179 $orig = $page->getRevision(); 00180 $page->doDeleteArticle( 'test Revision::newFromArchiveRow' ); 00181 00182 $dbr = wfgetDB( DB_SLAVE ); 00183 $res = $dbr->select( 'archive', '*', array( 'ar_rev_id' => $orig->getId() ) ); 00184 $this->assertTrue( is_object( $res ), 'query failed' ); 00185 00186 $row = $res->fetchObject(); 00187 $res->free(); 00188 00189 $rev = Revision::newFromArchiveRow( $row ); 00190 00191 $this->assertRevEquals( $orig, $rev ); 00192 } 00193 00197 public function testNewFromId() { 00198 $orig = $this->makeRevision(); 00199 00200 $rev = Revision::newFromId( $orig->getId() ); 00201 00202 $this->assertRevEquals( $orig, $rev ); 00203 } 00204 00208 public function testFetchRevision() { 00209 $page = $this->createPage( 'RevisionStorageTest_testFetchRevision', 'one', CONTENT_MODEL_WIKITEXT ); 00210 $id1 = $page->getRevision()->getId(); 00211 00212 $page->doEditContent( new WikitextContent( 'two' ), 'second rev' ); 00213 $id2 = $page->getRevision()->getId(); 00214 00215 $res = Revision::fetchRevision( $page->getTitle() ); 00216 00217 #note: order is unspecified 00218 $rows = array(); 00219 while ( ( $row = $res->fetchObject() ) ) { 00220 $rows[$row->rev_id] = $row; 00221 } 00222 00223 $row = $res->fetchObject(); 00224 $this->assertEquals( 1, count( $rows ), 'expected exactly one revision' ); 00225 $this->assertArrayHasKey( $id2, $rows, 'missing revision with id ' . $id2 ); 00226 } 00227 00231 public function testSelectFields() { 00232 global $wgContentHandlerUseDB; 00233 00234 $fields = Revision::selectFields(); 00235 00236 $this->assertTrue( in_array( 'rev_id', $fields ), 'missing rev_id in list of fields' ); 00237 $this->assertTrue( in_array( 'rev_page', $fields ), 'missing rev_page in list of fields' ); 00238 $this->assertTrue( in_array( 'rev_timestamp', $fields ), 'missing rev_timestamp in list of fields' ); 00239 $this->assertTrue( in_array( 'rev_user', $fields ), 'missing rev_user in list of fields' ); 00240 00241 if ( $wgContentHandlerUseDB ) { 00242 $this->assertTrue( in_array( 'rev_content_model', $fields ), 00243 'missing rev_content_model in list of fields' ); 00244 $this->assertTrue( in_array( 'rev_content_format', $fields ), 00245 'missing rev_content_format in list of fields' ); 00246 } 00247 } 00248 00252 public function testGetPage() { 00253 $page = $this->the_page; 00254 00255 $orig = $this->makeRevision( array( 'page' => $page->getId() ) ); 00256 $rev = Revision::newFromId( $orig->getId() ); 00257 00258 $this->assertEquals( $page->getId(), $rev->getPage() ); 00259 } 00260 00264 public function testGetText() { 00265 $this->hideDeprecated( 'Revision::getText' ); 00266 00267 $orig = $this->makeRevision( array( 'text' => 'hello hello.' ) ); 00268 $rev = Revision::newFromId( $orig->getId() ); 00269 00270 $this->assertEquals( 'hello hello.', $rev->getText() ); 00271 } 00272 00276 public function testGetContent_failure() { 00277 $rev = new Revision( array( 00278 'page' => $this->the_page->getId(), 00279 'content_model' => $this->the_page->getContentModel(), 00280 'text_id' => 123456789, // not in the test DB 00281 ) ); 00282 00283 $this->assertNull( $rev->getContent(), 00284 "getContent() should return null if the revision's text blob could not be loaded." ); 00285 00286 //NOTE: check this twice, once for lazy initialization, and once with the cached value. 00287 $this->assertNull( $rev->getContent(), 00288 "getContent() should return null if the revision's text blob could not be loaded." ); 00289 } 00290 00294 public function testGetContent() { 00295 $orig = $this->makeRevision( array( 'text' => 'hello hello.' ) ); 00296 $rev = Revision::newFromId( $orig->getId() ); 00297 00298 $this->assertEquals( 'hello hello.', $rev->getContent()->getNativeData() ); 00299 } 00300 00304 public function testRevText() { 00305 $this->hideDeprecated( 'Revision::revText' ); 00306 $orig = $this->makeRevision( array( 'text' => 'hello hello rev.' ) ); 00307 $rev = Revision::newFromId( $orig->getId() ); 00308 00309 $this->assertEquals( 'hello hello rev.', $rev->revText() ); 00310 } 00311 00315 public function testGetRawText() { 00316 $this->hideDeprecated( 'Revision::getRawText' ); 00317 00318 $orig = $this->makeRevision( array( 'text' => 'hello hello raw.' ) ); 00319 $rev = Revision::newFromId( $orig->getId() ); 00320 00321 $this->assertEquals( 'hello hello raw.', $rev->getRawText() ); 00322 } 00323 00327 public function testGetContentModel() { 00328 global $wgContentHandlerUseDB; 00329 00330 if ( !$wgContentHandlerUseDB ) { 00331 $this->markTestSkipped( '$wgContentHandlerUseDB is disabled' ); 00332 } 00333 00334 $orig = $this->makeRevision( array( 'text' => 'hello hello.', 00335 'content_model' => CONTENT_MODEL_JAVASCRIPT ) ); 00336 $rev = Revision::newFromId( $orig->getId() ); 00337 00338 $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContentModel() ); 00339 } 00340 00344 public function testGetContentFormat() { 00345 global $wgContentHandlerUseDB; 00346 00347 if ( !$wgContentHandlerUseDB ) { 00348 $this->markTestSkipped( '$wgContentHandlerUseDB is disabled' ); 00349 } 00350 00351 $orig = $this->makeRevision( array( 00352 'text' => 'hello hello.', 00353 'content_model' => CONTENT_MODEL_JAVASCRIPT, 00354 'content_format' => CONTENT_FORMAT_JAVASCRIPT 00355 ) ); 00356 $rev = Revision::newFromId( $orig->getId() ); 00357 00358 $this->assertEquals( CONTENT_FORMAT_JAVASCRIPT, $rev->getContentFormat() ); 00359 } 00360 00364 public function testIsCurrent() { 00365 $page = $this->createPage( 'RevisionStorageTest_testIsCurrent', 'Lorem Ipsum', CONTENT_MODEL_WIKITEXT ); 00366 $rev1 = $page->getRevision(); 00367 00368 # @todo find out if this should be true 00369 # $this->assertTrue( $rev1->isCurrent() ); 00370 00371 $rev1x = Revision::newFromId( $rev1->getId() ); 00372 $this->assertTrue( $rev1x->isCurrent() ); 00373 00374 $page->doEditContent( ContentHandler::makeContent( 'Bla bla', $page->getTitle(), CONTENT_MODEL_WIKITEXT ), 'second rev' ); 00375 $rev2 = $page->getRevision(); 00376 00377 # @todo find out if this should be true 00378 # $this->assertTrue( $rev2->isCurrent() ); 00379 00380 $rev1x = Revision::newFromId( $rev1->getId() ); 00381 $this->assertFalse( $rev1x->isCurrent() ); 00382 00383 $rev2x = Revision::newFromId( $rev2->getId() ); 00384 $this->assertTrue( $rev2x->isCurrent() ); 00385 } 00386 00390 public function testGetPrevious() { 00391 $page = $this->createPage( 'RevisionStorageTest_testGetPrevious', 'Lorem Ipsum testGetPrevious', CONTENT_MODEL_WIKITEXT ); 00392 $rev1 = $page->getRevision(); 00393 00394 $this->assertNull( $rev1->getPrevious() ); 00395 00396 $page->doEditContent( ContentHandler::makeContent( 'Bla bla', $page->getTitle(), CONTENT_MODEL_WIKITEXT ), 00397 'second rev testGetPrevious' ); 00398 $rev2 = $page->getRevision(); 00399 00400 $this->assertNotNull( $rev2->getPrevious() ); 00401 $this->assertEquals( $rev1->getId(), $rev2->getPrevious()->getId() ); 00402 } 00403 00407 public function testGetNext() { 00408 $page = $this->createPage( 'RevisionStorageTest_testGetNext', 'Lorem Ipsum testGetNext', CONTENT_MODEL_WIKITEXT ); 00409 $rev1 = $page->getRevision(); 00410 00411 $this->assertNull( $rev1->getNext() ); 00412 00413 $page->doEditContent( ContentHandler::makeContent( 'Bla bla', $page->getTitle(), CONTENT_MODEL_WIKITEXT ), 00414 'second rev testGetNext' ); 00415 $rev2 = $page->getRevision(); 00416 00417 $this->assertNotNull( $rev1->getNext() ); 00418 $this->assertEquals( $rev2->getId(), $rev1->getNext()->getId() ); 00419 } 00420 00424 public function testNewNullRevision() { 00425 $page = $this->createPage( 'RevisionStorageTest_testNewNullRevision', 'some testing text', CONTENT_MODEL_WIKITEXT ); 00426 $orig = $page->getRevision(); 00427 00428 $dbw = wfGetDB( DB_MASTER ); 00429 $rev = Revision::newNullRevision( $dbw, $page->getId(), 'a null revision', false ); 00430 00431 $this->assertNotEquals( $orig->getId(), $rev->getId(), 00432 'new null revision shold have a different id from the original revision' ); 00433 $this->assertEquals( $orig->getTextId(), $rev->getTextId(), 00434 'new null revision shold have the same text id as the original revision' ); 00435 $this->assertEquals( 'some testing text', $rev->getContent()->getNativeData() ); 00436 } 00437 00438 public static function provideUserWasLastToEdit() { 00439 return array( 00440 array( #0 00441 3, true, # actually the last edit 00442 ), 00443 array( #1 00444 2, true, # not the current edit, but still by this user 00445 ), 00446 array( #2 00447 1, false, # edit by another user 00448 ), 00449 array( #3 00450 0, false, # first edit, by this user, but another user edited in the mean time 00451 ), 00452 ); 00453 } 00454 00458 public function testUserWasLastToEdit( $sinceIdx, $expectedLast ) { 00459 $userA = User::newFromName( "RevisionStorageTest_userA" ); 00460 $userB = User::newFromName( "RevisionStorageTest_userB" ); 00461 00462 if ( $userA->getId() === 0 ) { 00463 $userA = User::createNew( $userA->getName() ); 00464 } 00465 00466 if ( $userB->getId() === 0 ) { 00467 $userB = User::createNew( $userB->getName() ); 00468 } 00469 00470 $ns = $this->getDefaultWikitextNS(); 00471 00472 $dbw = wfGetDB( DB_MASTER ); 00473 $revisions = array(); 00474 00475 // create revisions ----------------------------- 00476 $page = WikiPage::factory( Title::newFromText( 00477 'RevisionStorageTest_testUserWasLastToEdit', $ns ) ); 00478 00479 # zero 00480 $revisions[0] = new Revision( array( 00481 'page' => $page->getId(), 00482 'title' => $page->getTitle(), // we need the title to determine the page's default content model 00483 'timestamp' => '20120101000000', 00484 'user' => $userA->getId(), 00485 'text' => 'zero', 00486 'content_model' => CONTENT_MODEL_WIKITEXT, 00487 'summary' => 'edit zero' 00488 ) ); 00489 $revisions[0]->insertOn( $dbw ); 00490 00491 # one 00492 $revisions[1] = new Revision( array( 00493 'page' => $page->getId(), 00494 'title' => $page->getTitle(), // still need the title, because $page->getId() is 0 (there's no entry in the page table) 00495 'timestamp' => '20120101000100', 00496 'user' => $userA->getId(), 00497 'text' => 'one', 00498 'content_model' => CONTENT_MODEL_WIKITEXT, 00499 'summary' => 'edit one' 00500 ) ); 00501 $revisions[1]->insertOn( $dbw ); 00502 00503 # two 00504 $revisions[2] = new Revision( array( 00505 'page' => $page->getId(), 00506 'title' => $page->getTitle(), 00507 'timestamp' => '20120101000200', 00508 'user' => $userB->getId(), 00509 'text' => 'two', 00510 'content_model' => CONTENT_MODEL_WIKITEXT, 00511 'summary' => 'edit two' 00512 ) ); 00513 $revisions[2]->insertOn( $dbw ); 00514 00515 # three 00516 $revisions[3] = new Revision( array( 00517 'page' => $page->getId(), 00518 'title' => $page->getTitle(), 00519 'timestamp' => '20120101000300', 00520 'user' => $userA->getId(), 00521 'text' => 'three', 00522 'content_model' => CONTENT_MODEL_WIKITEXT, 00523 'summary' => 'edit three' 00524 ) ); 00525 $revisions[3]->insertOn( $dbw ); 00526 00527 # four 00528 $revisions[4] = new Revision( array( 00529 'page' => $page->getId(), 00530 'title' => $page->getTitle(), 00531 'timestamp' => '20120101000200', 00532 'user' => $userA->getId(), 00533 'text' => 'zero', 00534 'content_model' => CONTENT_MODEL_WIKITEXT, 00535 'summary' => 'edit four' 00536 ) ); 00537 $revisions[4]->insertOn( $dbw ); 00538 00539 // test it --------------------------------- 00540 $since = $revisions[$sinceIdx]->getTimestamp(); 00541 00542 $wasLast = Revision::userWasLastToEdit( $dbw, $page->getId(), $userA->getId(), $since ); 00543 00544 $this->assertEquals( $expectedLast, $wasLast ); 00545 } 00546 }