10000 [Config] extracted the xml parsing from XmlUtils::loadFile into XmlUt… by Basster · Pull Request #23482 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Config] extracted the xml parsing from XmlUtils::loadFile into XmlUt… #23482

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
2 changes: 1 addition & 1 deletion src/Symfony/Component/BrowserKit/Cookie.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public function __construct($name, $value, $expires = null, $path = null, $domai
$this->rawValue = $value;
} else {
$this->value = $value;
$this->rawValue = urlencode($value);
$this->rawValue = rawurlencode($value);
}
$this->name = $name;
$this->path = empty($path) ? '/' : $path;
Expand Down
15 changes: 15 additions & 0 deletions src/Symfony/Component/BrowserKit/Tests/CookieTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,21 @@

class CookieTest extends TestCase
{
public function testToString()
{
$cookie = new Cookie('foo', 'bar', strtotime('Fri, 20-May-2011 15:25:52 GMT'), '/', '.myfoodomain.com', true);
$this->assertEquals('foo=bar; expires=Fri, 20 May 2011 15:25:52 GMT; domain=.myfoodomain.com; path=/; secure; httponly', (string) $cookie, '->__toString() returns string representation of the cookie');

$cookie = new Cookie('foo', 'bar with white spaces', strtotime('Fri, 20-May-2011 15:25:52 GMT'), '/', '.myfoodomain.com', true);
$this->assertEquals('foo=bar%20with%20white%20spaces; expires=Fri, 20 May 2011 15:25:52 GMT; domain=.myfoodomain.com; path=/; secure; httponly', (string) $cookie, '->__toString() encodes the value of the cookie according to RFC 3986 (white space = %20)');

$cookie = new Cookie('foo', null, 1, '/admin/', '.myfoodomain.com');
$this->assertEquals('foo=; expires=Thu, 01 Jan 1970 00:00:01 GMT; domain=.myfoodomain.com; path=/admin/; httponly', (string) $cookie, '->__toString() returns string representation of a cleared cookie if value is NULL');

$cookie = new Cookie('foo', 'bar', 0, '/', '');
$this->assertEquals('foo=bar; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; httponly', (string) $cookie);
}

/**
* @dataProvider getTestsForToFromString
*/
Expand Down
17 changes: 16 additions & 1 deletion src/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,28 @@ public function testLoadFile()
XmlUtils::loadFile($fixtures.'valid.xml', array($mock, 'validate'));
$this->fail();
} catch (\InvalidArgumentException $e) {
$this->assertContains('is not valid', $e->getMessage());
$this->assertRegExp('/The XML file "[\w:\/\\\.]+" is not valid\./', $e->getMessage());
}

$this->assertInstanceOf('DOMDocument', XmlUtils::loadFile($fixtures.'valid.xml', array($mock, 'validate')));
$this->assertSame(array(), libxml_get_errors());
}

public function testParse()
{
$fixtures = __DIR__.'/../Fixtures/Util/';

$mock = $this->getMockBuilder(__NAMESPACE__.'\Validator')->getMock();
$mock->expects($this->once())->method('validate')->will($this->onConsecutiveCalls(false, true));

try {
XmlUtils::parse(file_get_contents($fixtures.'valid.xml'), array($mock, 'validate'));
$this->fail();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A better solution is to use @expectedException and @expectedExceptionMessage

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just re-used the way it has been done in the other tests in this class. Normally I'd go with the annotations, too.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other tests are written this way, because they try to test multiple cases in the same test. This is a legacy from tests written in the early days of Symfony's usage of PHPUnit.

} catch (\InvalidArgumentException $e) {
$this->assertContains('The XML is not valid', $e->getMessage());
}
}

