Skip to content

Commit 726cf51

Browse files
committed
test(laravel): rules on a collection #7280
1 parent 91b17f1 commit 726cf51

File tree

3 files changed

+95
-0
lines changed

3 files changed

+95
-0
lines changed

src/Laravel/Tests/ValidationTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,14 @@ public function testRouteWithRequirements(): void
7575
$response = $this->get('api/issue_7194_requirements/1', ['accept' => 'application/ld+json']);
7676
$response->assertStatus(200);
7777
}
78+
79+
public function testGetCollectionWithFormRequestValidation(): void
80+
{
81+
$response = $this->get('/api/slots/dropoff', ['accept' => 'application/ld+json']);
82+
$response->assertStatus(422);
83+
$response->assertJsonFragment(['violations' => [
84+
['propertyPath' => 'pickupDate', 'message' => 'The pickup date field is required.'],
85+
['propertyPath' => 'pickupSlotId', 'message' => 'The pickup slot id field is required.'],
86+
]]);
87+
}
7888
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Workbench\App\ApiResource;
6+
7+
use ApiPlatform\Metadata\ApiResource;
8+
use ApiPlatform\Metadata\GetCollection;
9+
use Workbench\App\Http\Requests\GetDropOffSlotsRequest;
10+
11+
#[ApiResource(
12+
operations: [
13+
new GetCollection(
14+
uriTemplate: '/slots/dropoff',
15+
rules: GetDropOffSlotsRequest::class,
16+
provider: [self::class, 'provide'],
17+
output: SlotsForDate::class,
18+
),
19+
],
20+
)]
21+
class SlotsForDate
22+
{
23+
public int $id = 1;
24+
public string $name = 'Morning Slot';
25+
public string $note = 'This is a morning slot';
26+
27+
public static function provide() {
28+
return [];
29+
}
30+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Workbench\App\Http\Requests;
6+
7+
use ApiPlatform\Laravel\State\ValidationErrorTrait;
8+
use Illuminate\Contracts\Validation\Validator;
9+
use Illuminate\Foundation\Http\FormRequest;
10+
11+
class GetDropOffSlotsRequest extends FormRequest
12+
{
13+
use ValidationErrorTrait;
14+
15+
public function authorize(): bool
16+
{
17+
return true;
18+
}
19+
20+
protected function prepareForValidation(): void
21+
{
22+
$this->merge([
23+
'pickupDate' => $this->query('pickupDate'),
24+
'pickupSlotId' => $this->query('pickupSlotId'),
25+
]);
26+
27+
}
28+
/**
29+
* Get the validation rules that apply to the request.
30+
*
31+
* @docs/guides/return-the-iri-of-your-resources-relations.php array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
32+
*/
33+
public function rules(): array
34+
{
35+
return [
36+
'pickupDate' => 'required|date|after_or_equal:today',
37+
'pickupSlotId' => 'required|string',
38+
];
39+
}
40+
41+
// to match api plaform validation response
42+
protected function failedValidation(Validator $validator): void
43+
{
44+
$violations = collect($validator->errors())
45+
->map(fn($m, $f) => ['propertyPath' => $f, 'message' => $m[0]]) //** @phpstan-ignore-line */
46+
->values()->all();
47+
48+
throw new \ApiPlatform\Laravel\ApiResource\ValidationError(
49+
$violations[0]['message'] ?? 'Validation failed.',
50+
hash('xxh3', implode(',', array_column($violations, 'propertyPath'))),
51+
new \Illuminate\Validation\ValidationException($validator),
52+
$violations
53+
);
54+
}
55+
}

0 commit comments

Comments
 (0)