Merge branch '2.3' into 2.4

* 2.3:
  remove obsolete test file
  [FrameworkBundle] output failed matched path for clarification
  bug #10242 Missing checkPreAuth from RememberMeAuthenticationProvider
  [Validator] Fixed StaticMethodLoaderTest to actually test something
  [Form] Fixed ValidatorTypeGuesser to guess properties without constraints not to be required
  Use request format from request in twig ExceptionController
  [Form] Moved POST_MAX_SIZE validation from FormValidator to request handler
  [Form] Add a form error if post_max_size has been reached.
  Response::isNotModified returns true when If-Modified-Since is later than Last-Modified
  [WebProfilerBundle] turbolinks compatibility

Conflicts:
	src/Symfony/Component/Form/CHANGELOG.md
	src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php
	src/Symfony/Component/Security/Core/Tests/Authentication/Provider/RememberMeAuthenticationProviderTest.php
This commit is contained in:
Fabien Potencier 2014-09-25 10:51:47 +02:00
commit 43b83cf8db
26 changed files with 418 additions and 287 deletions

View File

@ -89,7 +89,7 @@ EOF
}
if (!$matches) {
$output->writeln('<fg=red>None of the routes match</>');
$output->writeln(sprintf('<fg=red>None of the routes match the path "%s"</>', $input->getArgument('path_info')));
return 1;
}

View File

@ -147,8 +147,11 @@
</service>
<!-- FormTypeHttpFoundationExtension -->
<service id="form.server_params" class="Symfony\Component\Form\Util\ServerParams" public="false"/>
<service id="form.type_extension.form.http_foundation" class="Symfony\Component\Form\Extension\HttpFoundation\Type\FormTypeHttpFoundationExtension">
<tag name="form.type_extension" alias="form" />
<argument type="service" id="form.server_params"/>
</service>
<!-- FormTypeValidatorExtension -->

View File

@ -1,47 +0,0 @@
<?php
set_include_path('{include_path}');
require_once 'PHPUnit/Autoload.php';
ob_start();
function __phpunit_run_isolated_test()
{
if (!class_exists('{className}')) {
require_once '{filename}';
}
$result = new PHPUnit_Framework_TestResult;
$result->collectRawCodeCoverageInformation({collectCodeCoverageInformation});
$test = new {className}('{methodName}', unserialize('{data}'), '{dataName}');
$test->setDependencyInput(unserialize('{dependencyInput}'));
$test->setInIsolation(TRUE);
ob_end_clean();
ob_start();
$test->run($result);
$output = ob_get_clean();
print serialize(
array(
'testResult' => $test->getResult(),
'numAssertions' => $test->getNumAssertions(),
'result' => $result,
'output' => $output
)
);
ob_start();
}
{globals}
if (isset($GLOBALS['__PHPUNIT_BOOTSTRAP'])) {
require_once $GLOBALS['__PHPUNIT_BOOTSTRAP'];
unset($GLOBALS['__PHPUNIT_BOOTSTRAP']);
}
{constants}
__phpunit_run_isolated_test();
ob_end_clean();
?>

View File