public function testLoadFileWithInternalErrorsEnabled()
{
$internalErrors = libxml_use_internal_errors(true);
Expand Down
44 changes: 35 additions & 9 deletions src/Symfony/Component/Config/Util/XmlUtils.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Martin Hasoň <martin.hason@gmail.com>
* @author Ole Rößner <ole@roessner.it>
*/
class XmlUtils
{
const XML_IS_NOT_VALID_MESSAGE = 'The XML is not valid.';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-1 for defining a public constant with this message. We don't do it anywhere in Symfony

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay


/**
* This class should not be instantiated.
*/
Expand All @@ -29,22 +32,17 @@ private function __construct()
}

/**
* Loads an XML file.
* Parses an XML string.
*
* @param string $file An XML file path
* @param string $content An XML string
* @param string|callable|null $schemaOrCallable An XSD schema file path, a callable, or null to disable validation
*
* @return \DOMDocument
*
* @throws \InvalidArgumentException When loading of XML file returns error
*/
public static function loadFile($file, $schemaOrCallable = null)
public static function parse($content, $schemaOrCallable = null)
{
$content = @file_get_contents($file);
if ('' === trim($content)) {
throw new \InvalidArgumentException(sprintf('File %s does not contain valid XML, it is empty.', $file));
}

$internalErrors = libxml_use_internal_errors(true);
$disableEntities = libxml_disable_entity_loader(true);
libxml_clear_errors();
Expand Down Expand Up @@ -91,7 +89,7 @@ public static function loadFile($file, $schemaOrCallable = null)
if (!$valid) {
$messages = static::getXmlErrors($internalErrors);
if (empty($messages)) {
$messages = array(sprintf('The XML file "%s" is not valid.', $file));
$messages = array(self::XML_IS_NOT_VALID_MESSAGE);
}
throw new \InvalidArgumentException(implode("\n", $messages), 0, $e);
}
Expand All @@ -103,6 +101,34 @@ public static function loadFile($file, $schemaOrCallable = null)
return $dom;
}

/**
* Loads an XML file.
*
* @param string $file An XML file path
* @param string|callable|null $schemaOrCallable An XSD schema file path, a callable, or null to disable validation
*
* @return \DOMDocument
*
* @throws \InvalidArgumentException When loading of XML file returns error
*/
public static function loadFile($file, $schemaOrCallable = null)
{
$content = @file_get_contents($file);
if ('' === trim($content)) {
throw new \InvalidArgumentException(sprintf('File %s does not contain valid XML, it is empty.', $file));
}

try {
return static::parse($content, $schemaOrCallable);
} catch (\InvalidArgumentException $ex) {
throw new \InvalidArgumentException(
str_replace(self::XML_IS_NOT_VALID_MESSAGE, sprintf('The XML file "%s" is not valid.', $file), $ex->getMessage()),
$ex->getCode(),
$ex->getPrevious()
);
}
}

/**
* Converts a \DomElement object to a PHP array.
*
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Component/HttpFoundation/Cookie.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public function __toString()
if ('' === (string) $this->getValue()) {
$str .= 'deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001);
} else {
$str .= urlencode($this->getValue());
$str .= rawurlencode($this->getValue());

if (0 !== $this->getExpiresTime()) {
$str .= '; expires='.gmdate('D, d-M-Y H:i:s T', $this->getExpiresTime());
Expand Down
3 changes: 3 additions & 0 deletions src/Symfony/Component/HttpFoundation/Tests/CookieTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ public function testToString()
$cookie = new Cookie('foo', 'bar', strtotime('Fri, 20-May-2011 15:25:52 GMT'), '/', '.myfoodomain.com', true);
$this->assertEquals('foo=bar; expires=Fri, 20-May-2011 15:25:52 GMT; path=/; domain=.myfoodomain.com; secure; httponly', (string) $cookie, '->__toString() returns string representation of the cookie');

$cookie = new Cookie('foo', 'bar with white spaces', strtotime('Fri, 20-May-2011 15:25:52 GMT'), '/', '.myfoodomain.com', true);
$this->assertEquals('foo=bar%20with%20white%20spaces; expires=Fri, 20-May-2011 15:25:52 GMT; path=/; domain=.myfoodomain.com; secure; httponly', (string) $cookie, '->__toString() encodes the value of the cookie according to RFC 3986 (white space = %20)');

$cookie = new Cookie('foo', null, 1, '/admin/', '.myfoodomain.com');
$this->assertEquals('foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; path=/admin/; domain=.myfoodomain.com; httponly', (string) $cookie, '->__toString() returns string representation of a cleared cookie if value is NULL');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ public function authenticate(TokenInterface $token)
break;
}
} catch (AccountStatusException $e) {
$e->setToken($token);
$lastException = $e;

throw $e;
break;
} catch (AuthenticationException $e) {
$lastException = $e;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@

use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager;
use Symfony\Component\Security\Core\AuthenticationEvents;
use Symfony\Component\Security\Core\Event\AuthenticationEvent;
use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent;
use Symfony\Component\Security\Core\Exception\ProviderNotFoundException;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\AccountStatusException;
Expand Down Expand Up @@ -124,6 +127,50 @@ public function testEraseCredentialFlag()
$this->assertEquals('bar', $token->getCredentials());
}

public function testAuthenticateDispatchesAuthenticationFailureEvent()
{
$token = new UsernamePasswordToken('foo', 'bar', 'key');
$provider = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface')->getMock();
$provider->expects($this->once())->method('supports')->willReturn(true);
$provider->expects($this->once())->method('authenticate')->willThrowException($exception = new AuthenticationException());

$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$dispatcher
->expects($this->once())
->method('dispatch')
->with(AuthenticationEvents::AUTHENTICATION_FAILURE, $this->equalTo(new AuthenticationFailureEvent($token, $exception)));

$manager = new AuthenticationProviderManager(array($provider));
$manager->setEventDispatcher($dispatcher);

try {
$manager->authenticate($token);
$this->fail('->authenticate() should rethrow exceptions');
} catch (AuthenticationException $e) {
$this->assertSame($token, $exception->getToken());
}
}

public function testAuthenticateDispatchesAuthenticationSuccessEvent()
{
$token = new UsernamePasswordToken('foo', 'bar', 'key');

$provider = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface')->getMock();
$provider->expects($this->once())->method('supports')->willReturn(true);
$provider->expects($this->once())->method('authenticate')->willReturn($token);

$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$dispatcher
->expects($this->once())
->method('dispatch')
->with(AuthenticationEvents::AUTHENTICATION_SUCCESS, $this->equalTo(new AuthenticationEvent($token)));

$manager = new AuthenticationProviderManager(array($provider));
$manager->setEventDispatcher($dispatcher);

$this->assertSame($token, $manager->authenticate($token));
}

protected function getAuthenticationProvider($supports, $token = null, $exception = null)
{
$provider = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface')->getMock();
Expand Down
0