diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index ed6dcb9d..45acea1f 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -5785,16 +5785,6 @@ parameters: count: 1 path: tests/lib/Output/FieldTypeSerializerTest.php - - - message: "#^Method Ibexa\\\\Tests\\\\Rest\\\\Output\\\\Generator\\\\FieldTypeHashGeneratorBaseTest\\:\\:assertSerializationSame\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/lib/Output/Generator/FieldTypeHashGeneratorBaseTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Rest\\\\Output\\\\Generator\\\\FieldTypeHashGeneratorBaseTest\\:\\:assertSerializationSame\\(\\) has parameter \\$functionName with no type specified\\.$#" - count: 1 - path: tests/lib/Output/Generator/FieldTypeHashGeneratorBaseTest.php - - message: "#^Method Ibexa\\\\Tests\\\\Rest\\\\Output\\\\Generator\\\\FieldTypeHashGeneratorBaseTest\\:\\:getFieldTypeHashGenerator\\(\\) has no return type specified\\.$#" count: 1 diff --git a/src/contracts/Output/VisitorAdapterNormalizer.php b/src/contracts/Output/VisitorAdapterNormalizer.php index aeaa7678..56e1dd0f 100644 --- a/src/contracts/Output/VisitorAdapterNormalizer.php +++ b/src/contracts/Output/VisitorAdapterNormalizer.php @@ -77,7 +77,7 @@ public function supportsNormalization(mixed $data, ?string $format = null, array return $this->normalizer->supportsNormalization( $data, - null, + $format, $context + [self::CALLED_CONTEXT => true], ); } diff --git a/src/lib/Output/Generator/Data/ArrayList.php b/src/lib/Output/Generator/Data/ArrayList.php index d92ec548..7bd988d6 100644 --- a/src/lib/Output/Generator/Data/ArrayList.php +++ b/src/lib/Output/Generator/Data/ArrayList.php @@ -19,12 +19,10 @@ public function __construct( ) { $this->name = $name; $this->parent = $parent; + parent::__construct(); } - /** - * @return object - */ public function getParent(): object { return $this->parent; diff --git a/src/lib/Output/Generator/InMemory/Xml.php b/src/lib/Output/Generator/InMemory/Xml.php index d2004e67..aca372c2 100644 --- a/src/lib/Output/Generator/InMemory/Xml.php +++ b/src/lib/Output/Generator/InMemory/Xml.php @@ -9,7 +9,6 @@ namespace Ibexa\Rest\Output\Generator\InMemory; use Ibexa\Rest\Output\Generator\Data; -use Ibexa\Rest\Output\Generator\Data\ArrayList; use Ibexa\Rest\Output\Generator\Json; use Ibexa\Rest\Output\Normalizer\ArrayListNormalizer; use Ibexa\Rest\Output\Normalizer\ArrayObjectNormalizer; @@ -22,6 +21,7 @@ class Xml extends Json { public const string OUTER_ELEMENT = 'outer_element'; + #[\Override] public function getMediaType($name): string { return $this->generateMediaTypeWithVendor($name, 'xml', $this->vendor); @@ -31,12 +31,16 @@ public function getMediaType($name): string public function startList($name): void { $this->checkStartList($name); + + $this->isEmpty = false; + $array = new Data\ArrayList($name, $this->json); $this->json->$name = $array; $this->json = $array; } + #[\Override] public function startAttribute($name, $value): void { $this->checkStartAttribute($name); @@ -44,11 +48,13 @@ public function startAttribute($name, $value): void $this->json->{'@' . $name} = $value; } + #[\Override] public function serializeBool($boolValue): string { return $boolValue ? 'true' : 'false'; } + #[\Override] public function startValueElement(string $name, $value, array $attributes = []): void { $this->checkStartValueElement($name); @@ -64,13 +70,14 @@ public function startValueElement(string $name, $value, array $attributes = []): $jsonValue->{'#'} = $value; } - if ($this->json instanceof Json\ArrayObject || $this->json instanceof ArrayList) { + if ($this->json instanceof Json\ArrayObject || $this->json instanceof Data\ArrayList) { $this->json->append($jsonValue); } else { $this->json->$name = $jsonValue; } } + #[\Override] public function endDocument(mixed $data): string { parent::endDocument($data); @@ -96,6 +103,7 @@ public function endDocument(mixed $data): string return $serializer->serialize($data, 'xml', $encoderContext); } + #[\Override] public function getEncoderContext(array $data): array { return [ diff --git a/tests/integration/Serializer/SerializerTest.php b/tests/integration/Serializer/SerializerTest.php index 5433e70f..4d6aa8b4 100644 --- a/tests/integration/Serializer/SerializerTest.php +++ b/tests/integration/Serializer/SerializerTest.php @@ -46,7 +46,6 @@ public function testSerializeTestDataObject(): void $expectedData = [ 'string' => 'some_string', 'int' => 1, - 'innerObject' => null, 'location' => null, ]; @@ -60,11 +59,10 @@ public function testNormalizeTestDataObjectWithApiLocation(): void $dataObject = new TestDataObject( 'some_string', 1, - null, $this->locationService->loadLocation(2), ); - $normalizedData = $this->serializer->normalize($dataObject); + $normalizedData = $this->serializer->normalize($dataObject, 'json'); self::assertSame( 'application/vnd.ibexa.api.Location+json', @@ -83,19 +81,34 @@ public function testNormalizeTestDataObjectWithApiLocation(): void ); } - public function testSerializeTestDataObjectWithApiLocation(): void + public function testSerializeTestDataObjectWithApiLocationXml(): void { $dataObject = new TestDataObject( 'some_string', 1, - null, $this->locationService->loadLocation(2), ); $serializedData = $this->serializer->serialize($dataObject, 'xml'); - self::assertResponseMatchesXmlSnapshot( - $serializedData, - self::SNAPSHOT_DIR . '/TestDataObject.xml', + $expectedXml = new \DOMDocument(); + $expectedXml->preserveWhiteSpace = false; + $expectedXml->formatOutput = true; + $expectedXml->load(self::SNAPSHOT_DIR . '/TestDataObject.xml'); + + $actualXml = new \DOMDocument(); + $actualXml->preserveWhiteSpace = false; + $actualXml->formatOutput = true; + $actualXml->loadXML($serializedData); + + self::assertSame($expectedXml->saveXML(), $actualXml->saveXML()); + } + + public function testSerializeTestDataObjectWithApiLocationJson(): void + { + $dataObject = new TestDataObject( + 'some_string', + 1, + $this->locationService->loadLocation(2), ); $serializedData = $this->serializer->serialize($dataObject, 'json'); diff --git a/tests/integration/Serializer/TestDataObject.php b/tests/integration/Serializer/TestDataObject.php index 04b6e3e1..88e30cc3 100644 --- a/tests/integration/Serializer/TestDataObject.php +++ b/tests/integration/Serializer/TestDataObject.php @@ -15,7 +15,6 @@ public function __construct( public string $string, public int $int, - public ?self $innerObject = null, public ?Location $apiLocation = null, ) { } diff --git a/tests/integration/Serializer/TestDataObjectNormalizer.php b/tests/integration/Serializer/TestDataObjectNormalizer.php index 23000ffc..892ddd38 100644 --- a/tests/integration/Serializer/TestDataObjectNormalizer.php +++ b/tests/integration/Serializer/TestDataObjectNormalizer.php @@ -24,19 +24,18 @@ public function normalize(mixed $object, ?string $format = null, array $context { assert($object instanceof TestDataObject); - $scalarData = [ + $data = [ 'string' => $object->string, 'int' => $object->int, - 'innerObject' => $object->innerObject, 'location' => null, ]; if ($object->apiLocation instanceof Location) { - $normalizedLocation = $this->normalizer->normalize($object->apiLocation); - $scalarData['location'] = $normalizedLocation['Location'] ?? null; + $normalizedLocation = $this->normalizer->normalize($object->apiLocation, $format); + $data['location'] = $normalizedLocation['#'] ?? $normalizedLocation['Location'] ?? null; } - return $scalarData; + return $data; } public function supportsNormalization(mixed $data, ?string $format = null): bool diff --git a/tests/integration/Serializer/_snapshot/TestDataObject.json b/tests/integration/Serializer/_snapshot/TestDataObject.json index 5e6c17db..19bc0293 100644 --- a/tests/integration/Serializer/_snapshot/TestDataObject.json +++ b/tests/integration/Serializer/_snapshot/TestDataObject.json @@ -1,7 +1,6 @@ { "string": "some_string", "int": 1, - "innerObject": null, "location": { "_media-type": "application\/vnd.ibexa.api.Location+json", "_href": "\/api\/ibexa\/v2\/content\/locations\/1\/2", diff --git a/tests/integration/Serializer/_snapshot/TestDataObject.xml b/tests/integration/Serializer/_snapshot/TestDataObject.xml index d3b038ee..c043ebaa 100644 --- a/tests/integration/Serializer/_snapshot/TestDataObject.xml +++ b/tests/integration/Serializer/_snapshot/TestDataObject.xml @@ -1,88 +1,48 @@ + some_string 1 - - - <_media-type>application/vnd.ibexa.api.Location+json - <_href>/api/ibexa/v2/content/locations/1/2 + 2 0 - 0 - 0 - - <_media-type>application/vnd.ibexa.api.Location+json - <_href>/api/ibexa/v2/content/locations/1 - + false + false + /1/2/ 1 1 f3e90596361e31d496d4026eb624c983 - - <_media-type>application/vnd.ibexa.api.LocationList+json - <_href>/api/ibexa/v2/content/locations/1/2/children - - - <_media-type>application/vnd.ibexa.api.Content+json - <_href>/api/ibexa/v2/content/objects/57 - + + PRIORITY ASC - - <_media-type>application/vnd.ibexa.api.UrlAliasRefList+json - <_href>/api/ibexa/v2/content/locations/1/2/urlaliases - - - <_media-type>application/vnd.ibexa.api.ContentInfo+json - <_href>/api/ibexa/v2/content/objects/57 - - <_media-type>application/vnd.ibexa.api.Content+json - <_href>/api/ibexa/v2/content/objects/57 - <_remoteId>8a9c9c761004866fb458d89910f52bee - <_id>57 - - <_media-type>application/vnd.ibexa.api.ContentType+json - <_href>/api/ibexa/v2/content/types/21 - + + + + Home Home - - <_media-type>application/vnd.ibexa.api.VersionList+json - <_href>/api/ibexa/v2/content/objects/57/versions - - - <_media-type>application/vnd.ibexa.api.Version+json - <_href>/api/ibexa/v2/content/objects/57/currentversion - - <_media-type>application/vnd.ibexa.api.Version+json - <_href>/api/ibexa/v2/content/objects/57/versions/1 + + + 504 1 PUBLISHED 2007-11-28T16:51:36+00:00 - - <_media-type>application/vnd.ibexa.api.User+json - <_href>/api/ibexa/v2/user/users/14 - + 2007-11-28T16:50:55+00:00 eng-GB eng-GB - - <_media-type>application/vnd.ibexa.api.VersionTranslationInfo+json + eng-GB - - <_languageCode>eng-GB - Home - + Home - - <_media-type>application/vnd.ibexa.api.ContentInfo+json - <_href>/api/ibexa/v2/content/objects/57 - + @@ -93,43 +53,22 @@ Home - - <_media-type>application/vnd.ibexa.api.RelationList+json - <_href>/api/ibexa/v2/content/objects/57/versions/1/relations - - - - <_media-type>application/vnd.ibexa.api.Thumbnail+json - + + -
- <_media-type>application/vnd.ibexa.api.Section+json - <_href>/api/ibexa/v2/content/sections/1 -
- - <_media-type>application/vnd.ibexa.api.Location+json - <_href>/api/ibexa/v2/content/locations/1/2 - - - <_media-type>application/vnd.ibexa.api.LocationList+json - <_href>/api/ibexa/v2/content/objects/57/locations - - - <_media-type>application/vnd.ibexa.api.User+json - <_href>/api/ibexa/v2/user/users/14 - +
+ + + 2007-11-28T16:51:36+00:00 2007-11-19T13:54:46+00:00 eng-GB 1 - 1 - 0 + true + false PUBLISHED - - <_media-type>application/vnd.ibexa.api.ContentObjectStates+json - <_href>/api/ibexa/v2/content/objects/57/objectstates - + diff --git a/tests/lib/Output/Generator/FieldTypeHashGeneratorBaseTest.php b/tests/lib/Output/Generator/FieldTypeHashGeneratorBaseTest.php index 18bd2d2d..95c3d740 100644 --- a/tests/lib/Output/Generator/FieldTypeHashGeneratorBaseTest.php +++ b/tests/lib/Output/Generator/FieldTypeHashGeneratorBaseTest.php @@ -284,18 +284,31 @@ private function getGeneratorOutput() return $this->getGenerator()->endDocument('Version'); } - private function assertSerializationSame($functionName) + private function assertSerializationSame(string $functionName): void { $fixtureFile = $this->getFixtureFile($functionName); - $actualResult = $this->getGeneratorOutput(); + $isXml = str_starts_with(basename($fixtureFile), 'Xml'); - // file_put_contents( $fixtureFile, $actualResult ); - // $this->markTestIncomplete( "Wrote fixture to '{$fixtureFile}'." ); + $actualResult = $this->getGeneratorOutput(); - self::assertSame( - file_get_contents($this->getFixtureFile($functionName)), - $actualResult - ); + if ($isXml) { + $expectedXml = new \DOMDocument(); + $expectedXml->preserveWhiteSpace = false; + $expectedXml->formatOutput = true; + $expectedXml->load($fixtureFile); + + $actualXml = new \DOMDocument(); + $actualXml->preserveWhiteSpace = false; + $actualXml->formatOutput = true; + $actualXml->loadXML($actualResult); + + self::assertSame($expectedXml->saveXML(), $actualXml->saveXML()); + } else { + self::assertSame( + file_get_contents($this->getFixtureFile($functionName)), + $actualResult + ); + } } private function getFixtureFile($functionName) diff --git a/tests/lib/Output/Generator/XmlTest.php b/tests/lib/Output/Generator/XmlTest.php index 8d30e2d1..0378b972 100644 --- a/tests/lib/Output/Generator/XmlTest.php +++ b/tests/lib/Output/Generator/XmlTest.php @@ -26,8 +26,8 @@ public function testGeneratorDocument(): void $generator->startDocument('test'); - self::assertSame( - file_get_contents(__DIR__ . '/_fixtures/' . __FUNCTION__ . '.xml'), + $this->compareXmls( + __DIR__ . '/_fixtures/' . __FUNCTION__ . '.xml', $generator->endDocument('test'), ); } @@ -41,8 +41,8 @@ public function testGeneratorElement(): void $generator->startObjectElement('element'); $generator->endObjectElement('element'); - self::assertSame( - file_get_contents(__DIR__ . '/_fixtures/' . __FUNCTION__ . '.xml'), + $this->compareXmls( + __DIR__ . '/_fixtures/' . __FUNCTION__ . '.xml', $generator->endDocument('test') ); } @@ -56,8 +56,8 @@ public function testGeneratorElementMediaTypeOverwrite(): void $generator->startObjectElement('element', 'User'); $generator->endObjectElement('element'); - self::assertSame( - file_get_contents(__DIR__ . '/_fixtures/' . __FUNCTION__ . '.xml'), + $this->compareXmls( + __DIR__ . '/_fixtures/' . __FUNCTION__ . '.xml', $generator->endDocument('test') ); } @@ -75,8 +75,8 @@ public function testGeneratorStackedElement(): void $generator->endObjectElement('element'); - self::assertSame( - file_get_contents(__DIR__ . '/_fixtures/' . __FUNCTION__ . '.xml'), + $this->compareXmls( + __DIR__ . '/_fixtures/' . __FUNCTION__ . '.xml', $generator->endDocument('test'), ); } @@ -93,8 +93,8 @@ public function testGeneratorAttribute(): void $generator->endObjectElement('element'); - self::assertSame( - file_get_contents(__DIR__ . '/_fixtures/' . __FUNCTION__ . '.xml'), + $this->compareXmls( + __DIR__ . '/_fixtures/' . __FUNCTION__ . '.xml', $generator->endDocument('test') ); } @@ -112,8 +112,8 @@ public function testGeneratorStartEndAttribute(): void $generator->endObjectElement('element'); - self::assertSame( - file_get_contents(__DIR__ . '/_fixtures/' . __FUNCTION__ . '.xml'), + $this->compareXmls( + __DIR__ . '/_fixtures/' . __FUNCTION__ . '.xml', $generator->endDocument('test') ); } @@ -131,8 +131,8 @@ public function testGeneratorMultipleAttributes(): void $generator->endObjectElement('element'); - self::assertSame( - file_get_contents(__DIR__ . '/_fixtures/' . __FUNCTION__ . '.xml'), + $this->compareXmls( + __DIR__ . '/_fixtures/' . __FUNCTION__ . '.xml', $generator->endDocument('test') ); } @@ -149,8 +149,8 @@ public function testGeneratorValueElement(): void $generator->endObjectElement('element'); - self::assertSame( - file_get_contents(__DIR__ . '/_fixtures/' . __FUNCTION__ . '.xml'), + $this->compareXmls( + __DIR__ . '/_fixtures/' . __FUNCTION__ . '.xml', $generator->endDocument('test'), ); } @@ -168,8 +168,8 @@ public function testGeneratorStartEndValueElement(): void $generator->endObjectElement('element'); - self::assertSame( - file_get_contents(__DIR__ . '/_fixtures/' . __FUNCTION__ . '.xml'), + $this->compareXmls( + __DIR__ . '/_fixtures/' . __FUNCTION__ . '.xml', $generator->endDocument('test') ); } @@ -194,8 +194,8 @@ public function testGeneratorElementList(): void $generator->endObjectElement('elementList'); - self::assertSame( - file_get_contents(__DIR__ . '/_fixtures/' . __FUNCTION__ . '.xml'), + $this->compareXmls( + __DIR__ . '/_fixtures/' . __FUNCTION__ . '.xml', $generator->endDocument('test') ); } @@ -216,8 +216,8 @@ public function testGeneratorHashElement(): void $generator->endHashElement('elements'); - self::assertSame( - file_get_contents(__DIR__ . '/_fixtures/' . __FUNCTION__ . '.xml'), + $this->compareXmls( + __DIR__ . '/_fixtures/' . __FUNCTION__ . '.xml', $generator->endDocument('test') ); } @@ -238,8 +238,8 @@ public function testGeneratorValueList(): void $generator->endList('simpleValue'); $generator->endObjectElement('element'); - self::assertSame( - file_get_contents(__DIR__ . '/_fixtures/' . __FUNCTION__ . '.xml'), + $this->compareXmls( + __DIR__ . '/_fixtures/' . __FUNCTION__ . '.xml', $generator->endDocument('test') ); } @@ -285,4 +285,19 @@ protected function getGenerator(): Generator return $this->generator; } + + private function compareXmls(string|false $expected, string $result): void + { + $expectedXml = new \DOMDocument(); + $expectedXml->preserveWhiteSpace = false; + $expectedXml->formatOutput = true; + $expectedXml->load((string)$expected); + + $actualXml = new \DOMDocument(); + $actualXml->preserveWhiteSpace = false; + $actualXml->formatOutput = true; + $actualXml->loadXML($result); + + self::assertEquals($expectedXml->saveXML(), $actualXml->saveXML()); + } } diff --git a/tests/lib/Server/Output/ValueObjectVisitor/LocationTest.php b/tests/lib/Server/Output/ValueObjectVisitor/LocationTest.php index fdb75e0c..7e42b340 100644 --- a/tests/lib/Server/Output/ValueObjectVisitor/LocationTest.php +++ b/tests/lib/Server/Output/ValueObjectVisitor/LocationTest.php @@ -93,11 +93,38 @@ public function testVisitLocationAttributesResolvesMainLocation( $this->assertXMLTag( [ - 'tag' => 'Location', - 'content' => $location->id . 1 . 'false' . 'false', + 'tag' => 'id', + 'content' => $location->id, ], $result, - 'Invalid element.', + 'Invalid element.', + ); + + $this->assertXMLTag( + [ + 'tag' => 'priority', + 'content' => 1, + ], + $result, + 'Invalid element.', + ); + + $this->assertXMLTag( + [ + 'tag' => 'hidden', + 'content' => 'false', + ], + $result, + 'Invalid element.', + ); + + $this->assertXMLTag( + [ + 'tag' => 'invisible', + 'content' => 'false', + ], + $result, + 'Invalid element.', ); }