[HttpFoundation] Add functional tests for Response::sendHeaders()

This commit is contained in:
cvilleger 2018-04-05 14:19:22 +02:00 committed by Nicolas Grekas
parent e350ea000f
commit 73fec237da
18 changed files with 232 additions and 22 deletions

View File

@ -145,12 +145,12 @@ class Cookie
$str = ($this->isRaw() ? $this->getName() : urlencode($this->getName())).'=';
if ('' === (string) $this->getValue()) {
$str .= 'deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; max-age=-31536001';
$str .= 'deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; Max-Age=0';
} else {
$str .= $this->isRaw() ? $this->getValue() : rawurlencode($this->getValue());
if (0 !== $this->getExpiresTime()) {
$str .= '; expires='.gmdate('D, d-M-Y H:i:s T', $this->getExpiresTime()).'; max-age='.$this->getMaxAge();
$str .= '; expires='.gmdate('D, d-M-Y H:i:s T', $this->getExpiresTime()).'; Max-Age='.$this->getMaxAge();
}
}
@ -224,7 +224,9 @@ class Cookie
*/
public function getMaxAge()
{
return 0 !== $this->expire ? $this->expire - time() : 0;
$maxAge = $this->expire - time();
return 0 >= $maxAge ? 0 : $maxAge;
}
/**

View File

@ -162,13 +162,13 @@ class CookieTest extends TestCase
public function testToString()
{
$cookie = new Cookie('foo', 'bar', $expire = 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; max-age='.($expire - time()).'; path=/; domain=.myfoodomain.com; secure; httponly', (string) $cookie, '->__toString() returns string representation of the cookie');
$this->assertEquals('foo=bar; expires=Fri, 20-May-2011 15:25:52 GMT; Max-Age=0; 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; max-age='.($expire - time()).'; path=/; domain=.myfoodomain.com; secure; httponly', (string) $cookie, '->__toString() encodes the value of the cookie according to RFC 3986 (white space = %20)');
$this->assertEquals('foo=bar%20with%20white%20spaces; expires=Fri, 20-May-2011 15:25:52 GMT; Max-Age=0; 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', $expire = time() - 31536001).'; max-age='.($expire - time()).'; path=/admin/; domain=.myfoodomain.com; httponly', (string) $cookie, '->__toString() returns string representation of a cleared cookie if value is NULL');
$this->assertEquals('foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', $expire = time() - 31536001).'; Max-Age=0; path=/admin/; domain=.myfoodomain.com; 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; path=/; httponly', (string) $cookie);
@ -194,7 +194,7 @@ class CookieTest extends TestCase
$this->assertEquals($expire - time(), $cookie->getMaxAge());
$cookie = new Cookie('foo', 'bar', $expire = time() - 100);
$this->assertEquals($expire - time(), $cookie->getMaxAge());
$this->assertEquals(0, $cookie->getMaxAge());
}
public function testFromString()

View File

@ -0,0 +1,39 @@
<?php
use Symfony\Component\HttpFoundation\Response;
$parent = __DIR__;
while (!@file_exists($parent.'/vendor/autoload.php')) {
if (!@file_exists($parent)) {
// open_basedir restriction in effect
break;
}
if ($parent === dirname($parent)) {
echo "vendor/autoload.php not found\n";
exit(1);
}
$parent = dirname($parent);
}
require $parent.'/vendor/autoload.php';
error_reporting(-1);
ini_set('html_errors', 0);
ini_set('display_errors', 1);
header_remove('X-Powered-By');
header('Content-Type: text/plain; charset=utf-8');
register_shutdown_function(function () {
echo "\n";
session_write_close();
print_r(headers_list());
echo "shutdown\n";
});
ob_start();
$r = new Response();
$r->headers->set('Date', 'Sat, 12 Nov 1955 20:04:00 GMT');
return $r;

View File

@ -0,0 +1,11 @@
Warning: Expiry date cannot have a year greater than 9999 in %scookie_max_age.php on line 10
Array
(
[0] => Content-Type: text/plain; charset=utf-8
[1] => Cache-Control: no-cache, private
[2] => Date: Sat, 12 Nov 1955 20:04:00 GMT
[3] => Set-Cookie: foo=bar; expires=Sat, 01-Jan-10000 02:46:40 GMT; Max-Age=%d; path=/
)
shutdown

View File

@ -0,0 +1,10 @@
<?php
use Symfony\Component\HttpFoundation\Cookie;
$r = require __DIR__.'/common.inc';
$r->headers->setCookie(new Cookie('foo', 'bar', 253402310800, '', null, false, false));
$r->sendHeaders();
setcookie('foo2', 'bar', 253402310800, '/');

View File

@ -0,0 +1,10 @@
Array
(
[0] => Content-Type: text/plain; charset=utf-8
[1] => Cache-Control: no-cache, private
[2] => Date: Sat, 12 Nov 1955 20:04:00 GMT
[3] => Set-Cookie: ?*():@&+$/%#[]=?*():@&+$/%#[]; path=/
[4] => Set-Cookie: ?*():@&+$/%#[]=?*():@&+$/%#[]; path=/
)
shutdown

View File

@ -0,0 +1,12 @@
<?php
use Symfony\Component\HttpFoundation\Cookie;
$r = require __DIR__.'/common.inc';
$str = '?*():@&+$/%#[]';
$r->headers->setCookie(new Cookie($str, $str, 0, '/', null, false, false, true));
$r->sendHeaders();
setrawcookie($str, $str, 0, '/', null, false, false);

View File

@ -0,0 +1,9 @@
Array
(
[0] => Content-Type: text/plain; charset=utf-8
[1] => Cache-Control: no-cache, private
[2] => Date: Sat, 12 Nov 1955 20:04:00 GMT
[3] => Set-Cookie: CookieSamesiteLaxTest=LaxValue; path=/; httponly; samesite=lax
)
shutdown

View File

@ -0,0 +1,8 @@
<?php
use Symfony\Component\HttpFoundation\Cookie;
$r = require __DIR__.'/common.inc';
$r->headers->setCookie(new Cookie('CookieSamesiteLaxTest', 'LaxValue', 0, '/', null, false, true, false, Cookie::SAMESITE_LAX));
$r->sendHeaders();

View File

@ -0,0 +1,9 @@
Array
(
[0] => Content-Type: text/plain; charset=utf-8
[1] => Cache-Control: no-cache, private
[2] => Date: Sat, 12 Nov 1955 20:04:00 GMT
[3] => Set-Cookie: CookieSamesiteStrictTest=StrictValue; path=/; httponly; samesite=strict
)
shutdown

View File

@ -0,0 +1,8 @@
<?php
use Symfony\Component\HttpFoundation\Cookie;
$r = require __DIR__.'/common.inc';
$r->headers->setCookie(new Cookie('CookieSamesiteStrictTest', 'StrictValue', 0, '/', null, false, true, false, Cookie::SAMESITE_STRICT));
$r->sendHeaders();

View File

@ -0,0 +1,10 @@
Array
(
[0] => Content-Type: text/plain; charset=utf-8
[1] => Cache-Control: no-cache, private
[2] => Date: Sat, 12 Nov 1955 20:04:00 GMT
[3] => Set-Cookie: %3F%2A%28%29%3A%40%26%2B%24%2F%25%23%5B%5D=%3F%2A%28%29%3A%40%26%2B%24%2F%25%23%5B%5D; path=/
[4] => Set-Cookie: ?*():@&+$/%#[]=%3F%2A%28%29%3A%40%26%2B%24%2F%25%23%5B%5D; path=/
)
shutdown

View File

@ -0,0 +1,12 @@
<?php
use Symfony\Component\HttpFoundation\Cookie;
$r = require __DIR__.'/common.inc';
$str = '?*():@&+$/%#[]';
$r->headers->setCookie(new Cookie($str, $str, 0, '', null, false, false));
$r->sendHeaders();
setcookie($str, $str, 0, '/');

View File

@ -0,0 +1,6 @@
The cookie name "Hello + world" contains invalid characters.
Array
(
[0] => Content-Type: text/plain; charset=utf-8
)
shutdown

View File

@ -0,0 +1,11 @@
<?php
use Symfony\Component\HttpFoundation\Cookie;
$r = require __DIR__.'/common.inc';
try {
$r->headers->setCookie(new Cookie('Hello + world', 'hodor'));
} catch (\InvalidArgumentException $e) {
echo $e->getMessage();
}

View File

@ -0,0 +1,58 @@
<?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\HttpFoundation\Tests;
use PHPUnit\Framework\TestCase;
/**
* @requires PHP 7.0
*/
class ResponseFunctionalTest extends TestCase
{
private static $server;
public static function setUpBeforeClass()
{
$spec = array(
1 => array('file', '/dev/null', 'w'),
2 => array('file', '/dev/null', 'w'),
);
if (!self::$server = @proc_open('exec php -S localhost:8054', $spec, $pipes, __DIR__.'/Fixtures/response-functional')) {
self::markTestSkipped('PHP server unable to start.');
}
sleep(1);
}
public static function tearDownAfterClass()
{
if (self::$server) {
proc_terminate(self::$server);
proc_close(self::$server);
}
}
/**
* @dataProvider provideCookie
*/
public function testCookie($fixture)
{
$result = file_get_contents(sprintf('http://localhost:8054/%s.php', $fixture));
$this->assertStringMatchesFormatFile(__DIR__.sprintf('/Fixtures/response-functional/%s.expected', $fixture), $result);
}
public function provideCookie()
{
foreach (glob(__DIR__.'/Fixtures/response-functional/*.php') as $file) {
yield array(pathinfo($file, PATHINFO_FILENAME));
}
}
}

