]> gitweb.fluxo.info Git - semanticscuttle.git/commitdiff
Implement voting service and unit tests for it
authorcweiske <cweiske@b3834d28-1941-0410-a4f8-b48e95affb8f>
Sat, 24 Oct 2009 08:07:55 +0000 (08:07 +0000)
committercweiske <cweiske@b3834d28-1941-0410-a4f8-b48e95affb8f>
Sat, 24 Oct 2009 08:07:55 +0000 (08:07 +0000)
git-svn-id: https://semanticscuttle.svn.sourceforge.net/svnroot/semanticscuttle/trunk@401 b3834d28-1941-0410-a4f8-b48e95affb8f

src/SemanticScuttle/Service/Vote.php
tests/VoteTest.php [new file with mode: 0644]

index 3c4a14425abe60e36a2604e9b9d9f9d9870f758e..4a5baab22983c365424e9ff8d32334cffa9236b4 100644 (file)
@@ -1,4 +1,15 @@
 <?php
+/**
+ * SemanticScuttle - your social bookmark manager.
+ *
+ * PHP version 5.
+ *
+ * @category Bookmarking
+ * @package  SemanticScuttle
+ * @author   Christian Weiske <cweiske@cweiske.de>
+ * @license  GPL http://www.gnu.org/licenses/gpl.html
+ * @link     http://sourceforge.net/projects/semanticscuttle
+ */
 
 /**
  * SemanticScuttle voting system.
  * sure lookups are really fast, since every bookmarks
  * in a list shows its voting.
  *
+ * @category Bookmarking
+ * @package  SemanticScuttle
  * @author Christian Weiske <cweiske@cweiske.de>
+ * @license  GPL http://www.gnu.org/licenses/gpl.html
+ * @link     http://sourceforge.net/projects/semanticscuttle
  */
-class SemanticScuttle_Service_Vote extends SemanticScuttle_Service
+class SemanticScuttle_Service_Vote extends SemanticScuttle_DbService
 {
-    /**
-     * Database object
-     *
-     * @var sql_db
-     */
-    protected $db;
 
 
 
@@ -62,14 +71,39 @@ class SemanticScuttle_Service_Vote extends SemanticScuttle_Service
     /**
      * Returns the sum of votes for the given bookmark.
      *
+     * @internal
+     * Uses the "votes" table to retrieve the votes, which
+     * has high costs. It is more efficient to get the sum of
+     * all votes for a bookmark from the bookmarks table,
+     * field bVoting.
+     *
      * @param integer $bookmark Bookmark ID
      *
      * @return integer Vote (can be positive, 0 or negative)
      */
     public function getVoting($bookmark)
     {
-        //FIXME
-    }
+        $query = 'SELECT SUM(vote) as sum FROM ' . $this->getTableName()
+            . ' WHERE bid = "' . $this->db->sql_escape($bookmark) . '"';
+
+        if (!($dbres = $this->db->sql_query_limit($query, 1, 0))) {
+            message_die(
+                GENERAL_ERROR, 'Could not get voting',
+                '', __LINE__, __FILE__, $query, $this->db
+            );
+            //FIXME: throw exception
+            return false;
+        }
+
+        $row = $this->db->sql_fetchrow($dbres);
+        $this->db->sql_freeresult($dbres);
+
+        if (!$row) {
+            return false;
+        }
+
+        return (int)$row['sum'];
+    }//public function getVoting(..)
 
 
 
@@ -83,7 +117,26 @@ class SemanticScuttle_Service_Vote extends SemanticScuttle_Service
      */
     public function getVotes($bookmark)
     {
-        //FIXME
+        $query = 'SELECT COUNT(vote) as count FROM ' . $this->getTableName()
+            . ' WHERE bid = "' . $this->db->sql_escape($bookmark) . '"';
+
+        if (!($dbres = $this->db->sql_query_limit($query, 1, 0))) {
+            message_die(
+                GENERAL_ERROR, 'Could not get vote count',
+                '', __LINE__, __FILE__, $query, $this->db
+            );
+            //FIXME: throw exception
+            return false;
+        }
+
+        $row = $this->db->sql_fetchrow($dbres);
+        $this->db->sql_freeresult($dbres);
+
+        if (!$row) {
+            return false;
+        }
+
+        return (int)$row['count'];
     }
 
 
