Skip to content
Browse files

Adding test suite, travis config to run it and new auth adapter (100%…

… test coverage). Deprecating previous auth adapters
  • Loading branch information...
1 parent 13e8921 commit 6a2ae93ece20d89722ca9ec6bc2c905401c1f239 @Ocramius Ocramius committed Jun 30, 2012
View
6 .travis.yml
@@ -11,10 +11,12 @@ before_script:
- cp ../DoctrineModule/.travis/composer.json ./
- curl -s http://getcomposer.org/installer | php
- php composer.phar install
- - rm -rf vendor/doctrine/DoctrineModule
- - cp -r ../DoctrineModule vendor/doctrine/
+ - rm -rf vendor/doctrine/doctrine-module
+ - cp -r ../DoctrineModule vendor/doctrine/doctrine-module
- rm config/application.config.php && cp ../DoctrineModule/.travis/application.config.php config/
script:
- ./vendor/bin/doctrine-module help
- ./vendor/bin/doctrine-module list
+ - cd vendor/doctrine/doctrine-module/tests
+ - phpunit
View
2 src/DoctrineModule/Authentication/Adapter/DoctrineEntity.php
@@ -30,7 +30,7 @@
/**
* Authentication adapter that uses a Doctrine Entity for verification.
*
- * @deprecated please use DoctrineModule\Authentication\Adapter\DoctrineObject
+ * @deprecated please use DoctrineModule\Authentication\Adapter\DoctrineObjectRepository
* @license MIT
* @link http://www.doctrine-project.org/
* @since 0.1.0
View
1 src/DoctrineModule/Authentication/Adapter/DoctrineObject.php
@@ -27,6 +27,7 @@
/**
* Abstract authentication adapter that uses a Doctrine object for verification.
*
+ * @deprecated please use DoctrineModule\Authentication\Adapter\DoctrineObjectRepository
* @license MIT
* @link http://www.doctrine-project.org/
* @since 0.2.0
View
382 src/DoctrineModule/Authentication/Adapter/DoctrineObjectRepository.php
@@ -0,0 +1,382 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace DoctrineModule\Authentication\Adapter;
+
+use Doctrine\Common\Persistence\ObjectRepository;
+use Zend\Authentication\Adapter\AdapterInterface;
+use Zend\Authentication\Adapter\Exception;
+use Zend\Authentication\Result as AuthenticationResult;
+
+/**
+ * Abstract authentication adapter that uses a Doctrine object for verification.
+ *
+ * @license MIT
+ * @link http://www.doctrine-project.org/
+ * @since 0.2.0
+ * @author Tim Roediger <superdweebie@gmail.com>
+ */
+class DoctrineObjectRepository implements AdapterInterface
+{
+ /**
+ * Doctrine ObjectRepository instance
+ *
+ * @var ObjectRepository
+ */
+ protected $objectRepository;
+
+ /**
+ * Doctrine object class that holds the identity.
+ *
+ * @var string
+ */
+ protected $identityClassName;
+
+ /**
+ * Identity property to check credential against.
+ *
+ * @var string
+ */
+ protected $identityProperty;
+
+ /**
+ * Credential property to check credential against.
+ *
+ * @var string
+ */
+ protected $credentialProperty;
+
+ /**
+ * User supplied identity.
+ *
+ * @var string
+ */
+ protected $identityValue;
+
+ /**
+ * User supplied credential.
+ *
+ * @var string
+ */
+ protected $credentialValue;
+
+ /**
+ * User supplied credential.
+ *
+ * @var mixed
+ */
+ protected $credentialCallable;
+
+ /**
+ * User supplied identity
+ *
+ * @var mixed
+ */
+ protected $identityCallable;
+
+ /**
+ * Contains the authentication results.
+ *
+ * @var array
+ */
+ protected $authenticationResultInfo = null;
+
+ /**
+ * __construct() - Sets configuration options
+ *
+ * @param ObjectRepository $objectRepository
+ * @param string $identityClassName
+ * @param string $identityProperty
+ * @param string $credentialProperty
+ * @return void
+ */
+ public function __construct(
+ ObjectRepository $objectRepository,
+ $identityClassName,
+ $identityProperty = 'username',
+ $credentialProperty = 'password'
+ ) {
+ $this->setObjectRepository($objectRepository);
+ $this->setIdentityClassName($identityClassName);
+ $this->setIdentityProperty($identityProperty);
+ $this->setCredentialProperty($credentialProperty);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return \Zend\Authentication\Result
+ */
+ public function authenticate()
+ {
+ $this->authenticateSetup();
+ $identity = $this->objectRepository->findOneBy(array($this->identityProperty => $this->identityValue));
+
+ if (!$identity) {
+ $this->authenticationResultInfo['code'] = AuthenticationResult::FAILURE_IDENTITY_NOT_FOUND;
+ $this->authenticationResultInfo['messages'][] = 'A record with the supplied identity could not be found.';
+ return $this->authenticateCreateAuthResult();
+ }
+
+ $authResult = $this->authenticateValidateIdentity($identity);
+ return $authResult;
+ }
+
+ /**
+ * Sets the object repository where to look for identities
+ *
+ * @param ObjectRepository $objectRepository
+ * @return self
+ */
+ public function setObjectRepository(ObjectRepository $objectRepository)
+ {
+ $this->objectRepository = $objectRepository;
+ return $this;
+ }
+
+ /**
+ * Sets the identity class to use for authentication.
+ *
+ * @param string $identityClassName
+ * @return self
+ */
+ public function setIdentityClassName($identityClassName)
+ {
+ if (!class_exists($identityClassName)) {
+ throw new Exception\InvalidArgumentException(sprintf(
+ 'Provided $identityClassName "%s" does not exist or could not be loaded',
+ $identityClassName
+ ));
+ }
+
+ $this->identityClassName = $identityClassName;
+ return $this;
+ }
+
+ /**
+ * Set the value to be used as the identity
+ *
+ * @param mixed $value
+ * @return self
+ */
+ public function setIdentityValue($identityValue)
+ {
+ $this->identityValue = $identityValue;
+ return $this;
+ }
+
+ /**
+ * Set the credential value to be used.
+ *
+ * @param mixed $credentialValue
+ * @return self
+ */
+ public function setCredentialValue($credentialValue)
+ {
+ $this->credentialValue = $credentialValue;
+ return $this;
+ }
+
+ /**
+ * Set the credential callable to be used to transform the password
+ * before checking.
+ *
+ * @param string $callable
+ * @throws \InvalidArgumentException if argument is not a callable function
+ * @return self
+ */
+ public function setCredentialCallable($callable)
+ {
+ if (!is_callable($callable)) {
+ throw new Exception\InvalidArgumentException(sprintf(
+ '"%s" is not a callable',
+ is_string($callable) ? $callable : gettype($callable)
+ ));
+ }
+
+ $this->credentialCallable = $callable;
+ return $this;
+ }
+
+ /**
+ * Set the identity callable to be used when saving the identity property to the
+ * authentication result info.
+ *
+ * @param string $callable
+ * @throws \InvalidArgumentException if argument is not a callable function
+ * @return self
+ */
+ public function setIdentityCallable($callable)
+ {
+ if (!is_callable($callable)) {
+ throw new Exception\InvalidArgumentException(sprintf(
+ '"%s" is not a callable',
+ is_string($callable) ? $callable : gettype($callable)
+ ));
+ }
+
+ $this->identityCallable = $callable;
+ return $this;
+ }
+
+ /**
+ * Set the property name to be used as the identity property
+ *
+ * @param string $identityProperty
+ * @return self
+ */
+ public function setIdentityProperty($identityProperty)
+ {
+ if (!$identityProperty) {
+ throw new Exception\InvalidArgumentException(sprintf(
+ 'Provided $identityProperty is invalid, %s given',
+ gettype($identityProperty)
+ ));
+ }
+
+ $this->identityProperty = (string) $identityProperty;
+ return $this;
+ }
+
+ /**
+ * Set the property name to be used as the credential property
+ *
+ * @param string $credentialField
+ * @return self
+ */
+ public function setCredentialProperty($credentialProperty)
+ {
+ if (!$credentialProperty) {
+ throw new Exception\InvalidArgumentException(sprintf(
+ 'Provided $credentialProperty is invalid, %s given',
+ gettype($credentialProperty)
+ ));
+ }
+
+ $this->credentialProperty = (string) $credentialProperty;
+ return $this;
+ }
+
+ /**
+ * This method attempts to validate that the record in the resultset is indeed a
+ * record that matched the identity provided to this adapter.
+ *
+ * @param object $identity
+ * @throws \UnexpectedValueException - if the identity is not the class expected
+ * @throws \BadMethodCallException - if the credentialProperty cannot be accessed on identity
+ * @return \Zend\Authentication\Result
+ */
+ protected function authenticateValidateIdentity($identity)
+ {
+ if (!$identity instanceof $this->identityClassName) {
+ throw new Exception\UnexpectedValueException(sprintf(
+ 'Identity class type expected was %s, but got %s',
+ $this->identityClassName,
+ get_class($identity)
+ ));
+ }
+
+ $getter = 'get' . ucfirst($this->credentialProperty);
+ $vars = get_object_vars($identity);
+ $documentCredential = null;
+
+ if (method_exists($identity, $getter)) {
+ $documentCredential = $identity->$getter();
+ } else if (isset($identity->{$this->credentialProperty}) || isset($vars[$this->credentialProperty])) {
+ $documentCredential = $identity->{$this->credentialProperty};
+ } else {
+ throw new Exception\UnexpectedValueException(sprintf(
+ 'Property (%s) in (%s) is not accessible. You should implement %s::%s()',
+ $this->credentialProperty,
+ get_class($identity),
+ get_class($identity),
+ $getter
+ ));
+ }
+
+ $credentialValue = $this->credentialValue;
+ $callable = $this->credentialCallable;
+
+ if ($callable) {
+ $credentialValue = call_user_func($callable, $identity, $credentialValue);
+ }
+
+ if ($credentialValue !== true && $credentialValue != $documentCredential) {
+ $this->authenticationResultInfo['code'] = AuthenticationResult::FAILURE_CREDENTIAL_INVALID;
+ $this->authenticationResultInfo['messages'][] = 'Supplied credential is invalid.';
+ return $this->authenticateCreateAuthResult();
+ }
+
+ $identityCallable = $this->identityCallable;
+ if ($identityCallable) {
+ $identity = call_user_func($identityCallable, $identity);
+ }
+
+ $this->authenticationResultInfo['code'] = AuthenticationResult::SUCCESS;
+ $this->authenticationResultInfo['identity'] = $identity;
+ $this->authenticationResultInfo['messages'][] = 'Authentication successful.';
+ return $this->authenticateCreateAuthResult();
+ }
+
+ /**
+ * This method abstracts the steps involved with making sure that this adapter was
+ * indeed setup properly with all required pieces of information.
+ *
+ * @throws \Zend\Authentication\Adapter\Exception\RuntimeException - in the event that setup was not done properly
+ * @return bool
+ */
+ protected function authenticateSetup()
+ {
+ if (null === $this->identityValue) {
+ throw new Exception\RuntimeException(
+ 'A value for the identity was not provided prior to authentication with DoctrineObject authentication '
+ . 'adapter'
+ );
+ }
+
+ if (null === $this->credentialValue) {
+ throw new Exception\RuntimeException(
+ 'A credential value was not provided prior to authentication with DoctrineObject authentication adapter'
+ );
+ }
+
+ $this->authenticationResultInfo = array(
+ 'code' => AuthenticationResult::FAILURE,
+ 'identity' => $this->identityValue,
+ 'messages' => array()
+ );
+
+ return true;
+ }
+
+ /**
+ * Creates a Zend_Auth_Result object from the information that has been collected
+ * during the authenticate() attempt.
+ *
+ * @return \Zend\Authentication\Result
+ */
+ protected function authenticateCreateAuthResult()
+ {
+ return new AuthenticationResult(
+ $this->authenticationResultInfo['code'],
+ $this->authenticationResultInfo['identity'],
+ $this->authenticationResultInfo['messages']
+ );
+ }
+}
View
1 tests/.gitignore
@@ -0,0 +1 @@
+TestConfiguration.php
View
48 tests/Bootstrap.php
@@ -0,0 +1,48 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+use DoctrineModuleTest\ServiceManagerTestCase;
+
+chdir(__DIR__);
+
+$previousDir = '.';
+
+while (!file_exists('config/application.config.php')) {
+ $dir = dirname(getcwd());
+
+ if ($previousDir === $dir) {
+ throw new RuntimeException(
+ 'Unable to locate "config/application.config.php":'
+ . ' is OcraDiCompiler in a sub-directory of your application skeleton?'
+ );
+ }
+
+ $previousDir = $dir;
+ chdir($dir);
+}
+
+if (!include('vendor/autoload.php')) {
+ throw new RuntimeException('vendor/autoload.php could not be found. Did you run `php composer.phar install`?');
+}
+
+if (!$config = @include __DIR__ . '/TestConfiguration.php') {
+ $config = require __DIR__ . '/TestConfiguration.php.dist';
+}
+
+ServiceManagerTestCase::setServiceManagerConfiguration($config);
View
278 tests/DoctrineModuleTest/Authentication/Adapter/DoctrineObjectRepositoryTest.php
@@ -0,0 +1,278 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace DoctrineModuleTest\Authentication\Adapter;
+
+use PHPUnit_Framework_TestCase as BaseTestCase;
+use DoctrineModule\Authentication\Adapter\DoctrineObjectRepository as ObjectRepositoryAdapter;
+use DoctrineModuleTest\Authentication\Adapter\TestAsset\IdentityObject;
+use DoctrineModuleTest\Authentication\Adapter\TestAsset\PublicPropertiesIdentityObject;
+
+class DoctrineObjectRepositoryTest extends BaseTestCase
+{
+ public function testWillRejectInvalidIdentityClassName()
+ {
+ $this->setExpectedException(
+ 'Zend\Authentication\Adapter\Exception\InvalidArgumentException',
+ 'Provided $identityClassName "' . __NAMESPACE__ . '\TestAsset\SomeNonExistingClassName'
+ . '" does not exist or could not be loaded'
+ );
+ new ObjectRepositoryAdapter(
+ $this->getMock('Doctrine\Common\Persistence\ObjectRepository'),
+ __NAMESPACE__ . '\TestAsset\SomeNonExistingClassName'
+ );
+ }
+
+ public function testWillRejectInvalidIdentityProperty()
+ {
+ $this->setExpectedException(
+ 'Zend\Authentication\Adapter\Exception\InvalidArgumentException',
+ 'Provided $identityProperty is invalid, boolean given'
+ );
+ new ObjectRepositoryAdapter(
+ $this->getMock('Doctrine\Common\Persistence\ObjectRepository'),
+ __NAMESPACE__ . '\TestAsset\IdentityObject',
+ false
+ );
+ }
+
+ public function testWillRejectInvalidCredentialProperty()
+ {
+ $this->setExpectedException(
+ 'Zend\Authentication\Adapter\Exception\InvalidArgumentException',
+ 'Provided $credentialProperty is invalid, boolean given'
+ );
+ new ObjectRepositoryAdapter(
+ $this->getMock('Doctrine\Common\Persistence\ObjectRepository'),
+ __NAMESPACE__ . '\TestAsset\IdentityObject',
+ 'username',
+ false
+ );
+ }
+
+ public function testWillRequireIdentityValue()
+ {
+ $this->setExpectedException(
+ 'Zend\Authentication\Adapter\Exception\RuntimeException',
+ 'A value for the identity was not provided prior to authentication with DoctrineObject authentication '
+ . 'adapter'
+ );
+ $adapter = new ObjectRepositoryAdapter(
+ $this->getMock('Doctrine\Common\Persistence\ObjectRepository'),
+ __NAMESPACE__ . '\TestAsset\IdentityObject'
+ );
+ $adapter->setCredentialValue('a credential');
+ $adapter->authenticate();
+ }
+
+ public function testWillRequireCredentialValue()
+ {
+ $this->setExpectedException(
+ 'Zend\Authentication\Adapter\Exception\RuntimeException',
+ 'A credential value was not provided prior to authentication with DoctrineObject authentication adapter'
+ );
+ $adapter = new ObjectRepositoryAdapter(
+ $this->getMock('Doctrine\Common\Persistence\ObjectRepository'),
+ __NAMESPACE__ . '\TestAsset\IdentityObject'
+ );
+ $adapter->setIdentityValue('an identity');
+ $adapter->authenticate();
+ }
+
+ public function testWillRejectInvalidCredentialCallable()
+ {
+ $this->setExpectedException(
+ 'Zend\Authentication\Adapter\Exception\InvalidArgumentException',
+ '"array" is not a callable'
+ );
+ $adapter = new ObjectRepositoryAdapter(
+ $this->getMock('Doctrine\Common\Persistence\ObjectRepository'),
+ __NAMESPACE__ . '\TestAsset\IdentityObject'
+ );
+ $adapter->setCredentialCallable(array());
+ $adapter->authenticate();
+ }
+
+ public function testWillRejectInvalidIdentityCallable()
+ {
+ $this->setExpectedException(
+ 'Zend\Authentication\Adapter\Exception\InvalidArgumentException',
+ '"array" is not a callable'
+ );
+ $adapter = new ObjectRepositoryAdapter(
+ $this->getMock('Doctrine\Common\Persistence\ObjectRepository'),
+ __NAMESPACE__ . '\TestAsset\IdentityObject'
+ );
+ $adapter->setIdentityCallable(array());
+ $adapter->authenticate();
+ }
+
+ public function testAuthentication()
+ {
+ $entity = new IdentityObject();
+ $entity->setUsername('a username');
+ $entity->setPassword('a password');
+
+ $objectRepository = $this->getMock('Doctrine\Common\Persistence\ObjectRepository');
+ $method = $objectRepository
+ ->expects($this->exactly(2))
+ ->method('findOneBy')
+ ->with($this->equalTo(array('username' => 'a username')))
+ ->will($this->returnValue($entity));
+
+ $adapter = new ObjectRepositoryAdapter($objectRepository, __NAMESPACE__ . '\TestAsset\IdentityObject');
+ $adapter->setIdentityValue('a username');
+ $adapter->setCredentialValue('a password');
+
+ $result = $adapter->authenticate();
+
+ $this->assertTrue($result->isValid());
+
+ $method->will($this->returnValue(null));
+
+ $result = $adapter->authenticate();
+
+ $this->assertFalse($result->isValid());
+ }
+
+ public function testAuthenticationWithPublicProperties()
+ {
+ $entity = new PublicPropertiesIdentityObject();
+ $entity->username = 'a username';
+ $entity->password = 'a password';
+
+ $objectRepository = $this->getMock('Doctrine\Common\Persistence\ObjectRepository');
+ $method = $objectRepository
+ ->expects($this->exactly(2))
+ ->method('findOneBy')
+ ->with($this->equalTo(array('username' => 'a username')))
+ ->will($this->returnValue($entity));
+
+ $adapter = new ObjectRepositoryAdapter(
+ $objectRepository,
+ __NAMESPACE__ . '\TestAsset\PublicPropertiesIdentityObject'
+ );
+ $adapter->setIdentityValue('a username');
+ $adapter->setCredentialValue('a password');
+
+ $result = $adapter->authenticate();
+
+ $this->assertTrue($result->isValid());
+
+ $method->will($this->returnValue(null));
+
+ $result = $adapter->authenticate();
+
+ $this->assertFalse($result->isValid());
+ }
+
+ public function testWillRefuseToAuthenticateWithoutGettersOrPublicMethods()
+ {
+ $this->setExpectedException('Zend\Authentication\Adapter\Exception\UnexpectedValueException');
+
+ $objectRepository = $this->getMock('Doctrine\Common\Persistence\ObjectRepository');
+ $objectRepository
+ ->expects($this->once())
+ ->method('findOneBy')
+ ->with($this->equalTo(array('username' => 'a username')))
+ ->will($this->returnValue(new \stdClass()));
+
+ $adapter = new ObjectRepositoryAdapter($objectRepository, 'stdClass');
+ $adapter->setIdentityValue('a username');
+ $adapter->setCredentialValue('a password');
+ $adapter->authenticate();
+ }
+
+ public function testCanGetSpecificValueFromEntityThroughIdentityCallable()
+ {
+ $entity = new IdentityObject();
+ $entity->setUsername('username');
+ $entity->setPassword('password');
+
+ $objectRepository = $this->getMock('Doctrine\Common\Persistence\ObjectRepository');
+ $objectRepository
+ ->expects($this->once())
+ ->method('findOneBy')
+ ->with($this->equalTo(array('username' => 'username')))
+ ->will($this->returnValue($entity));
+
+ $adapter = new ObjectRepositoryAdapter($objectRepository, __NAMESPACE__ . '\TestAsset\IdentityObject');
+ $adapter->setIdentityValue('username');
+ $adapter->setCredentialValue('password');
+ // enforced type hinting to verify that closure is invoked correctly
+ $adapter->setIdentityCallable(function(IdentityObject $identity) {
+ return 'callable enforced value';
+ });
+
+ $result = $adapter->authenticate();
+
+ $this->assertEquals('callable enforced value', $result->getIdentity());
+ }
+
+ public function testCanValidateWithSpecialCrypt()
+ {
+ $hash = '$2a$07$usesomesillystringforsalt$';
+ $entity = new IdentityObject();
+ $entity->setUsername('username');
+ // Crypt password using Blowfish
+ $entity->setPassword(crypt('password', $hash));
+
+ $objectRepository = $this->getMock('Doctrine\Common\Persistence\ObjectRepository');
+ $objectRepository
+ ->expects($this->exactly(2))
+ ->method('findOneBy')
+ ->with($this->equalTo(array('username' => 'username')))
+ ->will($this->returnValue($entity));
+
+ $adapter = new ObjectRepositoryAdapter($objectRepository, __NAMESPACE__ . '\TestAsset\IdentityObject');
+ $adapter->setIdentityValue('username');
+ $adapter->setCredentialValue('password');
+ // enforced type hinting to verify that closure is invoked correctly
+ $adapter->setCredentialCallable(function(IdentityObject $identity, $credentialValue) use ($hash) {
+ return $identity->getPassword() === crypt($credentialValue, $hash);
+ });
+
+ $result = $adapter->authenticate();
+
+ $this->assertTrue($result->isValid());
+
+ $adapter->setCredentialValue('wrong password');
+ $result = $adapter->authenticate();
+
+ $this->assertFalse($result->isValid());
+ }
+
+ public function testWillRefuseToAuthenticateWhenInvalidInstanceIsFound()
+ {
+ $this->setExpectedException('Zend\Authentication\Adapter\Exception\UnexpectedValueException');
+
+ $objectRepository = $this->getMock('Doctrine\Common\Persistence\ObjectRepository');
+ $objectRepository
+ ->expects($this->once())
+ ->method('findOneBy')
+ ->with($this->equalTo(array('username' => 'a username')))
+ ->will($this->returnValue(new \stdClass()));
+
+ $adapter = new ObjectRepositoryAdapter($objectRepository, __NAMESPACE__ . '\TestAsset\IdentityObject');
+ $adapter->setIdentityValue('a username');
+ $adapter->setCredentialValue('a password');
+
+ $adapter->authenticate();
+ }
+}
View
65 tests/DoctrineModuleTest/Authentication/Adapter/TestAsset/IdentityObject.php
@@ -0,0 +1,65 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace DoctrineModuleTest\Authentication\Adapter\TestAsset;
+
+class IdentityObject
+{
+ /**
+ * @var string|null
+ */
+ protected $username;
+
+ /**
+ * @var string|null
+ */
+ protected $password;
+
+ /**
+ * @param string $password
+ */
+ public function setPassword($password)
+ {
+ $this->password = (string) $password;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getPassword()
+ {
+ return $this->password;
+ }
+
+ /**
+ * @param string $username
+ */
+ public function setUsername($username)
+ {
+ $this->username = (string) $username;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getUsername()
+ {
+ return $this->username;
+ }
+}
View
33 tests/DoctrineModuleTest/Authentication/Adapter/TestAsset/PublicPropertiesIdentityObject.php
@@ -0,0 +1,33 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace DoctrineModuleTest\Authentication\Adapter\TestAsset;
+
+class PublicPropertiesIdentityObject
+{
+ /**
+ * @var string|null
+ */
+ public $username;
+
+ /**
+ * @var string|null
+ */
+ public $password;
+}
View
70 tests/DoctrineModuleTest/ServiceManagerTestCase.php
@@ -0,0 +1,70 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace DoctrineModuleTest;
+
+use PHPUnit_Framework_TestCase as BaseTestCase;
+use Zend\ServiceManager\ServiceManager;
+use Zend\Mvc\Service\ServiceManagerConfiguration;
+
+/**
+ * Base test case to be used when a service manager instance is required
+ */
+class ServiceManagerTestCase extends BaseTestCase
+{
+ /**
+ * @var array
+ */
+ private static $configuration = array();
+
+ /**
+ * @static
+ * @param array $configuration
+ */
+ public static function setServiceManagerConfiguration(array $configuration)
+ {
+ static::$configuration = $configuration;
+ }
+
+ /**
+ * @static
+ * @return array
+ */
+ public static function getServiceManagerConfiguration()
+ {
+ return static::$configuration;
+ }
+
+ /**
+ * Retrieves a new ServiceManager instance
+ *
+ * @param array|null $configuration
+ * @return ServiceManager
+ */
+ public function getServiceManager(array $configuration = null)
+ {
+ $configuration = $configuration ?: static::getServiceManagerConfiguration();
+ $serviceManager = new ServiceManager(new ServiceManagerConfiguration($configuration));
+ $serviceManager->setService('ApplicationConfiguration', $configuration);
+ /* @var $moduleManager \Zend\ModuleManager\ModuleManagerInterface */
+ $moduleManager = $serviceManager->get('ModuleManager');
+ $moduleManager->loadModules();
+ return $serviceManager;
+ }
+}
View
16 tests/TestConfiguration.php.dist
@@ -0,0 +1,16 @@
+<?php
+return array(
+ 'modules' => array(
+ 'DoctrineModule',
+ ),
+ 'module_listener_options' => array(
+ 'config_cache_enabled' => false,
+ 'cache_dir' => 'data/cache',
+ 'module_paths' => array(
+ './vendor',
+ ),
+ ),
+ 'service_manager' => array(
+ 'use_defaults' => true,
+ ),
+);
View
11 tests/phpunit.xml
@@ -0,0 +1,11 @@
+<phpunit
+ bootstrap="./Bootstrap.php"
+ colors="true"
+ backupGlobals="false"
+>
+ <testsuites>
+ <testsuite name="DoctrineModule Test Suite">
+ <directory>./</directory>
+ </testsuite>
+ </testsuites>
+</phpunit>

0 comments on commit 6a2ae93

Please sign in to comment.
Something went wrong with that request. Please try again.