Skip to content

Commit 90ede6a

Browse files
committed
fix(mock-server): handle 404 and return codes for get endpoints
1 parent 6cd2b9c commit 90ede6a

3 files changed

Lines changed: 51 additions & 14 deletions

File tree

data/openapi.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,16 @@ paths:
4141
example:
4242
id: 1
4343
name: Alice
44+
/disabled-resource:
45+
get:
46+
summary: Disabled GET endpoint (API Platform pattern)
47+
responses:
48+
'404':
49+
description: Resource not available via GET
50+
content:
51+
application/json:
52+
schema:
53+
$ref: '#/components/schemas/Error'
4454
/users/{id}/tasks:
4555
post:
4656
summary: Create a task for a user (async)
@@ -100,3 +110,12 @@ components:
100110
type: string
101111
status:
102112
type: string
113+
Error:
114+
type: object
115+
properties:
116+
type:
117+
type: string
118+
title:
119+
type: string
120+
status:
121+
type: integer

src/Middleware/MockMiddleware/Request/RequestHandler.php

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public function handleValidRequest(
4747
return $this->responseFaker->mock(
4848
$openApi,
4949
$operationAddress,
50-
$statusCode ?? $this->getSuccessStatusCodes($openApi, $operationAddress),
50+
$statusCode ?? $this->getDefinedStatusCodes($openApi, $operationAddress),
5151
$acceptedContentTypes,
5252
$exampleName
5353
);
@@ -146,12 +146,14 @@ public function handleValidationFailedRequest(
146146
}
147147

148148
/**
149-
* Extract all 2xx status codes defined in the spec for the given operation,
150-
* sorted ascending. Falls back to ['200', '201'] if none are found.
149+
* Extract status codes defined in the spec for the given operation.
150+
*
151+
* Priority: 2xx codes first (sorted), then all other defined codes (sorted),
152+
* then 'default'. Falls back to ['200', '201'] only if the spec defines no responses at all.
151153
*
152154
* @return list<string>
153155
*/
154-
private function getSuccessStatusCodes(OpenApi $openApi, OperationAddress $operationAddress): array
156+
private function getDefinedStatusCodes(OpenApi $openApi, OperationAddress $operationAddress): array
155157
{
156158
try {
157159
$operation = (new SpecFinder($openApi))
@@ -164,25 +166,34 @@ private function getSuccessStatusCodes(OpenApi $openApi, OperationAddress $opera
164166
return ['200', '201'];
165167
}
166168

167-
$codes = [];
169+
$successCodes = [];
170+
$otherCodes = [];
171+
$hasDefault = false;
172+
168173
foreach (array_keys($operation->responses->getResponses()) as $code) {
169174
$code = (string) $code;
175+
176+
if ($code === 'default') {
177+
$hasDefault = true;
178+
continue;
179+
}
180+
170181
if (preg_match('/^2\d{2}$/', $code) === 1) {
171-
$codes[] = $code;
182+
$successCodes[] = $code;
183+
} else {
184+
$otherCodes[] = $code;
172185
}
173186
}
174187

175-
sort($codes);
188+
sort($successCodes);
189+
sort($otherCodes);
176190

177-
if ($codes === []) {
178-
// No 2xx codes defined, check for 'default' response
179-
if ($operation->responses->hasResponse('default')) {
180-
return ['default'];
181-
}
191+
$codes = [...$successCodes, ...$otherCodes];
182192

183-
return ['200', '201'];
193+
if ($hasDefault) {
194+
$codes[] = 'default';
184195
}
185196

186-
return $codes;
197+
return $codes !== [] ? $codes : ['200', '201'];
187198
}
188199
}

tests/Acceptance/MockServerCest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ public function testDeleteReturns204NoContent(AcceptanceTester $acceptanceTester
6565
$acceptanceTester->seeResponseCodeIs(204);
6666
}
6767

68+
public function testGetReturns404WhenOnlyDefinedStatusCode(AcceptanceTester $acceptanceTester): void
69+
{
70+
$acceptanceTester->sendGet('/disabled-resource');
71+
$acceptanceTester->seeResponseCodeIs(404);
72+
$acceptanceTester->seeResponseIsJson();
73+
}
74+
6875
public function testDisableMockViaHeader(AcceptanceTester $acceptanceTester): void
6976
{
7077
// If we explicitly set it to false, it should fall through to Mezzio's root handler

0 commit comments

Comments
 (0)