55namespace PhproTest \ApiProblemBundle \EventListener ;
66
77use Exception ;
8+
89use function json_encode ;
10+
911use Phpro \ApiProblem \ApiProblemInterface ;
1012use Phpro \ApiProblem \DebuggableApiProblemInterface ;
1113use Phpro \ApiProblem \Http \HttpApiProblem ;
1921use Symfony \Component \HttpFoundation \Request ;
2022use Symfony \Component \HttpKernel \Event \ExceptionEvent ;
2123use Symfony \Component \HttpKernel \HttpKernelInterface ;
22- use Throwable ;
2324
2425/** @covers \Phpro\ApiProblemBundle\EventListener\JsonApiProblemExceptionListener */
2526class JsonApiProblemExceptionListenerTest extends TestCase
2627{
2728 use ProphecyTrait;
2829
29- /**
30- * @var ObjectProphecy|Request
31- */
32- private $ request ;
33-
34- /**
35- * @var ExceptionEvent
36- */
37- private $ event ;
38-
39- /**
40- * @var Throwable
41- */
42- private $ exception ;
43-
4430 /**
4531 * @var ExceptionTransformerInterface|ObjectProphecy
4632 */
4733 private $ exceptionTransformer ;
4834
4935 protected function setUp (): void
5036 {
51- $ this ->request = $ this ->prophesize (Request::class);
52- $ httpKernel = $ this ->prophesize (HttpKernelInterface::class);
53- $ this ->exception = new Exception ('error ' );
54- $ this ->event = new ExceptionEvent (
55- $ httpKernel ->reveal (),
56- $ this ->request ->reveal (),
57- HttpKernelInterface::MASTER_REQUEST ,
58- $ this ->exception
59- );
6037 $ this ->exceptionTransformer = $ this ->prophesize (ExceptionTransformerInterface::class);
6138 $ this ->exceptionTransformer ->accepts (Argument::any ())->willReturn (false );
6239 }
@@ -65,89 +42,116 @@ protected function setUp(): void
6542 public function it_does_nothing_on_non_json_requests (): void
6643 {
6744 $ listener = new JsonApiProblemExceptionListener ($ this ->exceptionTransformer ->reveal (), false );
68- $ this ->request ->getPreferredFormat ()->willReturn ('html ' );
69- $ this ->request ->getContentType ()->willReturn ('text/html ' );
70- $ listener ->onKernelException ($ this ->event );
7145
72- $ this ->assertNull ($ this ->event ->getResponse ());
46+ $ request = new Request ();
47+ $ request ->headers ->set ('Accept ' , 'text/html ' );
48+ $ request ->headers ->set ('Content-Type ' , 'text/html ' );
49+
50+ $ event = $ this ->buildEvent ($ request );
51+ $ listener ->onKernelException ($ event );
52+
53+ $ this ->assertNull ($ event ->getResponse ());
7354 }
7455
7556 /** @test */
7657 public function it_runs_on_json_route_formats (): void
7758 {
7859 $ listener = new JsonApiProblemExceptionListener ($ this ->exceptionTransformer ->reveal (), false );
79- $ this ->request ->getPreferredFormat ()->willReturn ('json ' );
80- $ this ->request ->getContentType ()->willReturn (null );
81- $ listener ->onKernelException ($ this ->event );
8260
83- $ this ->assertApiProblemWithResponseBody (500 , $ this ->parseDataForException ());
61+ $ request = new Request ();
62+ $ request ->headers ->set ('Accept ' , 'application/json ' );
63+ $ request ->headers ->remove ('Content-Type ' );
64+ $ exception = new Exception ('error ' );
65+ $ event = $ this ->buildEvent ($ request , $ exception );
66+
67+ $ listener ->onKernelException ($ event );
68+
69+ $ this ->assertApiProblemWithResponseBody ($ event , 500 , $ this ->parseDataForException ($ exception ));
8470 }
8571
8672 /** @test */
8773 public function it_runs_on_json_content_types (): void
8874 {
8975 $ listener = new JsonApiProblemExceptionListener ($ this ->exceptionTransformer ->reveal (), false );
90- $ this ->request ->getPreferredFormat ()->willReturn ('html ' );
91- $ this ->request ->getContentType ()->willReturn ('application/json ' );
9276
93- $ listener ->onKernelException ($ this ->event );
94- $ this ->assertApiProblemWithResponseBody (500 , $ this ->parseDataForException ());
77+ $ request = new Request ();
78+ $ request ->headers ->set ('Accept ' , 'text/html ' );
79+ $ request ->headers ->set ('Content-Type ' , 'application/json ' );
80+ $ exception = new Exception ('error ' );
81+ $ event = $ this ->buildEvent ($ request , $ exception );
82+
83+ $ listener ->onKernelException ($ event );
84+ $ this ->assertApiProblemWithResponseBody ($ event , 500 , $ this ->parseDataForException ($ exception ));
9585 }
9686
9787 /** @test */
9888 public function it_runs_on_json_accept_header (): void
9989 {
10090 $ listener = new JsonApiProblemExceptionListener ($ this ->exceptionTransformer ->reveal (), false );
101- $ this ->request ->getPreferredFormat ()->willReturn ('json ' );
102- $ this ->request ->getContentType ()->willReturn ('html ' );
10391
104- $ listener ->onKernelException ($ this ->event );
105- $ this ->assertApiProblemWithResponseBody (500 , $ this ->parseDataForException ());
92+ $ request = new Request ();
93+ $ request ->headers ->set ('Accept ' , 'application/json ' );
94+ $ request ->headers ->set ('Content-Type ' , 'text/html ' );
95+ $ exception = new Exception ('error ' );
96+ $ event = $ this ->buildEvent ($ request , $ exception );
97+
98+ $ listener ->onKernelException ($ event );
99+ $ this ->assertApiProblemWithResponseBody ($ event , 500 , $ this ->parseDataForException ($ exception ));
106100 }
107101
108102 /** @test */
109103 public function it_parses_an_api_problem_response (): void
110104 {
111105 $ listener = new JsonApiProblemExceptionListener ($ this ->exceptionTransformer ->reveal (), false );
112- $ this ->request ->getPreferredFormat ()->willReturn ('json ' );
113- $ this ->request ->getContentType ()->willReturn ('application/json ' );
114106
115- $ listener ->onKernelException ($ this ->event );
116- $ this ->assertApiProblemWithResponseBody (500 , $ this ->parseDataForException ());
107+ $ request = new Request ();
108+ $ request ->headers ->set ('Accept ' , 'application/json ' );
109+ $ request ->headers ->set ('Content-Type ' , 'application/json ' );
110+ $ exception = new Exception ('error ' );
111+ $ event = $ this ->buildEvent ($ request , $ exception );
112+
113+ $ listener ->onKernelException ($ event );
114+ $ this ->assertApiProblemWithResponseBody ($ event , 500 , $ this ->parseDataForException ($ exception ));
117115 }
118116
119117 /** @test */
120118 public function it_uses_an_exception_transformer (): void
121119 {
122120 $ listener = new JsonApiProblemExceptionListener ($ this ->exceptionTransformer ->reveal (), false );
123- $ this ->request ->getPreferredFormat ()->willReturn ('json ' );
124- $ this ->request ->getContentType ()->willReturn ('application/json ' );
121+
122+ $ request = new Request ();
123+ $ request ->headers ->set ('Accept ' , 'application/json ' );
124+ $ request ->headers ->set ('Content-Type ' , 'text/html ' );
125+ $ event = $ this ->buildEvent ($ request );
125126
126127 $ apiProblem = $ this ->prophesize (ApiProblemInterface::class);
127128 $ apiProblem ->toArray ()->willReturn ([]);
128129
129130 $ this ->exceptionTransformer ->accepts (Argument::type (Exception::class))->willReturn (true );
130131 $ this ->exceptionTransformer ->transform (Argument::type (Exception::class))->willReturn ($ apiProblem ->reveal ());
131132
132- $ listener ->onKernelException ($ this -> event );
133- $ this ->assertApiProblemWithResponseBody (400 , []);
133+ $ listener ->onKernelException ($ event );
134+ $ this ->assertApiProblemWithResponseBody ($ event , 400 , []);
134135 }
135136
136137 /** @test */
137138 public function it_returns_the_status_code_from_the_api_problem (): void
138139 {
139140 $ listener = new JsonApiProblemExceptionListener ($ this ->exceptionTransformer ->reveal (), false );
140- $ this ->request ->getPreferredFormat ()->willReturn ('json ' );
141- $ this ->request ->getContentType ()->willReturn ('application/json ' );
141+
142+ $ request = new Request ();
143+ $ request ->headers ->set ('Accept ' , 'application/json ' );
144+ $ request ->headers ->set ('Content-Type ' , 'text/html ' );
145+ $ event = $ this ->buildEvent ($ request );
142146
143147 $ apiProblem = $ this ->prophesize (ApiProblemInterface::class);
144148 $ apiProblem ->toArray ()->willReturn (['status ' => 123 ]);
145149
146150 $ this ->exceptionTransformer ->accepts (Argument::type (Exception::class))->willReturn (true );
147151 $ this ->exceptionTransformer ->transform (Argument::type (Exception::class))->willReturn ($ apiProblem ->reveal ());
148152
149- $ listener ->onKernelException ($ this -> event );
150- $ this ->assertApiProblemWithResponseBody (123 , ['status ' => 123 ]);
153+ $ listener ->onKernelException ($ event );
154+ $ this ->assertApiProblemWithResponseBody ($ event , 123 , ['status ' => 123 ]);
151155 }
152156
153157 /** @test */
@@ -160,35 +164,52 @@ public function it_parses_a_debuggable_api_problem_response(): void
160164 $ apiProblem ->toDebuggableArray ()->willReturn ($ data );
161165 $ apiProblem ->toArray ()->willReturn ($ data );
162166
163- $ this ->exceptionTransformer ->accepts ($ this ->exception )->willReturn (true );
164- $ this ->exceptionTransformer ->transform ($ this ->exception )->willReturn ($ apiProblem ->reveal ());
167+ $ exception = new Exception ('error ' );
168+ $ this ->exceptionTransformer ->accepts ($ exception )->willReturn (true );
169+ $ this ->exceptionTransformer ->transform ($ exception )->willReturn ($ apiProblem ->reveal ());
165170
166- $ this ->request ->getPreferredFormat ()->willReturn ('json ' );
167- $ this ->request ->getContentType ()->willReturn ('application/json ' );
171+ $ request = new Request ();
172+ $ request ->headers ->set ('Accept ' , 'application/json ' );
173+ $ request ->headers ->set ('Content-Type ' , 'text/html ' );
174+ $ event = $ this ->buildEvent ($ request , $ exception );
168175
169- $ listener ->onKernelException ($ this -> event );
170- $ this ->assertApiProblemWithResponseBody (500 , $ data );
176+ $ listener ->onKernelException ($ event );
177+ $ this ->assertApiProblemWithResponseBody ($ event , 500 , $ data );
171178 }
172179
173- private function assertApiProblemWithResponseBody (int $ expectedResponseCode , array $ expectedData ): void
180+ private function assertApiProblemWithResponseBody (ExceptionEvent $ event , int $ expectedResponseCode , array $ expectedData ): void
174181 {
175- $ response = $ this -> event ->getResponse ();
182+ $ response = $ event ->getResponse ();
176183 $ this ->assertInstanceOf (JsonResponse::class, $ response );
177184 $ this ->assertSame ($ expectedResponseCode , $ response ->getStatusCode ());
178185 $ this ->assertSame ('application/problem+json ' , $ response ->headers ->get ('Content-Type ' ));
179186 $ this ->assertJsonStringEqualsJsonString (
180187 json_encode ($ expectedData ),
181- $ this -> event ->getResponse ()->getContent ()
188+ $ event ->getResponse ()->getContent ()
182189 );
183190 }
184191
185- private function parseDataForException (): array
192+ private function parseDataForException (Exception $ exception ): array
186193 {
187194 return [
188195 'status ' => 500 ,
189196 'type ' => HttpApiProblem::TYPE_HTTP_RFC ,
190197 'title ' => HttpApiProblem::getTitleForStatusCode (500 ),
191- 'detail ' => $ this -> exception ->getMessage (),
198+ 'detail ' => $ exception ->getMessage (),
192199 ];
193200 }
201+
202+ private function buildEvent (Request $ request , Exception $ exception = null ): ExceptionEvent
203+ {
204+ $ exception ??= new Exception ('error ' );
205+
206+ $ httpKernel = $ this ->prophesize (HttpKernelInterface::class);
207+
208+ return new ExceptionEvent (
209+ $ httpKernel ->reveal (),
210+ $ request ,
211+ HttpKernelInterface::MASTER_REQUEST ,
212+ $ exception
213+ );
214+ }
194215}
0 commit comments