cerbero90 /
json-api-error
| 1 | <?php |
||||
| 2 | |||||
| 3 | declare(strict_types=1); |
||||
| 4 | |||||
| 5 | namespace Cerbero\JsonApiError\Services; |
||||
| 6 | |||||
| 7 | use Cerbero\JsonApiError\Data\Dot; |
||||
| 8 | use Closure; |
||||
| 9 | use Illuminate\Testing\Assert; |
||||
| 10 | use Illuminate\Testing\TestResponse; |
||||
| 11 | use Symfony\Component\HttpFoundation\Response; |
||||
| 12 | |||||
| 13 | /** |
||||
| 14 | * The mixin to test JSON:API error responses. |
||||
| 15 | */ |
||||
| 16 | final class TestResponseMixin |
||||
| 17 | { |
||||
| 18 | /** |
||||
| 19 | * Assert that the response contains the given JSON:API error. |
||||
| 20 | * |
||||
| 21 | * @return Closure(string, int): TestResponse |
||||
| 22 | */ |
||||
| 23 | 12 | public function assertJsonApiError(): Closure |
|||
| 24 | { |
||||
| 25 | 12 | return function (string $detail, int $status = Response::HTTP_BAD_REQUEST) { |
|||
| 26 | /** |
||||
| 27 | * @var TestResponse $this |
||||
| 28 | */ |
||||
| 29 | 1 | return $this // @phpstan-ignore-line |
|||
| 30 | 1 | ->assertJsonApiErrorStructure() |
|||
| 31 | 1 | ->assertJsonPath('errors.0.status', (string) $status) |
|||
| 32 | 1 | ->assertJsonPath('errors.0.title', __("json-api-error::statuses.{$status}.title")) |
|||
| 33 | 1 | ->assertJsonPath('errors.0.detail', $detail); |
|||
| 34 | 12 | }; |
|||
| 35 | } |
||||
| 36 | |||||
| 37 | /** |
||||
| 38 | * Assert that the response contains the given JSON:API validation errors. |
||||
| 39 | * |
||||
| 40 | * @return Closure(array<string|int, string>): TestResponse |
||||
| 41 | */ |
||||
| 42 | 12 | public function assertJsonApiValidation(): Closure |
|||
| 43 | { |
||||
| 44 | 12 | return function (array $expected) { |
|||
| 45 | /** |
||||
| 46 | * @var TestResponse $this |
||||
| 47 | */ |
||||
| 48 | 1 | $this // @phpstan-ignore-line |
|||
| 49 | 1 | ->assertJsonApiErrorStructure() |
|||
| 50 | 1 | ->assertJsonPath('errors', fn(array $errors) => collect($errors)->every(function (array $error) { |
|||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
| 51 | 1 | return $error['status'] === '422' && $error['title'] === __('json-api-error::statuses.422.title'); |
|||
| 52 | 1 | })); |
|||
| 53 | |||||
| 54 | 1 | if (array_is_list($expected)) { |
|||
|
0 ignored issues
–
show
The function
array_is_list was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 55 | 1 | Assert::assertEqualsCanonicalizing($expected, $this->json('errors.*.detail')); |
|||
| 56 | |||||
| 57 | 1 | return $this; |
|||
| 58 | } |
||||
| 59 | |||||
| 60 | 1 | $actual = $this->collect('errors')->pluck('detail', 'source.pointer')->all(); |
|||
| 61 | |||||
| 62 | 1 | foreach ($expected as $dot => $detail) { |
|||
| 63 | 1 | $pointer = (new Dot($dot))->toJsonPointer(); |
|||
| 64 | 1 | $message = "The field [{$dot}] does not have the error [{$detail}]."; |
|||
| 65 | |||||
| 66 | 1 | Assert::assertSame($detail, $actual[$pointer] ?? null, $message); |
|||
| 67 | |||||
| 68 | 1 | unset($actual[$pointer]); |
|||
| 69 | } |
||||
| 70 | |||||
| 71 | 1 | Assert::assertEmpty($actual, 'Other unexpected validation errors occurred.'); |
|||
| 72 | |||||
| 73 | 1 | return $this; |
|||
| 74 | 12 | }; |
|||
| 75 | } |
||||
| 76 | |||||
| 77 | /** |
||||
| 78 | * Assert that the response contains the JSON:API error for the given HTTP status. |
||||
| 79 | * |
||||
| 80 | * @return Closure(int): TestResponse |
||||
| 81 | */ |
||||
| 82 | 12 | public function assertJsonApiErrorStatus(): Closure |
|||
| 83 | { |
||||
| 84 | 12 | return function (int $status) { |
|||
| 85 | /** |
||||
| 86 | * @var TestResponse $this |
||||
| 87 | */ |
||||
| 88 | 7 | return $this // @phpstan-ignore-line |
|||
| 89 | 7 | ->assertJsonApiErrorStructure() |
|||
| 90 | 7 | ->assertJsonPath('errors.0.status', (string) $status) |
|||
| 91 | 7 | ->assertJsonPath('errors.0.title', __("json-api-error::statuses.{$status}.title")) |
|||
| 92 | 7 | ->assertJsonPath('errors.0.detail', __("json-api-error::statuses.{$status}.detail")); |
|||
| 93 | 12 | }; |
|||
| 94 | } |
||||
| 95 | |||||
| 96 | /** |
||||
| 97 | * Assert that the response contains JSON:API compliant errors. |
||||
| 98 | * |
||||
| 99 | * @return Closure(): TestResponse |
||||
| 100 | */ |
||||
| 101 | 12 | public function assertJsonApiErrorStructure(): Closure |
|||
| 102 | { |
||||
| 103 | 12 | return function () { |
|||
| 104 | /** |
||||
| 105 | * @var TestResponse $this |
||||
| 106 | */ |
||||
| 107 | 9 | return $this->assertJsonStructure([ |
|||
| 108 | 9 | 'errors' => [ |
|||
| 109 | 9 | '*' => [ |
|||
| 110 | 9 | 'status', |
|||
| 111 | 9 | 'title', |
|||
| 112 | 9 | 'detail', |
|||
| 113 | 9 | ], |
|||
| 114 | 9 | ], |
|||
| 115 | 9 | ]); |
|||
| 116 | 12 | }; |
|||
| 117 | } |
||||
| 118 | } |
||||
| 119 |