Skip to content

Commit f472b69

Browse files
fix: use PATCH instead of PUT
Fixes #493 This was due to `standard_put`, following HTTP specification in API Platform. PUT method was used for api-platform/admin compatibility, but now it supports PATCH: api-platform/admin#589
1 parent 09b9cbc commit f472b69

File tree

8 files changed

+43
-49
lines changed

8 files changed

+43
-49
lines changed

api/src/Entity/Book.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
use ApiPlatform\Metadata\Delete;
1414
use ApiPlatform\Metadata\Get;
1515
use ApiPlatform\Metadata\GetCollection;
16+
use ApiPlatform\Metadata\Patch;
1617
use ApiPlatform\Metadata\Post;
17-
use ApiPlatform\Metadata\Put;
1818
use ApiPlatform\Metadata\UrlGeneratorInterface;
1919
use App\Enum\BookCondition;
2020
use App\Repository\BookRepository;
@@ -54,8 +54,7 @@
5454
new Get(
5555
uriTemplate: '/admin/books/{id}{._format}'
5656
),
57-
// https://github.com/api-platform/admin/issues/370
58-
new Put(
57+
new Patch(
5958
uriTemplate: '/admin/books/{id}{._format}',
6059
processor: BookPersistProcessor::class
6160
),

api/src/Entity/Review.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
use ApiPlatform\Metadata\NotExposed;
1414
use ApiPlatform\Metadata\Patch;
1515
use ApiPlatform\Metadata\Post;
16-
use ApiPlatform\Metadata\Put;
1716
use ApiPlatform\Metadata\UrlGeneratorInterface;
1817
use ApiPlatform\State\CreateProvider;
18+
use ApiPlatform\State\SerializerContextBuilderInterface;
1919
use App\Repository\ReviewRepository;
2020
use App\Security\Voter\OidcTokenPermissionVoter;
2121
use App\Serializer\IriTransformerNormalizer;
@@ -54,8 +54,7 @@
5454
new Get(
5555
uriTemplate: '/admin/reviews/{id}{._format}'
5656
),
57-
// https://github.com/api-platform/admin/issues/370
58-
new Put(
57+
new Patch(
5958
uriTemplate: '/admin/reviews/{id}{._format}',
6059
processor: ReviewPersistProcessor::class
6160
),
@@ -74,6 +73,7 @@
7473
],
7574
denormalizationContext: [
7675
AbstractNormalizer::GROUPS => ['Review:write', 'Review:write:admin'],
76+
SerializerContextBuilderInterface::ASSIGN_OBJECT_TO_POPULATE => true,
7777
],
7878
collectDenormalizationErrors: true,
7979
security: 'is_granted("OIDC_ADMIN")',

api/src/State/Processor/ReviewPersistProcessor.php

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
use ApiPlatform\Doctrine\Common\State\PersistProcessor;
88
use ApiPlatform\Metadata\Operation;
99
use ApiPlatform\Metadata\Post;
10-
use ApiPlatform\Metadata\Put;
1110
use ApiPlatform\State\ProcessorInterface;
1211
use App\Entity\Review;
1312
use App\Security\Http\Protection\ResourceHandlerInterface;
@@ -44,13 +43,6 @@ public function process(mixed $data, Operation $operation, array $uriVariables =
4443
$data->publishedAt = $this->clock->now();
4544
}
4645

47-
// standard PUT
48-
// todo find why $data lost properties unauthorized from deserialization
49-
if ($operation instanceof Put && isset($context['previous_data'])) {
50-
$data->user = $context['previous_data']->user;
51-
$data->publishedAt = $context['previous_data']->publishedAt;
52-
}
53-
5446
// save entity
5547
$data = $this->persistProcessor->process($data, $operation, $uriVariables, $context);
5648

api/tests/Api/Admin/BookTest.php

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use App\Tests\Api\Security\TokenGenerator;
1616
use App\Tests\Api\Trait\SerializerTrait;
1717
use PHPUnit\Framework\Attributes\DataProvider;
18+
use PHPUnit\Framework\Attributes\Group;
1819
use PHPUnit\Framework\Attributes\Test;
1920
use Symfony\Component\HttpFoundation\Response;
2021
use Symfony\Component\Mercure\Update;
@@ -363,8 +364,8 @@ public static function getInvalidData(): iterable
363364
}
364365

