summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcweiske <cweiske@b3834d28-1941-0410-a4f8-b48e95affb8f>2009-10-24 08:07:55 +0000
committercweiske <cweiske@b3834d28-1941-0410-a4f8-b48e95affb8f>2009-10-24 08:07:55 +0000
commitf3c36ee5c983a93ffb99dd1201b9e9831aa0eb11 (patch)
treea1110a02a9e7b36d9758fa4c0a3bea0bc9b48faa
parent00ba74e0c407a80f11bdd9724f9e8f885dc725e9 (diff)
downloadsemanticscuttle-f3c36ee5c983a93ffb99dd1201b9e9831aa0eb11.tar.gz
semanticscuttle-f3c36ee5c983a93ffb99dd1201b9e9831aa0eb11.tar.bz2
Implement voting service and unit tests for it
git-svn-id: https://semanticscuttle.svn.sourceforge.net/svnroot/semanticscuttle/trunk@401 b3834d28-1941-0410-a4f8-b48e95affb8f
-rw-r--r--src/SemanticScuttle/Service/Vote.php137
-rw-r--r--tests/VoteTest.php353
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