Add forms

This commit is contained in:
Romain Neutron
2013-04-30 20:30:17 +02:00
parent 518aab9e4a
commit 5e6d506d8d
20 changed files with 564 additions and 7 deletions

View File

@@ -0,0 +1,34 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Form\Constraint;
use Alchemy\Phrasea\Application;
use Symfony\Component\Validator\Constraint;
class NewEmail extends Constraint
{
private $app;
public function __construct(Application $app)
{
$this->message = _('This email is already bound to an account');
$this->app = $app;
parent::__construct();
}
public function isAlreadyRegistered($email)
{
$ret = (Boolean) \User_Adapter::get_usr_id_from_email($this->app, $email);
return $ret;
}
}

View File

@@ -0,0 +1,28 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Form\Constraint;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class NewEmailValidator extends ConstraintValidator
{
/**
* {@inheritDoc}
*/
public function validate($value, Constraint $constraint)
{
if ($constraint->isAlreadyRegistered($value)) {
$this->context->addViolation(_('There is already an account bound to this email address'));
}
}
}

View File

@@ -0,0 +1,40 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Form\Constraint;
use Alchemy\Phrasea\Application;
use Symfony\Component\Validator\Constraint;
class PasswordToken extends Constraint
{
private $app;
private $random;
public function __construct(Application $app, \random $random)
{
$this->message = _('The token provided is not valid anymore');
$this->app = $app;
$this->random = $random;
parent::__construct();
}
public function isValid($token)
{
try {
$datas = $this->random->helloToken($this->app, $token);
} catch (\Exception_NotFound $e) {
return false;
}
return \random::TYPE_PASSWORD === $datas['type'];
}
}

View File

@@ -0,0 +1,28 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Form\Constraint;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class PasswordTokenValidator extends ConstraintValidator
{
/**
* {@inheritDoc}
*/
public function validate($value, Constraint $constraint)
{
if ($constraint->isValid($value)) {
$this->context->addViolation('The token provided is not valid anymore');
}
}
}

View File

@@ -0,0 +1,64 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Form\Login;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Form\Constraint\PasswordToken;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Form used to renew password when password lost
*/
class PhraseaRecoverPasswordForm extends AbstractType
{
private $app;
public function __construct(Application $app)
{
$this->app = $app;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('token', 'hidden', array(
'required' => true,
'constraints' => array(
new PasswordToken($this->app, $this->app['tokens'])
)
));
$builder->add('password', 'password', array(
'label' => _('New password'),
'required' => true,
'constraints' => array(
new Assert\NotBlank(),
new Assert\Length(array('min' => 5)),
)
));
$builder->add('passwordConfirm', 'password', array(
'label' => _('New password (confirmation)'),
'required' => false,
'constraints' => array(
new Assert\NotBlank(),
new Assert\Length(array('min' => 5)),
)
));
}
public function getName()
{
return null;
}
}

View File

@@ -11,6 +11,7 @@
namespace Alchemy\Phrasea\Form\Login;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Utilities\String\Camelizer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
@@ -23,8 +24,9 @@ class PhraseaRegisterForm extends AbstractType
private $params;
private $camelizer;
public function __construct(array $available, array $params = array(), Camelizer $camelizer = null)
public function __construct(Application $app, array $available, array $params = array(), Camelizer $camelizer = null)
{
$this->app = $app;
$this->available = $available;
$this->params = $params;
$this->camelizer = $camelizer ?: new Camelizer();
@@ -37,6 +39,8 @@ class PhraseaRegisterForm extends AbstractType
'required' => true,
'constraints' => array(
new Assert\NotBlank(),
new Assert\Email(),
new \Alchemy\Phrasea\Form\Constraint\NewEmail($this->app),
),
));
@@ -44,7 +48,8 @@ class PhraseaRegisterForm extends AbstractType
'label' => _('Password'),
'required' => true,
'constraints' => array(
new Assert\NotBlank()
new Assert\NotBlank(),
new Assert\Length(array('min' => 5)),
)
));
@@ -52,13 +57,40 @@ class PhraseaRegisterForm extends AbstractType
'label' => _('Password (confirmation)'),
'required' => false,
'constraints' => array(
new Assert\NotBlank()
new Assert\NotBlank(),
new Assert\Length(array('min' => 5)),
)
));
$builder->add('accept-tou', 'checkbox', array(
'mapped' => false,
'required' => false
"constraints" => new Assert\True(array(
"message" => "Please accept the Terms and conditions in order to register")
),
));
require_once($this->app['phraseanet.registry']->get('GV_RootPath') . 'lib/classes/deprecated/inscript.api.php');
$baseIds = array();
foreach (\giveMeBases($this->app) as $sbas_id => $baseInsc) {
if (($baseInsc['CollsCGU'] || $baseInsc['Colls']) && $baseInsc['inscript']) {
if ($baseInsc['Colls']) {
foreach($baseInsc['Colls'] as $collId => $collName) {
$baseIds[\phrasea::baseFromColl($sbas_id, $collId, $this->app)] = $collName;
}
}
if ($baseInsc['CollsCGU']) {
foreach($baseInsc['CollsCGU'] as $collId => $collName) {
$baseIds[\phrasea::baseFromColl($sbas_id, $collId, $this->app)] = $collName;
}
}
}
}
$builder->add('collections', 'choice', array(
'choices' => $baseIds,
'multiple' => true,
'expanded' => true,
));
foreach ($this->params as $param) {

View File

@@ -15,6 +15,9 @@ use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Form used to renew the password once the user is logged, in its account.
*/
class PhraseaRenewPasswordForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
@@ -31,7 +34,8 @@ class PhraseaRenewPasswordForm extends AbstractType
'label' => _('New password'),
'required' => true,
'constraints' => array(
new Assert\NotBlank()
new Assert\NotBlank(),
new Assert\Length(array('min' => 5)),
)
));
@@ -39,7 +43,8 @@ class PhraseaRenewPasswordForm extends AbstractType
'label' => _('New password (confirmation)'),
'required' => false,
'constraints' => array(
new Assert\NotBlank()
new Assert\NotBlank(),
new Assert\Length(array('min' => 5)),
)
));
}

