Make userWasLastToEdit reusable.
authordaniel <daniel.kinzler@wikimedia.de>
Thu, 30 Aug 2012 17:17:14 +0000 (19:17 +0200)
committerdaniel <daniel.kinzler@wikimedia.de>
Mon, 3 Sep 2012 10:22:52 +0000 (12:22 +0200)
Make userWasLastToEdit a static method in the Revision class, so it can be
reused by extensions, etc.

Change-Id: Ib44423c3544dabab3be7fe6eb675315f2480838e

includes/EditPage.php
includes/Revision.php
tests/phpunit/includes/RevisionStorageTest.php

index f9bba19..0c232fb 100644 (file)
@@ -1295,7 +1295,7 @@ class EditPage {
                                                $this->isConflict = false;
                                                wfDebug( __METHOD__ . ": conflict suppressed; new section\n" );
                                        }
-                               } elseif ( $this->section == '' && $this->userWasLastToEdit( $wgUser->getId(), $this->edittime ) ) {
+                               } elseif ( $this->section == '' && Revision::userWasLastToEdit( DB_MASTER,  $this->mTitle->getArticleID(), $wgUser->getId(), $this->edittime ) ) {
                                        # Suppress edit conflict with self, except for section edits where merging is required.
                                        wfDebug( __METHOD__ . ": Suppressing edit conflict, same user.\n" );
                                        $this->isConflict = false;
@@ -1489,35 +1489,6 @@ class EditPage {
                }
        }
 
-       /**
-        * Check if no edits were made by other users since
-        * the time a user started editing the page. Limit to
-        * 50 revisions for the sake of performance.
-        *
-        * @param $id int
-        * @param $edittime string
-        *
-        * @return bool
-        */
-       protected function userWasLastToEdit( $id, $edittime ) {
-               if ( !$id ) return false;
-               $dbw = wfGetDB( DB_MASTER );
-               $res = $dbw->select( 'revision',
-                       'rev_user',
-                       array(
-                               'rev_page' => $this->mTitle->getArticleID(),
-                               'rev_timestamp > ' . $dbw->addQuotes( $dbw->timestamp( $edittime ) )
-                       ),
-                       __METHOD__,
-                       array( 'ORDER BY' => 'rev_timestamp ASC', 'LIMIT' => 50 ) );
-               foreach ( $res as $row ) {
-                       if ( $row->rev_user != $id ) {
-                               return false;
-                       }
-               }
-               return true;
-       }
-
        /**
         * @private
         * @todo document
index 9da031e..20cc8f5 100644 (file)
@@ -1290,4 +1290,42 @@ class Revision implements IDBAccessObject {
                }
                return 0;
        }
-}
+
+       /**
+        * Check if no edits were made by other users since
+        * the time a user started editing the page. Limit to
+        * 50 revisions for the sake of performance.
+        *
+        * @since 1.20
+        *
+        * @param DatabaseBase|int $db the Database to perform the check on. May be given as a Database object or
+        *        a database identifier usable with wfGetDB.
+        * @param int $pageId the ID of the page in question
+        * @param int $userId the ID of the user in question
+        * @param string $since look at edits since this time
+        *
+        * @return bool True if the given user was the only one to edit since the given timestamp
+        */
+       public static function userWasLastToEdit( $db, $pageId, $userId, $since ) {
+               if ( !$userId ) return false;
+
+               if ( is_int( $db ) ) {
+                       $db = wfGetDB( $db );
+               }
+
+               $res = $db->select( 'revision',
+                       'rev_user',
+                       array(
+                               'rev_page' => $pageId,
+                               'rev_timestamp > ' . $db->addQuotes( $db->timestamp( $since ) )
+                       ),
+                       __METHOD__,
+                       array( 'ORDER BY' => 'rev_timestamp ASC', 'LIMIT' => 50 ) );
+               foreach ( $res as $row ) {
+                       if ( $row->rev_user != $userId ) {
+                               return false;
+                       }
+               }
+               return true;
+       }
+}
\ No newline at end of file
index 6d82d0c..8a7face 100644 (file)
@@ -5,6 +5,9 @@
  *
  * @group Database
  * ^--- important, causes temporary tables to be used instead of the real database
