Skip to content

Commit e85bed4

Browse files
authored
Always validate complete response
1 parent a897dbf commit e85bed4

1 file changed

Lines changed: 60 additions & 33 deletions

File tree

test/EventListener/JsonApiProblemExceptionListenerTest.php

Lines changed: 60 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,15 @@ class JsonApiProblemExceptionListenerTest extends TestCase
2626
private $request;
2727

2828
/**
29-
* @var GetResponseForExceptionEvent|ObjectProphecy
29+
* @var ExceptionEvent
3030
*/
3131
private $event;
3232

33+
/**
34+
* @var \Throwable
35+
*/
36+
private $exception;
37+
3338
/**
3439
* @var ExceptionTransformerInterface|ObjectProphecy
3540
*/
@@ -39,8 +44,13 @@ protected function setUp(): void
3944
{
4045
$this->request = $this->prophesize(Request::class);
4146
$httpKernel = $this->prophesize(HttpKernelInterface::class);
42-
$exception = new \Exception('error');
43-
$this->event = new ExceptionEvent($httpKernel->reveal(), $this->request->reveal(), HttpKernelInterface::MASTER_REQUEST, $exception);
47+
$this->exception = new \Exception('error');
48+
$this->event = new ExceptionEvent(
49+
$httpKernel->reveal(),
50+
$this->request->reveal(),
51+
HttpKernelInterface::MASTER_REQUEST,
52+
$this->exception
53+
);
4454
$this->exceptionTransformer = $this->prophesize(ExceptionTransformerInterface::class);
4555
$this->exceptionTransformer->accepts(Argument::any())->willReturn(false);
4656
}
@@ -64,13 +74,7 @@ public function it_runs_on_json_route_formats(): void
6474
$this->request->getContentType()->willReturn(null);
6575
$listener->onKernelException($this->event);
6676

67-
$this->assertNotNull($this->event->getResponse());
68-
$this->assertEquals([
69-
'status' => 500,
70-
'type' => 'http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html',
71-
'title' => 'Internal Server Error',
72-
'detail' => 'error',
73-
], json_decode($this->event->getResponse()->getContent(), true));
77+
$this->assertApiProblemWithResponseBody(500, $this->parseDataForException());
7478
}
7579

7680
/** @test */
@@ -79,14 +83,9 @@ public function it_runs_on_json_content_types(): void
7983
$listener = new JsonApiProblemExceptionListener($this->exceptionTransformer->reveal(), false);
8084
$this->request->getRequestFormat()->willReturn('html');
8185
$this->request->getContentType()->willReturn('application/json');
86+
8287
$listener->onKernelException($this->event);
83-
$this->assertNotNull($this->event->getResponse());
84-
$this->assertEquals([
85-
'status' => 500,
86-
'type' => 'http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html',
87-
'title' => 'Internal Server Error',
88-
'detail' => 'error',
89-
], json_decode($this->event->getResponse()->getContent(), true));
88+
$this->assertApiProblemWithResponseBody(500, $this->parseDataForException());
9089
}
9190

9291
/** @test */
@@ -97,15 +96,7 @@ public function it_parses_an_api_problem_response(): void
9796
$this->request->getContentType()->willReturn('application/json');
9897

9998
$listener->onKernelException($this->event);
100-
$this->assertJsonStringEqualsJsonString(
101-
json_encode([
102-
'status' => 500,
103-
'type' => HttpApiProblem::TYPE_HTTP_RFC,
104-
'title' => HttpApiProblem::getTitleForStatusCode(500),
105-
'detail' => 'error',
106-
]),
107-
$this->event->getResponse()->getContent()
108-
);
99+
$this->assertApiProblemWithResponseBody(500, $this->parseDataForException());
109100
}
110101

111102
/** @test */
@@ -122,7 +113,24 @@ public function it_uses_an_exception_transformer(): void
122113
$this->exceptionTransformer->transform(Argument::type(\Exception::class))->willReturn($apiProblem->reveal());
123114

124115
$listener->onKernelException($this->event);
125-
$this->assertInstanceOf(JsonResponse::class, $this->event->getResponse());
116+
$this->assertApiProblemWithResponseBody(400, []);
117+
}
118+
119+
/** @test */
120+
public function it_returns_the_status_code_from_the_api_problem(): void
121+
{
122+
$listener = new JsonApiProblemExceptionListener($this->exceptionTransformer->reveal(), false);
123+
$this->request->getRequestFormat()->willReturn('json');
124+
$this->request->getContentType()->willReturn('application/json');
125+
126+
$apiProblem = $this->prophesize(ApiProblemInterface::class);
127+
$apiProblem->toArray()->willReturn(['status' => 123]);
128+
129+
$this->exceptionTransformer->accepts(Argument::type(\Exception::class))->willReturn(true);
130+
$this->exceptionTransformer->transform(Argument::type(\Exception::class))->willReturn($apiProblem->reveal());
131+
132+
$listener->onKernelException($this->event);
133+
$this->assertApiProblemWithResponseBody(123, ['status' => 123]);
126134
}
127135

128136
/** @test */
@@ -134,17 +142,36 @@ public function it_parses_a_debuggable_api_problem_response(): void
134142
$data = ['status' => 500, 'detail' => 'detail', 'debug' => true];
135143
$apiProblem->toDebuggableArray()->willReturn($data);
136144
$apiProblem->toArray()->willReturn($data);
137-
$exception = new \RuntimeException();
138145

139-
$this->exceptionTransformer->accepts($exception)->willReturn(true);
140-
$this->exceptionTransformer->transform($exception)->willReturn($apiProblem->reveal());
146+
$this->exceptionTransformer->accepts($this->exception)->willReturn(true);
147+
$this->exceptionTransformer->transform($this->exception)->willReturn($apiProblem->reveal());
141148

142149
$this->request->getRequestFormat()->willReturn('json');
143150
$this->request->getContentType()->willReturn('application/json');
144151

145-
$this->event->setResponse(new JsonResponse($data, 500, ['Content-Type' => 'application/problem+json']));
146-
147152
$listener->onKernelException($this->event);
148-
$this->assertStringContainsString('JsonApiProblemExceptionListenerTest', $this->event->getResponse()->getContent());
153+
$this->assertApiProblemWithResponseBody(500, $data);
154+
}
155+
156+
private function assertApiProblemWithResponseBody(int $expectedResponseCode, array $expectedData): void
157+
{
158+
$response = $this->event->getResponse();
159+
$this->assertInstanceOf(JsonResponse::class, $response);
160+
$this->assertSame($expectedResponseCode, $response->getStatusCode());
161+
$this->assertSame('application/problem+json', $response->headers->get('Content-Type'));
162+
$this->assertJsonStringEqualsJsonString(
163+
\json_encode($expectedData),
164+
$this->event->getResponse()->getContent()
165+
);
166+
}
167+
168+
private function parseDataForException(): array
169+
{
170+
return [
171+
'status' => 500,
172+
'type' => HttpApiProblem::TYPE_HTTP_RFC,
173+
'title' => HttpApiProblem::getTitleForStatusCode(500),
174+
'detail' => $this->exception->getMessage(),
175+
];
149176
}
150177
}

0 commit comments

Comments
 (0)