@ -39,20 +39,19 @@ class ExceptionController
* @param Request $request The request
* @param FlattenException $exception A FlattenException instance
* @param DebugLoggerInterface $logger A DebugLoggerInterface instance
* @param string $_format The format to use for rendering (html, xml, ...)
*
* @return Response
*
* @throws \InvalidArgumentException When the exception template does not exist
*/
public function showAction(Request $request, FlattenException $exception, DebugLoggerInterface $logger = null, $_format = 'html')
public function showAction(Request $request, FlattenException $exception, DebugLoggerInterface $logger = null)
{
$currentContent = $this->getAndCleanOutputBuffering($request->headers->get('X-Php-Ob-Level', -1));
$code = $exception->getStatusCode();
return new Response($this->twig->render(
$this->findTemplate($request, $_format, $code, $this->debug),
$this->findTemplate($request, $request->getRequestFormat(), $code, $this->debug),
array(
'status_code' => $code,
'status_text' => isset(Response::$statusTexts[$code]) ? Response::$statusTexts[$code] : '',

View File

@ -1,6 +1,6 @@
<!-- START of Symfony2 Web Debug Toolbar -->
{% if 'normal' != position %}
<div id="sfMiniToolbar-{{ token }}" class="sf-minitoolbar">
<div id="sfMiniToolbar-{{ token }}" class="sf-minitoolbar" data-no-turbolink>
<a href="javascript:void(0);" title="Show Symfony toolbar" onclick="
var elem = this.parentNode;
if (elem.style.display == 'none') {
@ -24,7 +24,7 @@
<div id="sfToolbarClearer-{{ token }}" style="clear: both; height: 38px;"></div>
{% endif %}
<div id="sfToolbarMainContent-{{ token }}" class="sf-toolbarreset">
<div id="sfToolbarMainContent-{{ token }}" class="sf-toolbarreset" data-no-turbolink>
{% for name, template in templates %}
{{ template.renderblock('toolbar', {
'collector': profile.getcollector(name),

View File

@ -56,8 +56,7 @@ class FormType extends BaseType
->setDataLocked($isDataOptionSet)
->setDataMapper($options['compound'] ? new PropertyPathMapper($this->propertyAccessor) : null)
->setMethod($options['method'])
->setAction($options['action'])
;
->setAction($options['action']);
if ($options['trim']) {
$builder->addEventSubscriber(new TrimListener());
@ -171,25 +170,26 @@ class FormType extends BaseType
));
$resolver->setDefaults(array(
'data_class' => $dataClass,
'empty_data' => $emptyData,
'trim' => true,
'required' => true,
'read_only' => false,
'max_length' => null,
'pattern' => null,
'property_path' => null,
'mapped' => true,
'by_reference' => true,
'error_bubbling' => $errorBubbling,
'label_attr' => array(),
'virtual' => null,
'inherit_data' => $inheritData,
'compound' => true,
'method' => 'POST',
'data_class' => $dataClass,
'empty_data' => $emptyData,
'trim' => true,
'required' => true,
'read_only' => false,
'max_length' => null,
'pattern' => null,
'property_path' => null,
'mapped' => true,
'by_reference' => true,
'error_bubbling' => $errorBubbling,
'label_attr' => array(),
'virtual' => null,
'inherit_data' => $inheritData,
'compound' => true,
'method' => 'POST',
// According to RFC 2396 (http://www.ietf.org/rfc/rfc2396.txt)
// section 4.2., empty URIs are considered same-document references
'action' => '',
'action' => '',
'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.',
));
$resolver->setAllowedTypes(array(

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\Form\Extension\HttpFoundation;
use Symfony\Component\Form\AbstractExtension;
use Symfony\Component\Form\Util\ServerParams;
/**
* Integrates the HttpFoundation component with the Form library.
@ -20,10 +21,20 @@ use Symfony\Component\Form\AbstractExtension;
*/
class HttpFoundationExtension extends AbstractExtension
{
/**
* @var ServerParams
*/
private $serverParams;
public function __construct(ServerParams $serverParams = null)
{
$this->serverParams = $serverParams;
}
protected function loadTypeExtensions()
{
return array(
new Type\FormTypeHttpFoundationExtension(),
new Type\FormTypeHttpFoundationExtension($this->serverParams),
);
}
}

View File

@ -12,8 +12,10 @@
namespace Symfony\Component\Form\Extension\HttpFoundation;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\RequestHandlerInterface;
use Symfony\Component\Form\Util\ServerParams;
use Symfony\Component\HttpFoundation\Request;
/**
@ -24,6 +26,19 @@ use Symfony\Component\HttpFoundation\Request;
*/
class HttpFoundationRequestHandler implements RequestHandlerInterface
{
/**
* @var ServerParams
*/
private $serverParams;
/**
* {@inheritdoc}
*/
public function __construct(ServerParams $serverParams = null)
{
$this->serverParams = $serverParams ?: new ServerParams();
}
/**
* {@inheritdoc}
*/
@ -53,6 +68,25 @@ class HttpFoundationRequestHandler implements RequestHandlerInterface
$data = $request->query->get($name);
}
} else {
// Mark the form with an error if the uploaded size was too large
// This is done here and not in FormValidator because $_POST is
// empty when that error occurs. Hence the form is never submitted.
$contentLength = $this->serverParams->getContentLength();
$maxContentLength = $this->serverParams->getPostMaxSize();
if (!empty($maxContentLength) && $contentLength > $maxContentLength) {
// Submit the form, but don't clear the default values
$form->submit(null, false);
$form->addError(new FormError(
$form->getConfig()->getOption('post_max_size_message'),
null,
array('{{ max }}' => $this->serverParams->getNormalizedIniPostMaxSize())
));
return;
}
if ('' === $name) {
$params = $request->request->all();
$files = $request->files->all();

View File

@ -15,6 +15,7 @@ use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\HttpFoundation\EventListener\BindRequestListener;
use Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationRequestHandler;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Util\ServerParams;
/**
* @author Bernhard Schussek <bschussek@gmail.com>
@ -31,10 +32,10 @@ class FormTypeHttpFoundationExtension extends AbstractTypeExtension
*/
private $requestHandler;
public function __construct()
public function __construct(ServerParams $serverParams = null)
{
$this->listener = new BindRequestListener();
$this->requestHandler = new HttpFoundationRequestHandler();
$this->requestHandler = new HttpFoundationRequestHandler($serverParams);
}
/**

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\Form\Extension\Validator\Constraints;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\Extension\Validator\Util\ServerParams;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
@ -21,22 +20,6 @@ use Symfony\Component\Validator\ConstraintValidator;
*/
class FormValidator extends ConstraintValidator
{
/**
* @var ServerParams
*/
private $serverParams;
/**
* Creates a validator with the given server parameters.
*
* @param ServerParams $params The server parameters. Default
* parameters are created if null.
*/
public function __construct(ServerParams $params = null)
{
$this->serverParams = $params ?: new ServerParams();
}
/**
* {@inheritdoc}
*/
@ -113,21 +96,6 @@ class FormValidator extends ConstraintValidator
$form->getExtraData()
);
}
// Mark the form with an error if the uploaded size was too large
$length = $this->serverParams->getContentLength();
if ($form->isRoot() && null !== $length) {
$max = $this->serverParams->getPostMaxSize();
if (!empty($max) && $length > $max) {
$this->context->addViolation(
$config->getOption('post_max_size_message'),
array('{{ max }}' => $this->serverParams->getNormalizedIniPostMaxSize()),
$length
);
}
}
}
/**

View File

@ -66,7 +66,6 @@ class FormTypeValidatorExtension extends BaseValidatorExtension
'invalid_message' => 'This value is not valid.',
'invalid_message_parameters' => array(),
'extra_fields_message' => 'This form should not contain extra fields.',
'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.',
));
$resolver->setNormalizers(array(

View File

@ -14,59 +14,6 @@ namespace Symfony\Component\Form\Extension\Validator\Util;
/**
* @author Bernhard Schussek <bschussek@gmail.com>
*/
class ServerParams
class ServerParams extends \Symfony\Component\Form\Util\ServerParams
{
/**
* Returns maximum post size in bytes.
*
* @return null|int The maximum post size in bytes
*/
public function getPostMaxSize()
{
$iniMax = strtolower($this->getNormalizedIniPostMaxSize());
if ('' === $iniMax) {
return;
}
$max = ltrim($iniMax, '+');
if (0 === strpos($max, '0x')) {
$max = intval($max, 16);
} elseif (0 === strpos($max, '0')) {
$max = intval($max, 8);
} else {
$max = intval($max);
}
switch (substr($iniMax, -1)) {
case 't': $max *= 1024;
case 'g': $max *= 1024;
case 'm': $max *= 1024;
case 'k': $max *= 1024;
}
return $max;
}
/**
* Returns the normalized "post_max_size" ini setting.
*
* @return string
*/
public function getNormalizedIniPostMaxSize()
{
return strtoupper(trim(ini_get('post_max_size')));
}
/**
* Returns the content length of the request.
*
* @return mixed The request content length.
*/
public function getContentLength()
{
return isset($_SERVER['CONTENT_LENGTH'])
? (int) $_SERVER['CONTENT_LENGTH']
: null;
}
}

View File

@ -276,10 +276,10 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface
}
}
}
}
if (null !== $defaultValue) {
$guesses[] = new ValueGuess($defaultValue, Guess::LOW_CONFIDENCE);
}
if (null !== $defaultValue) {
$guesses[] = new ValueGuess($defaultValue, Guess::LOW_CONFIDENCE);
}
return Guess::getBestGuess($guesses);

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\Form;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
use Symfony\Component\Form\Util\ServerParams;
/**
* A request handler using PHP's super globals $_GET, $_POST and $_SERVER.
@ -20,6 +21,19 @@ use Symfony\Component\Form\Exception\UnexpectedTypeException;
*/
class NativeRequestHandler implements RequestHandlerInterface
{
/**
* @var ServerParams
*/
private $serverParams;
/**
* {@inheritdoc}
*/
public function __construct(ServerParams $params = null)
{
$this->serverParams = $params ?: new ServerParams();
}
/**
* The allowed keys of the $_FILES array.
*
@ -62,6 +76,25 @@ class NativeRequestHandler implements RequestHandlerInterface
$data = $_GET[$name];
}
} else {
// Mark the form with an error if the uploaded size was too large
// This is done here and not in FormValidator because $_POST is
// empty when that error occurs. Hence the form is never submitted.
$contentLength = $this->serverParams->getContentLength();
$maxContentLength = $this->serverParams->getPostMaxSize();
if (!empty($maxContentLength) && $contentLength > $maxContentLength) {
// Submit the form, but don't clear the default values
$form->submit(null, false);
$form->addError(new FormError(
$form->getConfig()->getOption('post_max_size_message'),
null,
array('{{ max }}' => $this->serverParams->getNormalizedIniPostMaxSize())
));
return;
}
$fixedFiles = array();
foreach ($_FILES as $name => $file) {
$fixedFiles[$name] = self::stripEmptyFiles(self::fixPhpFilesArray($file));

View File

@ -11,21 +11,38 @@
namespace Symfony\Component\Form\Tests;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormFactory;
use Symfony\Component\Form\Forms;
use Symfony\Component\Form\RequestHandlerInterface;
/**
* @author Bernhard Schussek <bschussek@gmail.com>
*/
abstract class AbstractRequestHandlerTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \Symfony\Component\Form\RequestHandlerInterface
* @var RequestHandlerInterface
*/
protected $requestHandler;
/**
* @var FormFactory
*/
protected $factory;
protected $request;
protected $serverParams;
protected function setUp()
{
$this->serverParams = $this->getMock(
'Symfony\Component\Form\Util\ServerParams',
array('getNormalizedIniPostMaxSize', 'getContentLength')
);
$this->requestHandler = $this->getRequestHandler();
$this->factory = Forms::createFormFactoryBuilder()->getFormFactory();
$this->request = null;
}
@ -249,6 +266,50 @@ abstract class AbstractRequestHandlerTest extends \PHPUnit_Framework_TestCase
$this->requestHandler->handleRequest($form, $this->request);
}
/**
* @dataProvider getPostMaxSizeFixtures
*/
public function testAddFormErrorIfPostMaxSizeExceeded($contentLength, $iniMax, $shouldFail, array $errorParams = array())
{
$this->serverParams->expects($this->once())
->method('getContentLength')
->will($this->returnValue($contentLength));
$this->serverParams->expects($this->any())
->method('getNormalizedIniPostMaxSize')
->will($this->returnValue($iniMax));
$options = array('post_max_size_message' => 'Max {{ max }}!');
$form = $this->factory->createNamed('name', 'text', null, $options);
$this->setRequestData('POST', array(), array());
$this->requestHandler->handleRequest($form, $this->request);
if ($shouldFail) {
$errors = array(new FormError($options['post_max_size_message'], null, $errorParams));
$this->assertEquals($errors, $form->getErrors());
$this->assertTrue($form->isSubmitted());
} else {
$this->assertCount(0, $form->getErrors());
$this->assertFalse($form->isSubmitted());
}
}
public function getPostMaxSizeFixtures()
{
return array(
array(pow(1024, 3) + 1, '1G', true, array('{{ max }}' => '1G')),
array(pow(1024, 3), '1G', false),
array(pow(1024, 2) + 1, '1M', true, array('{{ max }}' => '1M')),
array(pow(1024, 2), '1M', false),
array(1024 + 1, '1K', true, array('{{ max }}' => '1K')),
array(1024, '1K', false),
array(null, '1K', false),
array(1024, '', false),
array(1024, 0, false),
);
}
abstract protected function setRequestData($method, $data, $files = array());
abstract protected function getRequestHandler();

View File

@ -43,7 +43,7 @@ class HttpFoundationRequestHandlerTest extends AbstractRequestHandlerTest
protected function getRequestHandler()
{
return new HttpFoundationRequestHandler();
return new HttpFoundationRequestHandler($this->serverParams);
}
protected function getMockFile()

View File

@ -542,69 +542,6 @@ class FormValidatorTest extends AbstractConstraintValidatorTest
), 'property.path', array('foo' => 'bar'));
}
/**
* @dataProvider getPostMaxSizeFixtures
*/
public function testPostMaxSizeViolation($contentLength, $iniMax, $nbViolation, array $params = array())
{
$this->serverParams->expects($this->once())
->method('getContentLength')
->will($this->returnValue($contentLength));
$this->serverParams->expects($this->any())
->method('getNormalizedIniPostMaxSize')
->will($this->returnValue($iniMax));
$options = array('post_max_size_message' => 'Max {{ max }}!');
$form = $this->getBuilder('name', null, $options)->getForm();
$this->validator->validate($form, new Form());
$violations = array();
for ($i = 0; $i < $nbViolation; ++$i) {
$violations[] = $this->createViolation($options['post_max_size_message'], $params, 'property.path', $contentLength);
}
$this->assertViolations($violations);
}
public function getPostMaxSizeFixtures()
{
return array(
array(pow(1024, 3) + 1, '1G', 1, array('{{ max }}' => '1G')),
array(pow(1024, 3), '1G', 0),
array(pow(1024, 2) + 1, '1M', 1, array('{{ max }}' => '1M')),
array(pow(1024, 2), '1M', 0),
array(1024 + 1, '1K', 1, array('{{ max }}' => '1K')),
array(1024, '1K', 0),
array(null, '1K', 0),
array(1024, '', 0),
array(1024, 0, 0),
);
}
public function testNoViolationIfNotRoot()
{
$this->serverParams->expects($this->once())
->method('getContentLength')
->will($this->returnValue(1025));
$this->serverParams->expects($this->never())
->method('getNormalizedIniPostMaxSize');
$parent = $this->getBuilder()
->setCompound(true)
->setDataMapper($this->getDataMapper())
->getForm();
$form = $this->getForm();
$parent->add($form);
$this->expectNoValidate();
$this->validator->validate($form, new Form());
$this->assertNoViolation();
}
/**
* Access has to be public, as this method is called via callback array
* in {@link testValidateFormDataCanHandleCallbackValidationGroups()}

View File

@ -13,32 +13,91 @@ namespace Symfony\Component\Form\Tests\Extension\Validator;
use Symfony\Component\Form\Extension\Validator\ValidatorTypeGuesser;
use Symfony\Component\Form\Guess\Guess;
use Symfony\Component\Form\Guess\ValueGuess;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\NotNull;
use Symfony\Component\Validator\Constraints\Range;
use Symfony\Component\Validator\Constraints\True;
use Symfony\Component\Validator\Constraints\Type;
use Symfony\Component\Validator\Mapping\ClassMetadata;
/**
* @author franek <franek@chicour.net>
*/
* @author franek <franek@chicour.net>
* @author Bernhard Schussek <bschussek@gmail.com>
*/
class ValidatorTypeGuesserTest extends \PHPUnit_Framework_TestCase
{
private $typeGuesser;
const TEST_CLASS = 'Symfony\Component\Form\Tests\Extension\Validator\ValidatorTypeGuesserTest_TestClass';
public function setUp()
const TEST_PROPERTY = 'property';
/**
* @var ValidatorTypeGuesser
*/
private $guesser;
/**
* @var ClassMetadata
*/
private $metadata;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $metadataFactory;
protected function setUp()
{
if (!class_exists('Symfony\Component\Validator\Constraint')) {
$this->markTestSkipped('The "Validator" component is not available');
}
$metadataFactory = $this->getMock('Symfony\Component\Validator\MetadataFactoryInterface');
$this->metadata = new ClassMetadata(self::TEST_CLASS);
$this->metadataFactory = $this->getMock('Symfony\Component\Validator\MetadataFactoryInterface');
$this->metadataFactory->expects($this->any())
->method('getMetadataFor')
->with(self::TEST_CLASS)
->will($this->returnValue($this->metadata));
$this->guesser = new ValidatorTypeGuesser($this->metadataFactory);
}
$this->typeGuesser = new ValidatorTypeGuesser($metadataFactory);
public function guessRequiredProvider()
{
return array(
array(new NotNull(), new ValueGuess(true, Guess::HIGH_CONFIDENCE)),
array(new NotBlank(), new ValueGuess(true, Guess::HIGH_CONFIDENCE)),
array(new True(), new ValueGuess(true, Guess::HIGH_CONFIDENCE)),
array(new Length(10), new ValueGuess(false, Guess::LOW_CONFIDENCE)),
array(new Range(array('min' => 1, 'max' => 20)), new ValueGuess(false, Guess::LOW_CONFIDENCE)),
);
}
/**
* @dataProvider guessRequiredProvider
*/
public function testGuessRequired($constraint, $guess)
{
// add distracting constraint
$this->metadata->addPropertyConstraint(self::TEST_PROPERTY, new Email());
// add constraint under test
$this->metadata->addPropertyConstraint(self::TEST_PROPERTY, $constraint);
$this->assertEquals($guess, $this->guesser->guessRequired(self::TEST_CLASS, self::TEST_PROPERTY));
}
public function testGuessRequiredReturnsFalseForUnmappedProperties()
{
$this->assertEquals(new ValueGuess(false, Guess::LOW_CONFIDENCE), $this->guesser->guessRequired(self::TEST_CLASS, self::TEST_PROPERTY));
}
public function testGuessMaxLengthForConstraintWithMaxValue()
{
$constraint = new Length(array('max' => '2'));
$result = $this->typeGuesser->guessMaxLengthForConstraint($constraint);
$result = $this->guesser->guessMaxLengthForConstraint($constraint);
$this->assertInstanceOf('Symfony\Component\Form\Guess\ValueGuess', $result);
$this->assertEquals(2, $result->getValue());
$this->assertEquals(Guess::HIGH_CONFIDENCE, $result->getConfidence());
@ -48,24 +107,11 @@ class ValidatorTypeGuesserTest extends \PHPUnit_Framework_TestCase
{
$constraint = new Length(array('min' => '2'));
$result = $this->typeGuesser->guessMaxLengthForConstraint($constraint);
$result = $this->guesser->guessMaxLengthForConstraint($constraint);
$this->assertNull($result);
}
/**
* @dataProvider dataProviderTestGuessMaxLengthForConstraintWithType
*/
public function testGuessMaxLengthForConstraintWithType($type)
{
$constraint = new Type($type);
$result = $this->typeGuesser->guessMaxLengthForConstraint($constraint);
$this->assertInstanceOf('Symfony\Component\Form\Guess\ValueGuess', $result);
$this->assertEquals(null, $result->getValue());
$this->assertEquals(Guess::MEDIUM_CONFIDENCE, $result->getConfidence());
}
public static function dataProviderTestGuessMaxLengthForConstraintWithType()
public function maxLengthTypeProvider()
{
return array (
array('double'),
@ -74,4 +120,22 @@ class ValidatorTypeGuesserTest extends \PHPUnit_Framework_TestCase
array('real'),
);
}
/**
* @dataProvider maxLengthTypeProvider
*/
public function testGuessMaxLengthForConstraintWithType($type)
{
$constraint = new Type($type);
$result = $this->guesser->guessMaxLengthForConstraint($constraint);
$this->assertInstanceOf('Symfony\Component\Form\Guess\ValueGuess', $result);
$this->assertNull($result->getValue());
$this->assertEquals(Guess::MEDIUM_CONFIDENCE, $result->getConfidence());
}
}
class ValidatorTypeGuesserTest_TestClass
{
private $property;
}

View File

@ -203,7 +203,7 @@ class NativeRequestHandlerTest extends AbstractRequestHandlerTest
protected function getRequestHandler()
{
return new NativeRequestHandler();
return new NativeRequestHandler($this->serverParams);
}
protected function getMockFile()

View File

@ -0,0 +1,72 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Form\Util;
/**
* @author Bernhard Schussek <bschussek@gmail.com>
*/
class ServerParams
{
/**
* Returns maximum post size in bytes.
*
* @return null|int The maximum post size in bytes
*/
public function getPostMaxSize()
{
$iniMax = strtolower($this->getNormalizedIniPostMaxSize());
if ('' === $iniMax) {
return;
}
$max = ltrim($iniMax, '+');
if (0 === strpos($max, '0x')) {
$max = intval($max, 16);
} elseif (0 === strpos($max, '0')) {
$max = intval($max, 8);
} else {
$max = intval($max);
}
switch (substr($iniMax, -1)) {
case 't': $max *= 1024;
case 'g': $max *= 1024;
case 'm': $max *= 1024;
case 'k': $max *= 1024;
}
return $max;
}
/**
* Returns the normalized "post_max_size" ini setting.
*
* @return string
*/
public function getNormalizedIniPostMaxSize()
{
return strtoupper(trim(ini_get('post_max_size')));
}
/**
* Returns the content length of the request.
*
* @return mixed The request content length.
*/
public function getContentLength()
{
return isset($_SERVER['CONTENT_LENGTH'])
? (int) $_SERVER['CONTENT_LENGTH']
: null;
}
}

View File

@ -1094,12 +1094,16 @@ class Response
return false;
}
$lastModified = $request->headers->get('If-Modified-Since');
$notModified = false;
$notModified = false;
$lastModified = $this->headers->get('Last-Modified');
$modifiedSince = $request->headers->get('If-Modified-Since');
if ($etags = $request->getEtags()) {
$notModified = (in_array($this->getEtag(), $etags) || in_array('*', $etags)) && (!$lastModified || $this->headers->get('Last-Modified') == $lastModified);
} elseif ($lastModified) {
$notModified = $lastModified == $this->headers->get('Last-Modified');
$notModified = in_array($this->getEtag(), $etags) || in_array('*', $etags);
}
if ($modifiedSince && $lastModified) {
$notModified = strtotime($modifiedSince) >= strtotime($lastModified) && (!$etags || $notModified);
}
if ($notModified) {

View File

@ -141,16 +141,24 @@ class ResponseTest extends ResponseTestCase
public function testIsNotModifiedLastModified()
{
$before = 'Sun, 25 Aug 2013 18:32:31 GMT';
$modified = 'Sun, 25 Aug 2013 18:33:31 GMT';
$after = 'Sun, 25 Aug 2013 19:33:31 GMT';
$request = new Request();
$request->headers->set('If-Modified-Since', $modified);
$response = new Response();
$response->headers->set('Last-Modified', $modified);
$response->headers->set('Last-Modified', $modified);
$this->assertTrue($response->isNotModified($request));
$response->headers->set('Last-Modified', $before);
$this->assertTrue($response->isNotModified($request));
$response->headers->set('Last-Modified', $after);
$this->assertFalse($response->isNotModified($request));
$response->headers->set('Last-Modified', '');
$this->assertFalse($response->isNotModified($request));
}
@ -175,6 +183,50 @@ class ResponseTest extends ResponseTestCase
$this->assertFalse($response->isNotModified($request));
}
public function testIsNotModifiedLastModifiedAndEtag()
{
$before = 'Sun, 25 Aug 2013 18:32:31 GMT';
$modified = 'Sun, 25 Aug 2013 18:33:31 GMT';
$after = 'Sun, 25 Aug 2013 19:33:31 GMT';
$etag = 'randomly_generated_etag';
$request = new Request();
$request->headers->set('if_none_match', sprintf('%s, %s', $etag, 'etagThree'));
$request->headers->set('If-Modified-Since', $modified);
$response = new Response();
$response->headers->set('ETag', $etag);
$response->headers->set('Last-Modified', $after);
$this->assertFalse($response->isNotModified($request));
$response->headers->set('ETag', 'non-existent-etag');
$response->headers->set('Last-Modified', $before);
$this->assertFalse($response->isNotModified($request));
$response->headers->set('ETag', $etag);
$response->headers->set('Last-Modified', $modified);
$this->assertTrue($response->isNotModified($request));
}
public function testIsNotModifiedIfModifiedSinceAndEtagWithoutLastModified()
{
$modified = 'Sun, 25 Aug 2013 18:33:31 GMT';
$etag = 'randomly_generated_etag';
$request = new Request();
$request->headers->set('if_none_match', sprintf('%s, %s', $etag, 'etagThree'));
$request->headers->set('If-Modified-Since', $modified);
$response = new Response();
$response->headers->set('ETag', $etag);
$this->assertTrue($response->isNotModified($request));
$response->headers->set('ETag', 'non-existent-etag');
$this->assertFalse($response->isNotModified($request));
}
public function testIsValidateable()
{
$response = new Response('', 200, array('Last-Modified' => $this->createDateTimeOneHourAgo()->format(DATE_RFC2822)));

View File

@ -50,7 +50,7 @@ class RememberMeAuthenticationProvider implements AuthenticationProviderInterfac
}
$user = $token->getUser();
$this->userChecker->checkPostAuth($user);
$this->userChecker->checkPreAuth($user);
$authenticatedToken = new RememberMeToken($user, $this->providerKey, $this->key);
$authenticatedToken->setAttributes($token->getAttributes());

View File

@ -12,7 +12,7 @@
namespace Symfony\Component\Security\Core\Tests\Authentication\Provider;
use Symfony\Component\Security\Core\Authentication\Provider\RememberMeAuthenticationProvider;
use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken;
use Symfony\Component\Security\Core\Exception\DisabledException;
use Symfony\Component\Security\Core\Role\Role;
class RememberMeAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
@ -45,15 +45,14 @@ class RememberMeAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
}
/**
* @expectedException \Symfony\Component\Security\Core\Exception\AccountExpiredException
* @expectedException \Symfony\Component\Security\Core\Exception\DisabledException
*/
public function testAuthenticateWhenPostChecksFails()
public function testAuthenticateWhenPreChecksFails()
{
$userChecker = $this->getMock('Symfony\Component\Security\Core\User\UserCheckerInterface');
$userChecker->expects($this->once())
->method('checkPostAuth')
->will($this->throwException($this->getMock('Symfony\Component\Security\Core\Exception\AccountExpiredException', null, array(), '')))
;
->method('checkPreAuth')
->will($this->throwException(new DisabledException()));
$provider = $this->getProvider($userChecker);
@ -65,8 +64,7 @@ class RememberMeAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
$user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
$user->expects($this->exactly(2))
->method('getRoles')
->will($this->returnValue(array('ROLE_FOO')))
;
->will($this->returnValue(array('ROLE_FOO')));
$provider = $this->getProvider();
@ -86,16 +84,14 @@ class RememberMeAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
$user
->expects($this->any())
->method('getRoles')
->will($this->returnValue(array()))
;
->will($this->returnValue(array()));
}
$token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\RememberMeToken', array('getProviderKey'), array($user, 'foo', $key));
$token
->expects($this->once())
->method('getProviderKey')
->will($this->returnValue('foo'))
;
->will($this->returnValue('foo'));
return $token;
}

