Skip to content

Commit 0da2d18

Browse files
committed
minor #7334 Do not exclude AdminRouterSubscriberTest from test suite & rewrite un… (michaelKaefer)
This PR was merged into the 4.x branch. Discussion ---------- Do not exclude AdminRouterSubscriberTest from test suite & rewrite un… …used ExceptionListenerTest which would not work anymore & add a conflict to composer.json to fix method signature missmatch Note on the conflict in `composer.json`: the following method signature is not compatible with `symfony/error-handler` lower than `5.4.35` and throws a fatal error if a lower version is used: ```php final class FlattenException extends BaseFlattenException { public static function create(\Exception $exception, ?int $statusCode = null, array $headers = []): static ``` Commits ------- b8419d0 Do not exclude AdminRouterSubscriberTest from test suite & rewrite unused ExceptionListenerTest which would not work anymore & add a conflict to composer.json to fix method signature missmatch
2 parents f4ab2c8 + b8419d0 commit 0da2d18

File tree

3 files changed

+95
-54
lines changed

3 files changed

+95
-54
lines changed

composer.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@
5959
"symfony/web-link": "^5.4|^6.0|^7.0|^8.0",
6060
"vincentlanglet/twig-cs-fixer": "^3.10"
6161
},
62+
"conflict": {
63+
"symfony/error-handler": "<5.4.35"
64+
},
6265
"config": {
6366
"sort-packages": true,
6467
"allow-plugins": {

phpunit.xml.dist

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
<testsuite name="EasyAdmin Test Suite">
2020
<directory>tests/</directory>
2121
<exclude>tests/Controller/PrettyUrls/</exclude>
22-
<exclude>tests/EventListener/</exclude>
2322
<exclude>tests/Form/</exclude>
2423
</testsuite>
2524
</testsuites>

tests/EventListener/ExceptionListenerTest.php

Lines changed: 92 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,81 +2,120 @@
22

33
namespace EasyCorp\Bundle\EasyAdminBundle\Tests\EventListener;
44

5+
use EasyCorp\Bundle\EasyAdminBundle\Context\ExceptionContext;
6+
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Context\AdminContextInterface;
7+
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Provider\AdminContextProviderInterface;
58
use EasyCorp\Bundle\EasyAdminBundle\EventListener\ExceptionListener;
6-
use EasyCorp\Bundle\EasyAdminBundle\Exception\EntityNotFoundException as EasyEntityNotFoundException;
9+
use EasyCorp\Bundle\EasyAdminBundle\Exception\BaseException;
710
use PHPUnit\Framework\TestCase;
811
use Symfony\Component\HttpFoundation\Request;
9-
use Symfony\Component\HttpFoundation\Response;
12+
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
1013
use Symfony\Component\HttpKernel\HttpKernelInterface;
14+
use Twig\Environment;
15+
use Twig\Error\RuntimeError;
16+
use Twig\Loader\ArrayLoader;
1117

1218
class ExceptionListenerTest extends TestCase
1319
{
14-
private function getTwig()
20+
/**
21+
* @dataProvider unhandledException
22+
*/
23+
public function testUnhandledException(bool $kernelDebug, bool $contextIsNull, \Exception $exception): void
1524
{
16-
$twig = $this->getMockBuilder('\Twig_Environment')->disableOriginalConstructor()->getMock();
17-
$twig->method('render')->willReturn('template content');
25+
$contextProvider = $this->createMock(AdminContextProviderInterface::class);
26+
if (!$contextIsNull) {
27+
$context = $this->createMock(AdminContextInterface::class);
28+
$context->method('getTemplatePath')->willReturn('foo');
29+
$contextProvider->method('getContext')->willReturn($context);
30+
}
1831

19-
return $twig;
20-
}
32+
$listener = new ExceptionListener(
33+
$kernelDebug,
34+
$contextProvider,
35+
$this->createMock(Environment::class),
36+
);
2137

22-
private function getEventExceptionThatShouldBeCalledOnce($exception)
23-
{
24-
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent')
25-
->disableOriginalConstructor()
26-
->getMock();
27-
$event->method('getException')->willReturn($exception);
28-
$event->method('getRequest')->willReturn(new Request());
29-
$event->method('getKernel')->willReturn(new TestKernel());
30-
$event->expects($this->once())->method('setResponse');
31-
32-
return $event;
38+
$expectedMessage = $exception->getMessage();
39+
40+
$listener->onKernelException($exceptionEvent = $this->createExceptionEvent($exception));
41+
42+
$this->assertSame($expectedMessage, $exceptionEvent->getThrowable()->getMessage());
43+
$this->assertNull($exceptionEvent->getResponse());
3344
}
3445

35-
public function testCatchBaseExceptions(): void
46+
public static function unhandledException(): \Generator
3647
{
37-
$exception = new EasyEntityNotFoundException([
38-
'entity_name' => 'Test',
39-
'entity_id_name' => 'Test key',
40-
'entity_id_value' => 2,
41-
]);
42-
$event = $this->getEventExceptionThatShouldBeCalledOnce($exception);
43-
$twig = $this->getTwig();
44-
45-
$listener = new ExceptionListener($twig, []);
46-
$listener->onKernelException($event);
48+
yield [true, true, new \Exception()];
49+
yield [true, false, new \Exception()];
50+
yield [false, true, new \Exception()];
51+
yield [false, false, new \Exception()];
52+
yield [true, true, new RuntimeError('foo')];
53+
yield [true, false, new RuntimeError('foo')];
54+
yield [false, true, new RuntimeError('foo')];
55+
yield [false, false, new RuntimeError('foo')];
56+
yield [true, true, new class(new ExceptionContext('foo')) extends BaseException {}];
57+
yield [true, false, new class(new ExceptionContext('foo')) extends BaseException {}];
58+
yield [false, true, new class(new ExceptionContext('foo')) extends BaseException {}];
4759
}
4860

49-
private function getEventExceptionThatShouldNotBeCalled($exception)
61+
public function testAppendMessage(): void
5062
{
51-
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent')
52-
->disableOriginalConstructor()
53-
->getMock();
54-
$event->method('getException')->willReturn($exception);
55-
$event->method('getRequest')->willReturn(new Request());
56-
$event->expects($this->never())->method('setResponse');
57-
58-
return $event;
63+
$listener = new ExceptionListener(
64+
true,
65+
$this->createMock(AdminContextProviderInterface::class),
66+
$this->createMock(Environment::class),
67+
);
68+
69+
$exception = new RuntimeError('Variable "ea" does not exist.');
70+
$listener->onKernelException($exceptionEvent = $this->createExceptionEvent($exception));
71+
72+
$expectedMessage = <<<MESSAGE
73+
Variable "ea" does not exist.
74+
75+
The "ea" variable stores the admin context (menu items, actions, fields, etc.) and it's created automatically for requests served by EasyAdmin.
76+
77+
If you are seeing this error, you are trying to use some EasyAdmin features in a request not served by EasyAdmin. For example, some of your custom actions may be trying to render or extend from one of the templates provided EasyAdmin.
78+
79+
Your request must meet one of these conditions to be served by EasyAdmin (and to have the "ea" variable defined):
80+
81+
1) It must be run by a controller that implements DashboardControllerInterface. This is done automatically for all actions and CRUD controllers associated to your dashboard.
82+
83+
2) It must contain an "eaContext" query string parameter that identifies the Dashboard associated to this request (this parameter is automatically added by EasyAdmin when creating menu items that link to custom Symfony routes).
84+
MESSAGE;
85+
86+
$this->assertSame($expectedMessage, $exceptionEvent->getThrowable()->getMessage());
87+
$this->assertNull($exceptionEvent->getResponse());
5988
}
6089

61-
public function testShouldNotCatchExceptionsWithSameName(): void
90+
public function testResponse(): void
6291
{
63-
$exception = new EntityNotFoundException();
64-
$event = $this->getEventExceptionThatShouldNotBeCalled($exception);
65-
$twig = $this->getTwig();
92+
$contextProvider = $this->createMock(AdminContextProviderInterface::class);
93+
$context = $this->createMock(AdminContextInterface::class);
94+
$context->method('getTemplatePath')->willReturn('@EasyAdmin/exception.html.twig');
95+
$contextProvider->method('getContext')->willReturn($context);
96+
$listener = new ExceptionListener(
97+
false,
98+
$contextProvider,
99+
new Environment(new ArrayLoader(['@EasyAdmin/exception.html.twig' => '{{ exception.publicMessage }}'])),
100+
);
66101

67-
$listener = new ExceptionListener($twig, []);
68-
$listener->onKernelException($event);
69-
}
70-
}
102+
$exception = new class(new ExceptionContext('foo')) extends BaseException {};
71103

72-
class EntityNotFoundException extends \Exception
73-
{
74-
}
104+
$expectedStatusCode = $exception->getStatusCode();
75105

76-
class TestKernel implements HttpKernelInterface
77-
{
78-
public function handle(Request $request, int $type = self::MAIN_REQUEST, bool $catch = true): Response
106+
$listener->onKernelException($exceptionEvent = $this->createExceptionEvent($exception));
107+
108+
$this->assertSame($expectedStatusCode, $exceptionEvent->getResponse()->getStatusCode());
109+
$this->assertSame('foo', $exceptionEvent->getResponse()->getContent());
110+
}
111+
112+
private function createExceptionEvent(\Exception $exception): ExceptionEvent
79113
{
80-
return new Response('foo');
114+
return new ExceptionEvent(
115+
$this->createStub(HttpKernelInterface::class),
116+
Request::create('/'),
117+
HttpKernelInterface::MAIN_REQUEST,
118+
$exception,
119+
);
81120
}
82121
}

0 commit comments

Comments
 (0)