View File

@@ -13,7 +13,6 @@ namespace Alchemy\Phrasea\Form\Type;
use Symfony\Component\Form\AbstractType;
// write tests
class GeonameType extends AbstractType
{
public function getParent()

View File

@@ -0,0 +1,32 @@
<?php
namespace Alchemy\Tests\Phrasea\Form\Constraint;
use Alchemy\Phrasea\Form\Constraint\NewEmail;
class NewEmailTest extends \PhraseanetPHPUnitAbstract
{
public function testAnUnknownAddressIsNotAlreadyRegistered()
{
$constraint = new NewEmail(self::$DI['app']);
$this->assertFalse($constraint->isAlreadyRegistered('nonehere'));
}
public function testARegisteredAddressIsAlreadyRegistered()
{
$constraint = new NewEmail(self::$DI['app']);
$this->assertTrue($constraint->isAlreadyRegistered(self::$DI['user']->get_email()));
}
public function testNullIsNotAlreadyRegistered()
{
$constraint = new NewEmail(self::$DI['app']);
$this->assertFalse($constraint->isAlreadyRegistered('null'));
}
public function testBlankIsNotAlreadyRegistered()
{
$constraint = new NewEmail(self::$DI['app']);
$this->assertFalse($constraint->isAlreadyRegistered(''));
}
}

View File

@@ -0,0 +1,53 @@
<?php
namespace Alchemy\Tests\Phrasea\Form\Constraint;
use Alchemy\Phrasea\Form\Constraint\NewEmailValidator;
class NewEmailValidatorTest extends \PhraseanetPHPUnitAbstract
{
/**
* @dataProvider provideValidationData
*/
public function testValidate($value, $alreadyRegistered)
{
$context = $this->getMock('Symfony\Component\Validator\ExecutionContextInterface');
$builder = $context
->expects($this->exactly($alreadyRegistered ? 1 : 0))
->method('addViolation');
if ($alreadyRegistered) {
$builder->with($this->isType('string'));
}
$validator = new NewEmailValidator();
$validator->initialize($context);
$constraint = $this->getConstraint();
$constraint
->expects($this->once())
->method('isAlreadyRegistered')
->with($value)
->will($this->returnValue($alreadyRegistered));
$validator->validate($value, $constraint);
}
public function provideValidationData()
{
return array(
array('romain@neutron.io', true),
array('romain@neutron.io', false),
array('', false),
array(null, false),
);
}
private function getConstraint()
{
return $this
->getMockBuilder('Alchemy\Phrasea\Form\Constraint\NewEmail')
->disableOriginalConstructor()
->getMock();
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace Alchemy\Tests\Phrasea\Form\Constraint;
use Alchemy\Phrasea\Form\Constraint\PasswordToken;
class PasswordTokenTest extends \PhraseanetPHPUnitAbstract
{
public function testInvalidTokenIsNotValid()
{
$random = $this
->getMockBuilder('random')
->disableOriginalConstructor()
->setMethods(array('helloToken'))
->getMock();
$token = \random::generatePassword();
$random
->expects($this->once())
->method('helloToken')
->with(self::$DI['app'], $token)
->will($this->throwException(new \Exception_NotFound('Token not found')));
$constraint = new PasswordToken(self::$DI['app'], $random);
$this->assertFalse($constraint->isValid($token));
}
public function testValidTokenIsValid()
{
$random = $this
->getMockBuilder('random')
->disableOriginalConstructor()
->setMethods(array('helloToken'))
->getMock();
$token = \random::generatePassword();
$random
->expects($this->once())
->method('helloToken')
->with(self::$DI['app'], $token)
->will($this->returnValue(array('usr_id' => mt_rand(), 'type' => \random::TYPE_PASSWORD)));
$constraint = new PasswordToken(self::$DI['app'], $random);
$this->assertTrue($constraint->isValid($token));
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace Alchemy\Tests\Phrasea\Form\Constraint;
use Alchemy\Phrasea\Form\Constraint\PasswordTokenValidator;
class PasswordTokenValidatorTest extends \PhraseanetPHPUnitAbstract
{
/**
* @dataProvider provideValidationData
*/
public function testValidate($value, $isValid)
{
$context = $this->getMock('Symfony\Component\Validator\ExecutionContextInterface');
$builder = $context
->expects($this->exactly($isValid ? 1 : 0))
->method('addViolation');
if ($isValid) {
$builder->with($this->isType('string'));
}
$validator = new PasswordTokenValidator();
$validator->initialize($context);
$constraint = $this->getConstraint();
$constraint
->expects($this->once())
->method('isValid')
->with($value)
->will($this->returnValue($isValid));
$validator->validate($value, $constraint);
}
public function provideValidationData()
{
return array(
array(\random::generatePassword(), true),
array(\random::generatePassword(), false),
);
}
private function getConstraint()
{
return $this
->getMockBuilder('Alchemy\Phrasea\Form\Constraint\PasswordToken')
->disableOriginalConstructor()
->getMock();
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace Alchemy\Tests\Phrasea\Form;
abstract class FormTestCase extends \PhraseanetPHPUnitAbstract
{
public function testBuildForm()
{
$form = $this->getForm();
$builder = $this
->getMockBuilder('Symfony\Component\Form\FormBuilder')
->disableOriginalConstructor()
->getMock();
$form->buildForm($builder, array('disabled' => false));
}
public function testGetName()
{
$form = $this->getForm();
$this->assertNull($form->getName());
}
abstract protected function getForm();
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Alchemy\Tests\Phrasea\Form\Login;
use Alchemy\Phrasea\Form\Login\PhraseaAuthenticationForm;
use Alchemy\Tests\Phrasea\Form\FormTestCase;
class PhraseaAuthenticationFormTest extends FormTestCase
{
protected function getForm()
{
return new PhraseaAuthenticationForm();
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Alchemy\Tests\Phrasea\Form\Login;
use Alchemy\Phrasea\Form\Login\PhraseaAuthenticationWithMappingForm;;
use Alchemy\Tests\Phrasea\Form\FormTestCase;
class PhraseaAuthenticationWithMappingFormTest extends FormTestCase
{
protected function getForm()
{
return new PhraseaAuthenticationWithMappingForm();
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Alchemy\Tests\Phrasea\Form\Login;
use Alchemy\Phrasea\Form\Login\PhraseaForgotPasswordForm;;
use Alchemy\Tests\Phrasea\Form\FormTestCase;
class PhraseaForgotPasswordFormTest extends FormTestCase
{
protected function getForm()
{
return new PhraseaForgotPasswordForm();
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Alchemy\Tests\Phrasea\Form\Login;
use Alchemy\Phrasea\Form\Login\PhraseaRecoverPasswordForm;;
use Alchemy\Tests\Phrasea\Form\FormTestCase;
class PhraseaRecoverPasswordFormTest extends FormTestCase
{
protected function getForm()
{
return new PhraseaRecoverPasswordForm(self::$DI['app']);
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Alchemy\Tests\Phrasea\Form\Login;
use Alchemy\Phrasea\Form\Login\PhraseaRegisterForm;;
use Alchemy\Tests\Phrasea\Form\FormTestCase;
class PhraseaRegisterFormTest extends FormTestCase
{
protected function getForm()
{
$available = array(
'parameter' => array(
'type' => 'text',
'label' => 'Yollah !',
)
);
$params = array(
array(
'name' => 'parameter',
'required' => true
)
);
return new PhraseaRegisterForm(self::$DI['app'], $available, $params, new \Alchemy\Phrasea\Utilities\String\Camelizer());
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Alchemy\Tests\Phrasea\Form\Login;
use Alchemy\Phrasea\Form\Login\PhraseaRenewPasswordForm;;
use Alchemy\Tests\Phrasea\Form\FormTestCase;
class PhraseaRenewPasswordFormTest extends FormTestCase
{
protected function getForm()
{
return new PhraseaRenewPasswordForm();
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace Alchemy\Tests\Phrasea\Form\Type;
use Alchemy\Phrasea\Form\Type\GeonameType;
class GeonameTypeTest extends \PhraseanetPHPUnitAbstract
{
public function testGetParent()
{
$geoname = new GeonameType();
$this->assertEquals('text', $geoname->getParent());
}
public function testGetName()
{
$geoname = new GeonameType();
$this->assertEquals('geoname', $geoname->getName());
}
}