View File

@ -4,7 +4,7 @@ namespace Symfony\Component\Validator\Tests\Mapping\Loader;
use Symfony\Component\Validator\Mapping\ClassMetadata;
abstract class AbstractMethodStaticLoader
abstract class AbstractStaticMethodLoader
{
abstract public static function loadMetadata(ClassMetadata $metadata);
}

View File

@ -90,22 +90,19 @@ class StaticMethodLoaderTest extends \PHPUnit_Framework_TestCase
public function testLoadClassMetadataIgnoresAbstractMethods()
{
error_reporting(E_ALL | E_STRICT);
// Disable error reporting, as AbstractStaticMethodLoader produces a
// strict standards error
error_reporting(0);
if (0 !== error_reporting()) {
$this->markTestSkipped('Could not disable error reporting');
}
include __DIR__.'/AbstractStaticMethodLoader.php';
$metadata = new ClassMetadata(__NAMESPACE__.'\AbstractStaticMethodLoader');
$loader = new StaticMethodLoader('loadMetadata');
$caught = false;
try {
include __DIR__.'/AbstractMethodStaticLoader.php';
} catch (\Exception $e) {
// catching the PHP notice that is converted to an exception by PHPUnit
$caught = true;
}
if (!$caught) {
$this->fail('AbstractMethodStaticLoader should produce a strict standard error.');
}
$metadata = new ClassMetadata(__NAMESPACE__.'\AbstractMethodStaticLoader');
$loader->loadClassMetadata($metadata);
$this->assertCount(0, $metadata->getConstraints());