-
-
Notifications
You must be signed in to change notification settings - Fork 962
Expand file tree
/
Copy pathDateTimeNormalizerPriorityTest.php
More file actions
95 lines (80 loc) · 3.45 KB
/
DateTimeNormalizerPriorityTest.php
File metadata and controls
95 lines (80 loc) · 3.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
<?php
/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <dunglas@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace ApiPlatform\Tests\Functional;
use ApiPlatform\Test\ApiTestCase;
use ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\DateTimeNormalizationIssue;
use ApiPlatform\Tests\SetupClassResourcesTrait;
/**
* Tests that ItemNormalizer does not intercept DateTimeImmutable objects
* before Symfony's DateTimeNormalizer when context leaks through custom normalizers.
*
* Reproduces and validates the fix for issue #7733:
* https://github.com/api-platform/core/issues/7733
*
* The issue occurs when a custom normalizer delegates DateTimeImmutable
* normalization to the serializer with a context containing force_resource_class,
* causing ItemNormalizer to incorrectly intercept it.
*/
final class DateTimeNormalizerPriorityTest extends ApiTestCase
{
use SetupClassResourcesTrait;
protected static ?bool $alwaysBootKernel = false;
/**
* @return class-string[]
*/
public static function getResources(): array
{
return [DateTimeNormalizationIssue::class];
}
/**
* Test that DateTimeImmutable is properly serialized to a string
* in the API response.
*/
public function testDateTimeImmutableIsNormalizedAsString(): void
{
$response = self::createClient()->request('GET', '/datetime_normalization_issues/1');
$this->assertResponseIsSuccessful();
$data = $response->toArray();
$this->assertSame(1, $data['id']);
$this->assertSame('Test Resource', $data['name']);
$this->assertArrayHasKey('updatedAt', $data);
$this->assertIsString($data['updatedAt']);
$this->assertStringContainsString('2024-01-15', $data['updatedAt']);
}
/**
* Tests that ItemNormalizer::supportsNormalization returns false for DateTimeImmutable
* even when force_resource_class leaks through context from a parent resource normalization.
*
* This directly reproduces the bug in issue #7733 where a custom normalizer delegates
* DateTimeImmutable normalization to the serializer with a context containing
* force_resource_class, causing ItemNormalizer to incorrectly claim it can handle
* the DateTimeImmutable object and then fail with:
*
* LogicException: Can't get a way to read the property "id" in class "DateTimeImmutable".
*/
public function testDateTimeImmutableIsNotInterceptedByItemNormalizer(): void
{
self::bootKernel();
$serializer = self::getContainer()->get('serializer');
// Simulate a custom normalizer that delegates DateTimeImmutable normalization
// with a context that still contains force_resource_class from the parent resource
$dateTime = new \DateTimeImmutable('2024-01-15T10:30:00+00:00');
// Before the fix, this would throw a LogicException about the "id" property
// After the fix, DateTimeNormalizer handles it correctly
$result = $serializer->normalize($dateTime, 'jsonld', [
'force_resource_class' => DateTimeNormalizationIssue::class,
]);
// DateTimeNormalizer should handle this, producing a string
// ItemNormalizer must NOT intercept it
$this->assertIsString($result);
$this->assertStringContainsString('2024-01-15', $result);
}
}