@@ -99,7 +152,28 @@ class SemanticScuttle_Service_Vote extends SemanticScuttle_Service
      */
     public function hasVoted($bookmark, $user)
     {
-        //FIXME
+        $query = 'SELECT COUNT(vote) as count FROM ' . $this->getTableName()
+            . ' WHERE'
+            . ' bid = "' . $this->db->sql_escape($bookmark) . '"'
+            . ' AND uid = "' . $this->db->sql_escape($user) . '"';
+
+        if (!($dbres = $this->db->sql_query_limit($query, 1, 0))) {
+            message_die(
+                GENERAL_ERROR, 'Could not get vote count',
+                '', __LINE__, __FILE__, $query, $this->db
+            );
+            //FIXME: throw exception
+            return false;
+        }
+
+        $row = $this->db->sql_fetchrow($dbres);
+        $this->db->sql_freeresult($dbres);
+
+        if (!$row) {
+            return false;
+        }
+
+        return (int)$row['count'] == 1;
     }
 
 
@@ -111,11 +185,32 @@ class SemanticScuttle_Service_Vote extends SemanticScuttle_Service
      * @param integer $bookmark Bookmark ID
      * @param integer $user     User ID
      *
-     * @return integer Either 1 or -1.
+     * @return integer Either 1 or -1, null when not voted.
      */
     public function getVote($bookmark, $user)
     {
-        //FIXME
+        $query = 'SELECT vote FROM ' . $this->getTableName()
+            . ' WHERE'
+            . ' bid = "' . $this->db->sql_escape($bookmark) . '"'
+            . ' AND uid = "' . $this->db->sql_escape($user) . '"';
+
+        if (!($dbres = $this->db->sql_query_limit($query, 1, 0))) {
+            message_die(
+                GENERAL_ERROR, 'Could not get vote count',
+                '', __LINE__, __FILE__, $query, $this->db
+            );
+            //FIXME: throw exception
+            return false;
+        }
+
+        $row = $this->db->sql_fetchrow($dbres);
+        $this->db->sql_freeresult($dbres);
+
+        if (!$row) {
+            return null;
+        }
+
+        return $row['vote'];
     }
 
 
@@ -149,7 +244,7 @@ class SemanticScuttle_Service_Vote extends SemanticScuttle_Service
             return false;
         }
 
-        $dbresult = $this->db->sql_query(
+        $res = $this->db->sql_query(
             'INSERT INTO ' . $this->getTableName()
             . ' SET'
             . ' bid = ' . (int)$bookmark
@@ -157,8 +252,17 @@ class SemanticScuttle_Service_Vote extends SemanticScuttle_Service
             . ',vote = ' . (int)$vote
         );
         //FIXME: check for sql error
-        $this->db->sql_freeresult();
-        //FIXME: update bookmarks table
+        $this->db->sql_freeresult($res);
+
+        //update bookmark table
+        $bm  = SemanticScuttle_Service_Factory::get('Bookmark');
+        $res = $this->db->sql_query(
+            'UPDATE ' . $bm->getTableName()
+            . ' SET bVoting = bVoting + ' . (int)$vote
+        );
+        $this->db->sql_freeresult($res);
+
+        return true;
     }
 
 
@@ -172,6 +276,7 @@ class SemanticScuttle_Service_Vote extends SemanticScuttle_Service
      */
     public function rewriteVotings()
     {
+        throw new Exception('Not implemented yet');
         //FIXME
         //SELECT bid, SUM( vote ) FROM sc_votes GROUP BY bid
     }