+ *
+ * @group medium
+ * ^--- important, causes tests not to fail with timeout
  */
 class RevisionStorageTest extends MediaWikiTestCase {
 
@@ -306,4 +309,100 @@ class RevisionStorageTest extends MediaWikiTestCase {
                $this->assertEquals( $orig->getTextId(), $rev->getTextId(), 'new null revision shold have the same text id as the original revision' );
                $this->assertEquals( 'some testing text', $rev->getText() );
        }
+
+       public function dataUserWasLastToEdit() {
+               return array(
+                       array( #0
+                               3, true, # actually the last edit
+                       ),
+                       array( #1
+                               2, true, # not the current edit, but still by this user
+                       ),
+                       array( #2
+                               1, false, # edit by another user
+                       ),
+                       array( #3
+                               0, false, # first edit, by this user, but another user edited in the mean time
+                       ),
+               );
+       }
+
+       /**
+        * @dataProvider dataUserWasLastToEdit
+        */
+       public function testUserWasLastToEdit( $sinceIdx, $expectedLast ) {
+               $userA = \User::newFromName( "RevisionStorageTest_userA" );
+               $userB = \User::newFromName( "RevisionStorageTest_userB" );
+
+               if ( $userA->getId() === 0 ) {
+                       $userA = \User::createNew( $userA->getName() );
+               }
+
+               if ( $userB->getId() === 0 ) {
+                       $userB = \User::createNew( $userB->getName() );
+               }
+
+               $dbw = wfGetDB( DB_MASTER );
+               $revisions = array();
+
+               // create revisions -----------------------------
+               $page = WikiPage::factory( Title::newFromText( 'RevisionStorageTest_testUserWasLastToEdit' ) );
+
+               # zero
+               $revisions[0] = new Revision( array(
+                       'page' => $page->getId(),
+                       'timestamp' => '20120101000000',
+                       'user' => $userA->getId(),
+                       'text' => 'zero',
+                       'summary' => 'edit zero'
+               ) );
+               $revisions[0]->insertOn( $dbw );
+
+               # one
+               $revisions[1] = new Revision( array(
+                       'page' => $page->getId(),
+                       'timestamp' => '20120101000100',
+                       'user' => $userA->getId(),
+                       'text' => 'one',
+                       'summary' => 'edit one'
+               ) );
+               $revisions[1]->insertOn( $dbw );
+
+               # two
+               $revisions[2] = new Revision( array(
+                       'page' => $page->getId(),
+                       'timestamp' => '20120101000200',
+                       'user' => $userB->getId(),
+                       'text' => 'two',
+                       'summary' => 'edit two'
+               ) );
+               $revisions[2]->insertOn( $dbw );
+
+               # three
+               $revisions[3] = new Revision( array(
+                       'page' => $page->getId(),
+                       'timestamp' => '20120101000300',
+                       'user' => $userA->getId(),
+                       'text' => 'three',
+                       'summary' => 'edit three'
+               ) );
+               $revisions[3]->insertOn( $dbw );
+
+               # four
+               $revisions[4] = new Revision( array(
+                       'page' => $page->getId(),
+                       'timestamp' => '20120101000200',
+                       'user' => $userA->getId(),
+                       'text' => 'zero',
+                       'summary' => 'edit four'
+               ) );
+               $revisions[4]->insertOn( $dbw );
+
+               // test it ---------------------------------
+               $since = $revisions[ $sinceIdx ]->getTimestamp();
+
+               $wasLast = Revision::userWasLastToEdit( $dbw, $page->getId(), $userA->getId(), $since );
+
+               $this->assertEquals( $expectedLast, $wasLast );
+       }
 }