partkeepr

fork of partkeepr
git clone https://git.e1e0.net/partkeepr.git
Log | Files | Refs | Submodules | README | LICENSE

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:
Asrc/backend/de/RaumZeitLabor/PartKeepr/UserPreference/Exceptions/UserPreferenceNotFoundException.php | 21+++++++++++++++++++++
Msrc/backend/de/RaumZeitLabor/PartKeepr/UserPreference/UserPreference.php | 66+++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Atests/UserPreference/UserPreferenceTest.php | 146+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtests/bootstrap.php | 63+++++++++++++++++++++++++++++++++++++++++----------------------
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