commit 153b5c0348572ba2e719d58be81f081f009bf610
parent ff744bd302a55e81cc364572169a058a066584c9
Author: Felicitus <felicitus@felicitus.org>
Date: Sat, 12 May 2012 06:57:13 +0200
Added some more helper methods for the user preferences; implemented unit tests for them.
Diffstat:
4 files changed, 261 insertions(+), 35 deletions(-)
diff --git a/src/backend/de/RaumZeitLabor/PartKeepr/UserPreference/Exceptions/UserPreferenceNotFoundException.php b/src/backend/de/RaumZeitLabor/PartKeepr/UserPreference/Exceptions/UserPreferenceNotFoundException.php
@@ -0,0 +1,20 @@
+<?php
+namespace de\RaumZeitLabor\PartKeepr\UserPreference\Exceptions;
+
+use de\RaumZeitLabor\PartKeepr\User\User,
+ de\RaumZeitLabor\PartKeepr\Util\SerializableException,
+ de\RaumZeitLabor\PartKeepr\PartKeepr;
+
+/**
+ * Is thrown when the user has given wrong credentials.
+ */
+class UserPreferenceNotFoundException extends SerializableException {
+ public function __construct (User $user, $preferenceKey) {
+ $message = sprintf( PartKeepr::i18n("User preference %s not found for user %s (%s)"),
+ $preferenceKey,
+ $user->getUsername(),
+ $user->getId());
+
+ parent::__construct($message);
+ }
+}+
\ No newline at end of file
diff --git a/src/backend/de/RaumZeitLabor/PartKeepr/UserPreference/UserPreference.php b/src/backend/de/RaumZeitLabor/PartKeepr/UserPreference/UserPreference.php
@@ -1,11 +1,13 @@
<?php
namespace de\RaumZeitLabor\PartKeepr\UserPreference;
-use de\RaumZeitLabor\PartKeepr\Util\Serializable;
-use de\RaumZeitLabor\PartKeepr\PartKeepr;
-use de\RaumZeitLabor\PartKeepr\User\User;
-use de\RaumZeitLabor\PartKeepr\Util\Configuration;
-use de\RaumZeitLabor\PartKeepr\Util\BaseEntity;
+use de\RaumZeitLabor\PartKeepr\Util\Serializable,
+ de\RaumZeitLabor\PartKeepr\PartKeepr,
+ de\RaumZeitLabor\PartKeepr\User\User,
+ de\RaumZeitLabor\PartKeepr\Util\Configuration,
+ de\RaumZeitLabor\PartKeepr\Util\BaseEntity,
+ de\RaumZeitLabor\PartKeepr\UserPreference\Exceptions\UserPreferenceNotFoundException,
+ Doctrine\ORM\NoResultException;
/**
* Represents a user preference entry.
@@ -13,7 +15,7 @@ use de\RaumZeitLabor\PartKeepr\Util\BaseEntity;
* User preferences are a simple key => value mechanism, where the developer can
* specify the key and value himself.
*
- * Note that values are stored internally as JSON to keep their type.
+ * Note that values are stored internally as serialized PHP values to keep their type.
*
* @Entity
**/
@@ -118,20 +120,58 @@ class UserPreference implements Serializable {
$query->setParameter("key", $key);
try {
- $up = $query->getSingleResult();
+ $userPreference = $query->getSingleResult();
} catch (\Exception $e) {
- $up = new UserPreference();
- $up->setUser($user);
- $up->setKey($key);
+ $userPreference = new UserPreference();
+ $userPreference->setUser($user);
+ $userPreference->setKey($key);
- PartKeepr::getEM()->persist($up);
+ PartKeepr::getEM()->persist($userPreference);
}
- $up->setValue($value);
+ $userPreference->setValue($value);
PartKeepr::getEM()->flush();
- return $up;
+ return $userPreference;
+ }
+
+ /**
+ * Returns a specific preference value for the given user
+ *
+ * @param User $user The user to retrieve the preference for
+ * @param string $key The preference key to retrieve
+ * @return string The preference string
+ * @throws UserPreferenceNotFoundException Thrown if the preference key was not found
+ */
+ public static function getPreferenceValue (User $user, $key) {
+ $userPreference = self::getPreference($user, $key);
+
+ return $userPreference->getValue();
+ }
+
+ /**
+ * Returns a specific preference object for the given user
+ *
+ * @param User $user The user to retrieve the preference for
+ * @param string $key The preference key to retrieve
+ * @return UserPreference The preference object
+ * @throws UserPreferenceNotFoundException Thrown if the preference key was not found
+ */
+ public static function getPreference (User $user, $key) {
+ $dql = "SELECT up FROM de\RaumZeitLabor\PartKeepr\UserPreference\UserPreference up WHERE up.user = :user AND ";
+ $dql .= "up.preferenceKey = :key";
+
+ $query = PartKeepr::getEM()->createQuery($dql);
+ $query->setParameter("user", $user);
+ $query->setParameter("key", $key);
+
+ try {
+ $up = $query->getSingleResult();
+ return $up;
+ } catch (NoResultException $e) {
+ throw new UserPreferenceNotFoundException($user, $key);
+ }
}
/**
diff --git a/tests/UserPreference/UserPreferenceTest.php b/tests/UserPreference/UserPreferenceTest.php
@@ -0,0 +1,145 @@
+<?php
+namespace de\RaumZeitLabor\PartKeepr\Tests\UserPreference;
+
+use de\RaumZeitLabor\PartKeepr\PartKeepr,
+ de\RaumZeitLabor\PartKeepr\User\User,
+ de\RaumZeitLabor\PartKeepr\UserPreference\UserPreference;
+
+class UserPreferenceTest extends \PHPUnit_Framework_TestCase {
+ protected $user;
+
+ /**
+ * Assigns the "regular" user for this test and deletes all user preferences for testing
+ * (non-PHPdoc)
+ * @see PHPUnit_Framework_TestCase::setUp()
+ */
+ protected function setUp () {
+ $this->user = User::loadByName("regular");
+
+ $this->deleteUserPreferences();
+ }
+
+ /**
+ * Deletes all user preferences after testing
+ * (non-PHPdoc)
+ * @see PHPUnit_Framework_TestCase::tearDown()
+ */
+ protected function tearDown () {
+ $this->deleteUserPreferences();
+ }
+
+ /**
+ * Deletes all user preferences for the test user.
+ *
+ * @param none
+ * @return nothing
+ */
+ protected function deleteUserPreferences () {
+ $dql = "DELETE FROM de\RaumZeitLabor\PartKeepr\UserPreference\UserPreference up WHERE up.user = :user";
+
+ $query = PartKeepr::getEM()->createQuery($dql);
+ $query->setParameter("user", $this->user);
+ $query->execute();
+ }
+
+ /**
+ * Tests if user preferences can be set
+ */
+ public function testSetUserPreference () {
+ $preferenceKey = "test1";
+ $preferenceValue = "123";
+
+ UserPreference::setPreference($this->user, $preferenceKey, $preferenceValue);
+
+ // Read back the set user preference to make sure it's valid
+ $this->assertEquals($preferenceValue, UserPreference::getPreferenceValue($this->user, $preferenceKey));
+
+ // Make sure that the user is set correctly
+ $this->assertEquals($this->user, UserPreference::getPreference($this->user, $preferenceKey)->getUser());
+
+ // Make sure the key is set correctly
+ $this->assertEquals($preferenceKey, UserPreference::getPreference($this->user, $preferenceKey)->getKey());
+
+ // Make sure that we only get one result when we set the same preference twice
+ UserPreference::setPreference($this->user, $preferenceKey, $preferenceValue);
+
+ $dql = "SELECT COUNT(up) FROM de\RaumZeitLabor\PartKeepr\UserPreference\UserPreference up WHERE ";
+ $dql .= "up.user = :user AND up.preferenceKey = :key";
+
+ $query = PartKeepr::getEM()->createQuery($dql);
+ $query->setParameter("user", $this->user);
+ $query->setParameter("key", $preferenceKey);
+
+ $this->assertEquals(1, $query->getSingleScalarResult());
+ }
+
+ /**
+ * Tests if the correct exception is thrown when attempting to load a non-existing user preference
+ * @expectedException de\RaumZeitLabor\PartKeepr\UserPreference\Exceptions\UserPreferenceNotFoundException
+ */
+ public function testGetNonExistingUserPreference () {
+ $preferenceKey = "test2";
+
+ UserPreference::getPreferenceValue($this->user, $preferenceKey);
+ }
+
+ /**
+ * Make sure that deleting a user preference actually works.
+ *
+ * We're expecting the UserPreferenceNotFoundException because we are attempting to retrieve the value of the
+ * previously deleted value.
+ *
+ * @expectedException de\RaumZeitLabor\PartKeepr\UserPreference\Exceptions\UserPreferenceNotFoundException
+ */
+ public function testDeleteUserPreference () {
+ $preferenceKey = "test3";
+ $preferenceValue = "123";
+
+ UserPreference::setPreference($this->user, $preferenceKey, $preferenceValue);
+
+ UserPreference::deletePreference($this->user, $preferenceKey);
+
+ // This one should give us the UserPreferenceNotFoundException
+ UserPreference::getPreferenceValue($this->user, $preferenceKey);
+ }
+
+ /**
+ * This test makes sure that the format in the database is a PHP serialized string. In case somebody
+ * decides to change the format, this test will fail. IF THIS TEST FAILS, YOU NEED TO PROVIDE A DATABASE
+ * UPGRADE METHOD! DO NOT CHANGE THIS TEST SO THAT IT SIMPLY PASSES!
+ */
+ public function testDatabaseFormat () {
+ $preferenceKey = "test4";
+ $preferenceValue = "123";
+
+ UserPreference::setPreference($this->user, $preferenceKey, $preferenceValue);
+
+ $dql = "SELECT up.preferenceValue FROM de\RaumZeitLabor\PartKeepr\UserPreference\UserPreference up WHERE ";
+ $dql .= "up.user = :user AND up.preferenceKey = :key";
+
+ $query = PartKeepr::getEM()->createQuery($dql);
+ $query->setParameter("user", $this->user);
+ $query->setParameter("key", $preferenceKey);
+
+ $this->assertEquals('s:3:"123";', $query->getSingleScalarResult());
+ }
+
+ /**
+ * Tests if the serialized format matches our requirements. Change this test if you've changed the
+ * implementation of the user preferences.
+ */
+ public function testSerialize () {
+ $preferenceKey = "test5";
+ $preferenceValue = "123";
+
+ $expectedArray = array(
+ "key" => $preferenceKey,
+ "value" => $preferenceValue,
+ "user_id" => $this->user->getId()
+ );
+
+ $userPreference = UserPreference::setPreference($this->user, $preferenceKey, $preferenceValue);
+
+ $this->assertEquals($expectedArray, $userPreference->serialize());
+ }
+}+
\ No newline at end of file
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
@@ -7,24 +7,43 @@ use de\RaumZeitLabor\PartKeepr\PartCategory\PartCategoryManager,
include(dirname(__DIR__). "/src/backend/de/RaumZeitLabor/PartKeepr/PartKeepr.php");
-PartKeepr::initialize("test");
-
-$tool = new \Doctrine\ORM\Tools\SchemaTool(PartKeepr::getEM());
-$classes = PartKeepr::getClassMetaData();
-
-$tool->dropSchema($classes);
-$tool->createSchema($classes);
-
-/* Some very basic installation things */
-PartCategoryManager::getInstance()->ensureRootExists();
-
-/* Create a blank admin user */
-$user = new User();
-$user->setUsername("admin");
-$user->setPassword("admin");
-$user->setAdmin(true);
-
-PartKeepr::getEM()->persist($user);
-
-
-PartKeepr::getEM()->flush();-
\ No newline at end of file
+/**
+ * Initializes a bootstrapped PartKeepr environment.
+ *
+ * This is done within a function because we don't want to pollute the globals, which would give the following message
+ * during unit tests:
+ *
+ * "PDOException: You cannot serialize or unserialize PDO instances"
+ */
+function initializeEnvironment () {
+ PartKeepr::initialize("test");
+
+ $tool = new \Doctrine\ORM\Tools\SchemaTool(PartKeepr::getEM());
+ $classes = PartKeepr::getClassMetaData();
+
+ $tool->dropDatabase();
+ $tool->createSchema($classes);
+
+ /* Some very basic installation things */
+ PartCategoryManager::getInstance()->ensureRootExists();
+
+ /* Create a blank admin user */
+ $user = new User();
+ $user->setUsername("admin");
+ $user->setPassword("admin");
+ $user->setAdmin(true);
+
+ PartKeepr::getEM()->persist($user);
+
+ /* Create a blank regular user */
+ $user = new User();
+ $user->setUsername("regular");
+ $user->setPassword("regular");
+ $user->setAdmin(false);
+
+ PartKeepr::getEM()->persist($user);
+
+ PartKeepr::getEM()->flush();
+}
+
+initializeEnvironment();+
\ No newline at end of file