Skip to content

Commit b21b611

Browse files
paulundbastien-phi
authored andcommitted
Add regex pattern match against the requested url path (#1)
* Add regex pattern match against the requested url path * Update title of yaml
1 parent 4f4ab7f commit b21b611

File tree

3 files changed

+90
-3
lines changed

3 files changed

+90
-3
lines changed

src/Middleware.php

+10-3
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public function handle(Request $request, Closure $next): mixed
4646
try {
4747
/** @var \Illuminate\Routing\Route $route */
4848
$route = $request->route();
49-
[$specPath, $pathItem] = $this->pathItem($route, $request->method());
49+
[$specPath, $pathItem] = $this->pathItem($route, $request->method(), $request->path());
5050
} catch (InvalidPathException|MalformedSpecException|MissingSpecException|TypeErrorException|UnresolvableReferenceException $exception) {
5151
$this->spectator->captureRequestValidation($exception);
5252
$this->spectator->captureResponseValidation($exception);
@@ -117,7 +117,7 @@ protected function validate(Request $request, Closure $next, string $specPath, P
117117
* @throws IOException
118118
* @throws InvalidJsonPointerSyntaxException
119119
*/
120-
protected function pathItem(Route $route, string $requestMethod): array
120+
protected function pathItem(Route $route, string $requestMethod, string $requestUrlPath): array
121121
{
122122
$requestPath = Str::start($route->uri(), '/');
123123

@@ -142,7 +142,14 @@ protected function pathItem(Route $route, string $requestMethod): array
142142

143143
if (Str::match($route->getCompiled()->getRegex(), $resolvedPath) !== '') {
144144
$pathMatches = true;
145-
if (in_array(strtolower($requestMethod), $methods, true)) {
145+
$requestUrlPath = '/'.ltrim($requestUrlPath, '/');
146+
$regExPattern = preg_replace('/\{[^}]+\}/', '.+', $resolvedPath);
147+
$regExPattern = str_replace('/', '\/', $regExPattern);
148+
149+
$matchedMethod = in_array(strtolower($requestMethod), $methods, true);
150+
$matchRequestUrl = preg_match('/^'.$regExPattern.'$/', $requestUrlPath) !== 0;
151+
152+
if ($matchedMethod && $matchRequestUrl) {
146153
$partialMatch = [$resolvedPath, $pathItem];
147154
}
148155
}

tests/Fixtures/Test.v3.yaml

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
openapi: 3.0.0
2+
info:
3+
title: Test.v3
4+
version: '1.0'
5+
servers:
6+
- url: 'http://localhost:3000'
7+
paths:
8+
/cars/electric:
9+
patch:
10+
summary: Update car charging status
11+
tags: []
12+
requestBody:
13+
content:
14+
application/json:
15+
schema:
16+
type: object
17+
required:
18+
- charging
19+
properties:
20+
charging:
21+
type: boolean
22+
description: Update charging status
23+
example: true
24+
responses:
25+
'200':
26+
description: OK
27+
content:
28+
application/json:
29+
schema:
30+
type: object
31+
properties:
32+
name:
33+
type: string
34+
35+
/cars/ice:
36+
patch:
37+
summary: Update car refilling status
38+
tags: []
39+
requestBody:
40+
content:
41+
application/json:
42+
schema:
43+
type: object
44+
required:
45+
- refill
46+
properties:
47+
refill:
48+
type: boolean
49+
description: Update refill status
50+
example: true
51+
responses:
52+
'200':
53+
description: OK
54+
content:
55+
application/json:
56+
schema:
57+
type: object
58+
properties:
59+
name:
60+
type: string
61+
62+
components:
63+
schemas: {}

tests/RequestValidatorTest.php

+17
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,23 @@ public function test_parameter_decoupling(): void
903903
$this->getJson('/users/1')
904904
->assertValidRequest();
905905
}
906+
907+
public function test_static_url_parameter_decoupling(): void
908+
{
909+
Spectator::using('Test.v3.yaml');
910+
911+
Route::patch('/cars/{name}', function ($name) {
912+
return [
913+
'name' => $name,
914+
];
915+
})->middleware([SubstituteBindings::class, Middleware::class]);
916+
917+
$this->patchJson('/cars/electric', ['charging' => true])
918+
->assertValidRequest();
919+
920+
$this->patchJson('/cars/ice', ['refill' => true])
921+
->assertValidRequest();
922+
}
906923
}
907924

908925
class TestUser extends Model

0 commit comments

Comments
 (0)