diff options
| -rw-r--r-- | src/SemanticScuttle/Service/Vote.php | 137 | ||||
| -rw-r--r-- | tests/VoteTest.php | 353 | 
2 files changed, 474 insertions, 16 deletions
| diff --git a/src/SemanticScuttle/Service/Vote.php b/src/SemanticScuttle/Service/Vote.php index 3c4a144..4a5baab 100644 --- a/src/SemanticScuttle/Service/Vote.php +++ b/src/SemanticScuttle/Service/Vote.php @@ -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. @@ -15,16 +26,14 @@   * 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 index 0000000..90fae48 --- /dev/null +++ b/tests/VoteTest.php @@ -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 | 