365366
#[Test]
366-
#[\PHPUnit\Framework\Attributes\Group('apiCall')]
367-
#[\PHPUnit\Framework\Attributes\Group('mercure')]
367+
#[Group('apiCall')]
368+
#[Group('mercure')]
368369
public function asAdminUserICanCreateABook(): void
369370
{
370371
$token = self::getContainer()->get(TokenGenerator::class)->generateToken([
@@ -424,13 +425,13 @@ public function asNonAdminUserICannotUpdateBook(int $expectedCode, string $hydra
424425
$options['auth_bearer'] = $token;
425426
}
426427

427-
$this->client->request('PUT', '/admin/books/' . $book->getId(), $options + [
428+
$this->client->request('PATCH', '/admin/books/' . $book->getId(), $options + [
428429
'json' => [
429430
'book' => 'https://gutendex.com/books/31547.json',
430431
'condition' => BookCondition::NewCondition->value,
431432
],
432433
'headers' => [
433-
'Content-Type' => 'application/ld+json',
434+
'Content-Type' => 'application/merge-patch+json',
434435
'Accept' => 'application/ld+json',
435436
],
436437
]);
@@ -454,13 +455,13 @@ public function asAdminUserICannotUpdateAnInvalidBook(): void
454455
'email' => UserFactory::createOneAdmin()->email,
455456
]);
456457

457-
$this->client->request('PUT', '/admin/books/invalid', [
458+
$this->client->request('PATCH', '/admin/books/invalid', [
458459
'auth_bearer' => $token,
459460
'json' => [
460461
'condition' => BookCondition::DamagedCondition->value,
461462
],
462463
'headers' => [
463-
'Content-Type' => 'application/ld+json',
464+
'Content-Type' => 'application/merge-patch+json',
464465
'Accept' => 'application/ld+json',
465466
],
466467
]);
@@ -478,11 +479,11 @@ public function asAdminUserICannotUpdateABookWithInvalidData(array $data, int $s
478479
'email' => UserFactory::createOneAdmin()->email,
479480
]);
480481

481-
$this->client->request('PUT', '/admin/books/' . $book->getId(), [
482+
$this->client->request('PATCH', '/admin/books/' . $book->getId(), [
482483
'auth_bearer' => $token,
483484
'json' => $data,
484485
'headers' => [
485-
'Content-Type' => 'application/ld+json',
486+
'Content-Type' => 'application/merge-patch+json',
486487
'Accept' => 'application/ld+json',
487488
],
488489
]);
@@ -494,29 +495,27 @@ public function asAdminUserICannotUpdateABookWithInvalidData(array $data, int $s
494495
}
495496

496497
#[Test]
497-
#[\PHPUnit\Framework\Attributes\Group('apiCall')]
498-
#[\PHPUnit\Framework\Attributes\Group('mercure')]
498+
#[Group('apiCall')]
499+
#[Group('mercure')]
499500
public function asAdminUserICanUpdateABook(): void
500501
{
501502
$book = BookFactory::createOne([
502503
'book' => 'https://gutendex.com/books/31547.json',
504+
'condition' => BookCondition::UsedCondition,
503505
]);
504506
self::getMercureHub()->reset();
505507

506508
$token = self::getContainer()->get(TokenGenerator::class)->generateToken([
507509
'email' => UserFactory::createOneAdmin()->email,
508510
]);
509511

510-
$response = $this->client->request('PUT', '/admin/books/' . $book->getId(), [
512+
$response = $this->client->request('PATCH', '/admin/books/' . $book->getId(), [
511513
'auth_bearer' => $token,
512514
'json' => [
513-
'@id' => '/books/' . $book->getId(),
514-
// Must set all data because of standard PUT
515-
'book' => 'https://gutendex.com/books/31547.json',
516515
'condition' => BookCondition::DamagedCondition->value,
517516
],
518517
'headers' => [
519-
'Content-Type' => 'application/ld+json',
518+
'Content-Type' => 'application/merge-patch+json',
520519
'Accept' => 'application/ld+json',
521520
],
522521
]);
@@ -586,7 +585,7 @@ public function asAdminUserICannotDeleteAnInvalidBook(): void
586585
}
587586

588587
#[Test]
589-
#[\PHPUnit\Framework\Attributes\Group('mercure')]
588+
#[Group('mercure')]
590589
public function asAdminUserICanDeleteABook(): void
591590
{
592591
$book = BookFactory::createOne(['title' => 'Hyperion']);

api/tests/Api/Admin/ReviewTest.php

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use App\Tests\Api\Security\TokenGenerator;
1717
use App\Tests\Api\Trait\SerializerTrait;
1818
use PHPUnit\Framework\Attributes\DataProvider;
19+
use PHPUnit\Framework\Attributes\Group;
1920
use PHPUnit\Framework\Attributes\Test;
2021
use Symfony\Component\HttpFoundation\Response;
2122
use Symfony\Component\Mercure\Update;
@@ -240,14 +241,14 @@ public function asAdminUserICannotUpdateAnInvalidReview(): void
240241
'email' => UserFactory::createOneAdmin()->email,
241242
]);
242243

243-
$this->client->request('PUT', '/admin/reviews/invalid', [
244+
$this->client->request('PATCH', '/admin/reviews/invalid', [
244245
'auth_bearer' => $token,
245246
'json' => [
246247
'body' => 'Very good book!',
247248
'rating' => 5,
248249
],
249250
'headers' => [
250-
'Content-Type' => 'application/ld+json',
251+
'Content-Type' => 'application/merge-patch+json',
251252
'Accept' => 'application/ld+json',
252253
],
253254
]);
@@ -256,29 +257,30 @@ public function asAdminUserICannotUpdateAnInvalidReview(): void
256257
}
257258

258259
#[Test]
259-
#[\PHPUnit\Framework\Attributes\Group('mercure')]
260+
#[Group('mercure')]
260261
public function asAdminUserICanUpdateAReview(): void
261262
{
262263
$book = BookFactory::createOne();
263-
$review = ReviewFactory::createOne(['book' => $book]);
264+
$review = ReviewFactory::createOne([
265+
'book' => $book,
266+
'body' => "Yeah, it's ok...",
267+
'rating' => 3,
268+
]);
264269
$user = UserFactory::createOneAdmin();
265270
self::getMercureHub()->reset();
266271

267272
$token = self::getContainer()->get(TokenGenerator::class)->generateToken([
268273
'email' => $user->email,
269274
]);
270275

271-
$response = $this->client->request('PUT', '/admin/reviews/' . $review->getId(), [
276+
$response = $this->client->request('PATCH', '/admin/reviews/' . $review->getId(), [
272277
'auth_bearer' => $token,
273278
'json' => [
274-
// Must set all data because of standard PUT
275-
'book' => '/admin/books/' . $book->getId(),
276-
'letter' => null,
277279
'body' => 'Very good book!',
278280
'rating' => 5,
279281
],
280282
'headers' => [
281-
'Content-Type' => 'application/ld+json',
283+
'Content-Type' => 'application/merge-patch+json',
282284
'Accept' => 'application/ld+json',
283285
],
284286
]);
@@ -351,7 +353,7 @@ public function asAdminUserICannotDeleteAnInvalidReview(): void
351353
}
352354

353355
#[Test]
354-
#[\PHPUnit\Framework\Attributes\Group('mercure')]
356+
#[Group('mercure')]
355357
public function asAdminUserICanDeleteAReview(): void
356358
{
357359
$review = ReviewFactory::createOne(['body' => 'Best book ever!']);

api/tests/Api/BookmarkTest.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use App\Repository\BookmarkRepository;
1414
use App\Tests\Api\Security\TokenGenerator;
1515
use App\Tests\Api\Trait\SerializerTrait;
16+
use PHPUnit\Framework\Attributes\Group;
1617
use PHPUnit\Framework\Attributes\Test;
1718
use Symfony\Component\HttpFoundation\Response;
1819
use Symfony\Component\Mercure\Update;
@@ -140,7 +141,7 @@ public function asAUserICannotCreateABookmarkWithInvalidData(): void
140141
}
141142

142143
#[Test]
143-
#[\PHPUnit\Framework\Attributes\Group('mercure')]
144+
#[Group('mercure')]
144145
public function asAUserICanCreateABookmark(): void
145146
{
146147
$book = BookFactory::createOne(['book' => 'https://openlibrary.org/books/OL2055137M.json']);
@@ -277,7 +278,7 @@ public function asAUserICannotDeleteAnInvalidBookmark(): void
277278
}
278279

279280
#[Test]
280-
#[\PHPUnit\Framework\Attributes\Group('mercure')]
281+
#[Group('mercure')]
281282
public function asAUserICanDeleteMyBookmark(): void
282283
{
283284
$book = BookFactory::createOne(['title' => 'Hyperion']);

api/tests/Api/ReviewTest.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use App\Tests\Api\Security\TokenGenerator;
1717
use App\Tests\Api\Trait\SerializerTrait;
1818
use PHPUnit\Framework\Attributes\DataProvider;
19+
use PHPUnit\Framework\Attributes\Group;
1920
use PHPUnit\Framework\Attributes\Test;
2021
use Symfony\Component\HttpFoundation\Response;
2122
use Symfony\Component\Mercure\Update;
@@ -238,7 +239,7 @@ public function asAUserICannotAddAReviewWithValidDataOnAnInvalidBook(): void
238239
}
239240

240241
#[Test]
241-
#[\PHPUnit\Framework\Attributes\Group('mercure')]
242+
#[Group('mercure')]
242243
public function asAUserICanAddAReviewOnABook(): void
243244
{
244245
$book = BookFactory::createOne();
@@ -443,7 +444,7 @@ public function asAUserICannotUpdateAnInvalidBookReview(): void
443444
}
444445

445446
#[Test]
446-
#[\PHPUnit\Framework\Attributes\Group('mercure')]
447+
#[Group('mercure')]
447448
public function asAUserICanUpdateMyBookReview(): void
448449
{
449450
$review = ReviewFactory::createOne();
@@ -544,7 +545,7 @@ public function asAUserICannotDeleteAnInvalidBookReview(): void
544545
}
545546

546547
#[Test]
547-
#[\PHPUnit\Framework\Attributes\Group('mercure')]
548+
#[Group('mercure')]
548549
public function asAUserICanDeleteMyBookReview(): void
549550
{
550551
$review = ReviewFactory::createOne(['body' => 'Best book ever!']);

compose.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ services:
33
image: ${IMAGES_PREFIX:-}app-php
44
depends_on:
55
database:
6-
condition: service_healthy
6+
condition: service_started
77
pwa:
8-
condition: service_healthy
8+
condition: service_started
99
keycloak:
10-
condition: service_healthy
10+
condition: service_started
1111
restart: unless-stopped
1212
environment:
1313
PWA_UPSTREAM: pwa:3000
@@ -124,7 +124,7 @@ services:
124124
retries: 15
125125
depends_on:
126126
keycloak-database:
127-
condition: service_healthy
127+
condition: service_started
128128
ports:
129129
- target: 8080
130130
published: 8080

0 commit comments

Comments
 (0)