| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 | <?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\Debug\Tests\Exception;use PHPUnit\Framework\TestCase;use Symfony\Component\Debug\Exception\FlattenException;use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException;use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;use Symfony\Component\HttpKernel\Exception\ConflictHttpException;use Symfony\Component\HttpKernel\Exception\GoneHttpException;use Symfony\Component\HttpKernel\Exception\LengthRequiredHttpException;use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException;use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;use Symfony\Component\HttpKernel\Exception\PreconditionFailedHttpException;use Symfony\Component\HttpKernel\Exception\PreconditionRequiredHttpException;use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException;class FlattenExceptionTest extends TestCase{    public function testStatusCode()    {        $flattened = FlattenException::create(new \RuntimeException(), 403);        $this->assertEquals('403', $flattened->getStatusCode());        $flattened = FlattenException::create(new \RuntimeException());        $this->assertEquals('500', $flattened->getStatusCode());        $flattened = FlattenException::create(new NotFoundHttpException());        $this->assertEquals('404', $flattened->getStatusCode());        $flattened = FlattenException::create(new UnauthorizedHttpException('Basic realm="My Realm"'));        $this->assertEquals('401', $flattened->getStatusCode());        $flattened = FlattenException::create(new BadRequestHttpException());        $this->assertEquals('400', $flattened->getStatusCode());        $flattened = FlattenException::create(new NotAcceptableHttpException());        $this->assertEquals('406', $flattened->getStatusCode());        $flattened = FlattenException::create(new ConflictHttpException());        $this->assertEquals('409', $flattened->getStatusCode());        $flattened = FlattenException::create(new MethodNotAllowedHttpException(['POST']));        $this->assertEquals('405', $flattened->getStatusCode());        $flattened = FlattenException::create(new AccessDeniedHttpException());        $this->assertEquals('403', $flattened->getStatusCode());        $flattened = FlattenException::create(new GoneHttpException());        $this->assertEquals('410', $flattened->getStatusCode());        $flattened = FlattenException::create(new LengthRequiredHttpException());        $this->assertEquals('411', $flattened->getStatusCode());        $flattened = FlattenException::create(new PreconditionFailedHttpException());        $this->assertEquals('412', $flattened->getStatusCode());        $flattened = FlattenException::create(new PreconditionRequiredHttpException());        $this->assertEquals('428', $flattened->getStatusCode());        $flattened = FlattenException::create(new ServiceUnavailableHttpException());        $this->assertEquals('503', $flattened->getStatusCode());        $flattened = FlattenException::create(new TooManyRequestsHttpException());        $this->assertEquals('429', $flattened->getStatusCode());        $flattened = FlattenException::create(new UnsupportedMediaTypeHttpException());        $this->assertEquals('415', $flattened->getStatusCode());        if (class_exists(SuspiciousOperationException::class)) {            $flattened = FlattenException::create(new SuspiciousOperationException());            $this->assertEquals('400', $flattened->getStatusCode());        }    }    public function testHeadersForHttpException()    {        $flattened = FlattenException::create(new MethodNotAllowedHttpException(['POST']));        $this->assertEquals(['Allow' => 'POST'], $flattened->getHeaders());        $flattened = FlattenException::create(new UnauthorizedHttpException('Basic realm="My Realm"'));        $this->assertEquals(['WWW-Authenticate' => 'Basic realm="My Realm"'], $flattened->getHeaders());        $flattened = FlattenException::create(new ServiceUnavailableHttpException('Fri, 31 Dec 1999 23:59:59 GMT'));        $this->assertEquals(['Retry-After' => 'Fri, 31 Dec 1999 23:59:59 GMT'], $flattened->getHeaders());        $flattened = FlattenException::create(new ServiceUnavailableHttpException(120));        $this->assertEquals(['Retry-After' => 120], $flattened->getHeaders());        $flattened = FlattenException::create(new TooManyRequestsHttpException('Fri, 31 Dec 1999 23:59:59 GMT'));        $this->assertEquals(['Retry-After' => 'Fri, 31 Dec 1999 23:59:59 GMT'], $flattened->getHeaders());        $flattened = FlattenException::create(new TooManyRequestsHttpException(120));        $this->assertEquals(['Retry-After' => 120], $flattened->getHeaders());    }    /**     * @dataProvider flattenDataProvider     */    public function testFlattenHttpException(\Exception $exception)    {        $flattened = FlattenException::create($exception);        $flattened2 = FlattenException::create($exception);        $flattened->setPrevious($flattened2);        $this->assertEquals($exception->getMessage(), $flattened->getMessage(), 'The message is copied from the original exception.');        $this->assertEquals($exception->getCode(), $flattened->getCode(), 'The code is copied from the original exception.');        $this->assertInstanceOf($flattened->getClass(), $exception, 'The class is set to the class of the original exception');    }    /**     * @dataProvider flattenDataProvider     */    public function testPrevious(\Exception $exception)    {        $flattened = FlattenException::create($exception);        $flattened2 = FlattenException::create($exception);        $flattened->setPrevious($flattened2);        $this->assertSame($flattened2, $flattened->getPrevious());        $this->assertSame([$flattened2], $flattened->getAllPrevious());    }    /**     * @requires PHP 7.0     */    public function testPreviousError()    {        $exception = new \Exception('test', 123, new \ParseError('Oh noes!', 42));        $flattened = FlattenException::create($exception)->getPrevious();        $this->assertEquals($flattened->getMessage(), 'Parse error: Oh noes!', 'The message is copied from the original exception.');        $this->assertEquals($flattened->getCode(), 42, 'The code is copied from the original exception.');        $this->assertEquals($flattened->getClass(), 'Symfony\Component\Debug\Exception\FatalThrowableError', 'The class is set to the class of the original exception');    }    /**     * @dataProvider flattenDataProvider     */    public function testLine(\Exception $exception)    {        $flattened = FlattenException::create($exception);        $this->assertSame($exception->getLine(), $flattened->getLine());    }    /**     * @dataProvider flattenDataProvider     */    public function testFile(\Exception $exception)    {        $flattened = FlattenException::create($exception);        $this->assertSame($exception->getFile(), $flattened->getFile());    }    /**     * @dataProvider flattenDataProvider     */    public function testToArray(\Exception $exception)    {        $flattened = FlattenException::create($exception);        $flattened->setTrace([], 'foo.php', 123);        $this->assertEquals([            [                'message' => 'test',                'class' => 'Exception',                'trace' => [[                    'namespace' => '', 'short_class' => '', 'class' => '', 'type' => '', 'function' => '', 'file' => 'foo.php', 'line' => 123,                    'args' => [],                ]],            ],        ], $flattened->toArray());    }    public function flattenDataProvider()    {        return [            [new \Exception('test', 123)],        ];    }    public function testArguments()    {        $dh = opendir(__DIR__);        $fh = tmpfile();        $incomplete = unserialize('O:14:"BogusTestClass":0:{}');        $exception = $this->createException([            (object) ['foo' => 1],            new NotFoundHttpException(),            $incomplete,            $dh,            $fh,            function () {},            [1, 2],            ['foo' => 123],            null,            true,            false,            0,            0.0,            '0',            '',            INF,            NAN,        ]);        $flattened = FlattenException::create($exception);        $trace = $flattened->getTrace();        $args = $trace[1]['args'];        $array = $args[0][1];        closedir($dh);        fclose($fh);        $i = 0;        $this->assertSame(['object', 'stdClass'], $array[$i++]);        $this->assertSame(['object', 'Symfony\Component\HttpKernel\Exception\NotFoundHttpException'], $array[$i++]);        $this->assertSame(['incomplete-object', 'BogusTestClass'], $array[$i++]);        $this->assertSame(['resource', \defined('HHVM_VERSION') ? 'Directory' : 'stream'], $array[$i++]);        $this->assertSame(['resource', 'stream'], $array[$i++]);        $args = $array[$i++];        $this->assertSame($args[0], 'object');        $this->assertTrue('Closure' === $args[1] || is_subclass_of($args[1], '\Closure'), 'Expect object class name to be Closure or a subclass of Closure.');        $this->assertSame(['array', [['integer', 1], ['integer', 2]]], $array[$i++]);        $this->assertSame(['array', ['foo' => ['integer', 123]]], $array[$i++]);        $this->assertSame(['null', null], $array[$i++]);        $this->assertSame(['boolean', true], $array[$i++]);        $this->assertSame(['boolean', false], $array[$i++]);        $this->assertSame(['integer', 0], $array[$i++]);        $this->assertSame(['float', 0.0], $array[$i++]);        $this->assertSame(['string', '0'], $array[$i++]);        $this->assertSame(['string', ''], $array[$i++]);        $this->assertSame(['float', INF], $array[$i++]);        // assertEquals() does not like NAN values.        $this->assertEquals($array[$i][0], 'float');        $this->assertNan($array[$i][1]);    }    public function testRecursionInArguments()    {        $a = null;        $a = ['foo', [2, &$a]];        $exception = $this->createException($a);        $flattened = FlattenException::create($exception);        $trace = $flattened->getTrace();        $this->assertStringContainsString('*DEEP NESTED ARRAY*', serialize($trace));    }    public function testTooBigArray()    {        $a = [];        for ($i = 0; $i < 20; ++$i) {            for ($j = 0; $j < 50; ++$j) {                for ($k = 0; $k < 10; ++$k) {                    $a[$i][$j][$k] = 'value';                }            }        }        $a[20] = 'value';        $a[21] = 'value1';        $exception = $this->createException($a);        $flattened = FlattenException::create($exception);        $trace = $flattened->getTrace();        $this->assertSame($trace[1]['args'][0], ['array', ['array', '*SKIPPED over 10000 entries*']]);        $serializeTrace = serialize($trace);        $this->assertStringContainsString('*SKIPPED over 10000 entries*', $serializeTrace);        $this->assertStringNotContainsString('*value1*', $serializeTrace);    }    private function createException($foo)    {        return new \Exception();    }}
 |