diff --git a/tests/VoteTest.php b/tests/VoteTest.php
new file mode 100644 (file)
index 0000000..90fae48
--- /dev/null
@@ -0,0 +1,353 @@
+<?php
+/**
+ * SemanticScuttle - your social bookmark manager.
+ *
+ * PHP version 5.
+ *
+ * @category Bookmarking
+ * @package  SemanticScuttle
+ * @author   Christian Weiske <cweiske@cweiske.de>
+ * @license  GPL http://www.gnu.org/licenses/gpl.html
+ * @link     http://sourceforge.net/projects/semanticscuttle
+ */
+
+require_once 'prepare.php';
+require_once 'PHPUnit/Framework.php';
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'VoteTest::main');
+}
+
+/**
+ * Unit tests for the SemanticScuttle voting system.
+ *
+ * @category Bookmarking
+ * @package  SemanticScuttle
+ * @author Christian Weiske <cweiske@cweiske.de>
+ * @license  GPL http://www.gnu.org/licenses/gpl.html
+ * @link     http://sourceforge.net/projects/semanticscuttle
+ */
+class VoteTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Vote service instance to test.
+     *
+     * @var SemanticScuttle_Service_Vote
+     */
+    protected $vs = null;
+
+
+
+    /**
+     * Used to run this test class standalone
+     *
+     * @return void
+     */
+    public static function main()
+    {
+        require_once 'PHPUnit/TextUI/TestRunner.php';
+        PHPUnit_TextUI_TestRunner::run(
+            new PHPUnit_Framework_TestSuite('VoteTest')
+        );
+    }
+
+
+
+    public function setUp()
+    {
+        //FIXME: create true new instance
+        $this->vs = SemanticScuttle_Service_Factory::get('Vote');
+    }
+
+
+
+    /**
+     * Create a new bookmark.
+     *
+     * @return integer ID of bookmark
+     */
+    protected function addBookmark()
+    {
+        $bs = SemanticScuttle_Service_Factory::get('Bookmark');
+        $rand = rand();
+        $bid = $bs->addBookmark(
+            'http://example.org/' . $rand,
+            'unittest bookmark #' . $rand,
+            'description',
+            null,
+            0,
+            array('unittest')
+        );
+        return $bid;
+    }
+
+
+
+    /**
+     * Test getVoting() when no votes have been cast.
+     *
+     * @return void
+     */
+    public function testGetVotingZero()
+    {
+        $bid = $this->addBookmark();
+        $this->assertEquals(0, $this->vs->getVoting($bid));
+    }
+
+
+
+    /**
+     * Test getVoting() when one positive vote has been cast.
+     *
+     * @return void
+     */
+    public function testGetVotingOne()
+    {
+        $bid = $this->addBookmark();
+        $this->vs->vote($bid, 1, 1);
+        $this->assertEquals(1, $this->vs->getVoting($bid));
+    }
+
+
+
+    /**
+     * Test getVoting() when one nevative vote has been cast.
+     *
+     * @return void
+     */
+    public function testGetVotingMinusOne()
+    {
+        $bid = $this->addBookmark();
+        $this->vs->vote($bid, 1, -1);
+        $this->assertEquals(-1, $this->vs->getVoting($bid));
+    }
+
+
+
+    /**
+     * Test getVoting() when several votes have been cast.
+     *
+     * @return void
+     */
+    public function testGetVotingSum()
+    {
+        $bid = $this->addBookmark();
+        $this->vs->vote($bid, 1, 1);
+        $this->vs->vote($bid, 2, -1);
+        $this->vs->vote($bid, 3, 1);
+        $this->vs->vote($bid, 4, 1);
+        $this->assertEquals(2, $this->vs->getVoting($bid));
+    }
+
+
+
+    /**
+     * Test getVotes() when no vote has been cast.
+     *
+     * @return void
+     */
+    public function testGetVotesZero()
+    {
+        $bid = $this->addBookmark();
+        $this->assertEquals(0, $this->vs->getVotes($bid));
+    }
+
+
+
+    /**
+     * Test getVotes() when one vote has been cast.
+     *
+     * @return void
+     */
+    public function testGetVotesOne()
+    {
+        $bid = $this->addBookmark();
+        $this->vs->vote($bid, 1, 1);
+        $this->assertEquals(1, $this->vs->getVotes($bid));
+    }
+
+
+
+    /**
+     * Test getVoting() when several votes have been cast.
+     *
+     * @return void
+     */
+    public function testGetVotesMultiple()
+    {
+        $bid = $this->addBookmark();
+        $this->vs->vote($bid, 1, 1);
+        $this->vs->vote($bid, 2, -1);
+        $this->vs->vote($bid, 3, 1);
+        $this->vs->vote($bid, 4, 1);
+        $this->assertEquals(4, $this->vs->getVotes($bid));
+    }
+
+
+
+    /**
+     * Test hasVoted() when a no vote has been cast
+     *
+     * @return void
+     */
+    public function testHasVotedFalse()
+    {
+        $uid = 1;
+        $bid = $this->addBookmark();
+        $this->assertFalse($this->vs->hasVoted($bid, $uid));
+    }
+
+
+
+    /**
+     * Test hasVoted() when a vote has been cast
+     *
+     * @return void
+     */
+    public function testHasVotedTrue()
+    {
+        $uid = 1;
+        $bid = $this->addBookmark();
+        $this->vs->vote($bid, $uid, 1);
+        $this->assertTrue($this->vs->hasVoted($bid, $uid));
+    }
+
+
+
+    /**
+     * Test hasVoted() when a vote has been cast for other bookmarks
+     *
+     * @return void
+     */
+    public function testHasVotedFalseOthers()
+    {
+        $uid = 1;
+        $bid = $this->addBookmark();
+        $bid2 = $this->addBookmark();
+        $bid3 = $this->addBookmark();
+
+        $this->vs->vote($bid, $uid, 1);
+        $this->vs->vote($bid3, $uid, 1);
+
+        $this->assertFalse($this->vs->hasVoted($bid2, $uid));
+    }
+
+
+
+    /**
+     * Test getVote() when no vote has been cast.
+     *
+     * @return void
+     */
+    public function testGetVoteNone()
+    {
+        $uid = 1;
+        $bid = $this->addBookmark();
+        $this->assertNull($this->vs->getVote($bid, $uid));
+    }
+
+
+
+    /**
+     * Test getVote() when a positive vote has been cast.
+     *
+     * @return void
+     */
+    public function testGetVoteOne()
+    {
+        $uid = 1;
+        $bid = $this->addBookmark();
+        $this->vs->vote($bid, $uid, 1);
+        $this->assertEquals(1, $this->vs->getVote($bid, $uid));
+    }
+
+
+
+    /**
+     * Test getVote() when a negavitve vote has been cast.
+     *
+     * @return void
+     */
+    public function testGetVoteMinusOne()
+    {
+        $uid = 1;
+        $bid = $this->addBookmark();
+        $this->vs->vote($bid, $uid, -1);
+        $this->assertEquals(-1, $this->vs->getVote($bid, $uid));
+    }
+
+
+
+    /**
+     * Test vote() with wrong vote parameter
+     *
+     * @return void
+     */
+    public function testVoteWrongVoteParam()
+    {
+        $uid = 1;
+        $bid = $this->addBookmark();
+        $this->assertFalse($this->vs->vote($bid, $uid, 2));
+        $this->assertFalse($this->vs->vote($bid, $uid, 0));
+        $this->assertFalse($this->vs->vote($bid, $uid, 1.5));
+        $this->assertFalse($this->vs->vote($bid, $uid, -1.1));
+        $this->assertFalse($this->vs->vote($bid, $uid, 'yes'));
+        $this->assertFalse($this->vs->vote($bid, $uid, 'no'));
+    }
+
+
+
+    /**
+     * Test vote() when the user already has voted
+     *
+     * @return void
+     */
+    public function testVoteHasVoted()
+    {
+        $uid = 1;
+        $bid = $this->addBookmark();
+        $this->assertTrue($this->vs->vote($bid, $uid, 1));
+        $this->assertFalse($this->vs->vote($bid, $uid, 1));
+
+        $bid = $this->addBookmark();
+        $this->assertTrue($this->vs->vote($bid, $uid, -1));
+        $this->assertFalse($this->vs->vote($bid, $uid, 1));
+    }
+
+
+
+    /**
+     * Test vote() with positive vote
+     *
+     * @return void
+     */
+    public function testVotePositive()
+    {
+        $uid = 1;
+        $bid = $this->addBookmark();
+        $this->assertTrue($this->vs->vote($bid, $uid, 1));
+        $this->assertEquals(1, $this->vs->getVote($bid, $uid));
+    }
+
+
+
+    /**
+     * Test vote() with negative vote
+     *
+     * @return void
+     */
+    public function testVoteNegative()
+    {
+        $uid = 1;
+        $bid = $this->addBookmark();
+        $this->assertTrue($this->vs->vote($bid, $uid, -1));
+        $this->assertEquals(-1, $this->vs->getVote($bid, $uid));
+    }
+
+}//class VoteTest extends PHPUnit_Framework_TestCase
+
+
+if (PHPUnit_MAIN_METHOD == 'VoteTest::main') {
+    VoteTest::main();
+}
+?>
\ No newline at end of file