View File

@ -116,7 +116,7 @@ class ResponseHeaderBagTest extends TestCase
$bag->clearCookie('foo');
$this->assertSetCookieHeader('foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; max-age=-31536001; path=/; httponly', $bag);
$this->assertSetCookieHeader('foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; Max-Age=0; path=/; httponly', $bag);
}
public function testClearCookieSecureNotHttpOnly()
@ -125,7 +125,7 @@ class ResponseHeaderBagTest extends TestCase
$bag->clearCookie('foo', '/', null, true, false);
$this->assertSetCookieHeader('foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; max-age=-31536001; path=/; secure', $bag);
$this->assertSetCookieHeader('foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; Max-Age=0; path=/; secure', $bag);
}
public function testReplace()

View File

@ -60,22 +60,17 @@ class ClientTest extends TestCase
$m = $r->getMethod('filterResponse');
$m->setAccessible(true);
$expected = array(
'foo=bar; expires=Sun, 15-Feb-2009 20:00:00 GMT; max-age='.(strtotime('Sun, 15-Feb-2009 20:00:00 GMT') - time()).'; path=/foo; domain=http://example.com; secure; httponly',
'foo1=bar1; expires=Sun, 15-Feb-2009 20:00:00 GMT; max-age='.(strtotime('Sun, 15-Feb-2009 20:00:00 GMT') - time()).'; path=/foo; domain=http://example.com; secure; httponly',
);
$response = new Response();
$response->headers->setCookie($cookie1 = new Cookie('foo', 'bar', \DateTime::createFromFormat('j-M-Y H:i:s T', '15-Feb-2009 20:00:00 GMT')->format('U'), '/foo', 'http://example.com', true, true));
$domResponse = $m->invoke($client, $response);
$this->assertSame((string) $cookie1, $domResponse->getHeader('Set-Cookie'));
$response = new Response();
$response->headers->setCookie(new Cookie('foo', 'bar', \DateTime::createFromFormat('j-M-Y H:i:s T', '15-Feb-2009 20:00:00 GMT')->format('U'), '/foo', 'http://example.com', true, true));
$response->headers->setCookie($cookie1 = new Cookie('foo', 'bar', \DateTime::createFromFormat('j-M-Y H:i:s T', '15-Feb-2009 20:00:00 GMT')->format('U'), '/foo', 'http://example.com', true, true));
$response->headers->setCookie($cookie2 = new Cookie('foo1', 'bar1', \DateTime::createFromFormat('j-M-Y H:i:s T', '15-Feb-2009 20:00:00 GMT')->format('U'), '/foo', 'http://example.com', true, true));
$domResponse = $m->invoke($client, $response);
$this->assertEquals($expected[0], $domResponse->getHeader('Set-Cookie'));
$response = new Response();
$response->headers->setCookie(new Cookie('foo', 'bar', \DateTime::createFromFormat('j-M-Y H:i:s T', '15-Feb-2009 20:00:00 GMT')->format('U'), '/foo', 'http://example.com', true, true));
$response->headers->setCookie(new Cookie('foo1', 'bar1', \DateTime::createFromFormat('j-M-Y H:i:s T', '15-Feb-2009 20:00:00 GMT')->format('U'), '/foo', 'http://example.com', true, true));
$domResponse = $m->invoke($client, $response);
$this->assertEquals($expected[0], $domResponse->getHeader('Set-Cookie'));
$this->assertEquals($expected, $domResponse->getHeader('Set-Cookie', false));
$this->assertSame((string) $cookie1, $domResponse->getHeader('Set-Cookie'));
$this->assertSame(array((string) $cookie1, (string) $cookie2), $domResponse->getHeader('Set-Cookie', false));
}
public function testFilterResponseSupportsStreamedResponses()