Skip to content

JsonSchema assertion will always fail for API Resources that have an output class defined #4222

Description

@llupa

API Platform version(s) affected: 2.5.8 and up

Description

The SchemaFactory for Hydra properties is hardcoded to add @context as a string type. This works fine when the Resource class matches the output object. The ItemNormalizer will set @context as an IRI/URI in this case.

In case of a Resource class using an output class (see example below) the ItemNormalizer will ignore the object and the ObjectNormalizer takes over and will hard-code set the @context as an array. This happens via getAnonymousResourceContext used in ContextBuilder.

How to reproduce

  1. Create a resource with output option:
Domain\Licence\Entity\LicenceCommentary:
    description: Licence commentary
    attributes:
        output: Domain\Licence\Model\LicenceCommentaryOutput
        input: Domain\Licence\Model\LicenceCommentaryInput
  1. use the JsonSchema assertions provided by API Platform:
self::assertMatchesResourceItemJsonSchema(LicenceCommentary::class);
✘ Create [405 ms]
   │
   │ Failed asserting that Array &0 (
   │     '@context' => Array &1 (
   │         '@vocab' => 'http://example.com/docs.jsonld#'
   │         'hydra' => 'http://www.w3.org/ns/hydra/core#'
   │         'uuid' => 'LicenceCommentaryOutput/uuid'
   │         'type' => 'LicenceCommentaryOutput/type'
   │         'text' => 'LicenceCommentaryOutput/text'
   │     )
   │     '@type' => 'LicenceCommentary'
   │     '@id' => '/licences/57e4525d-3bc7-44ea-a5d9-8039f8f431fa/commentaries/92fd7512-70ff-423c-9136-96529a27b21e'
   │     'uuid' => '92fd7512-70ff-423c-9136-96529a27b21e'
   │     'type' => 'create type'
   │     'text' => 'create text'
   │ ) matches the provided JSON Schema.
   │ @context: Object value found, but a string is required
   │ 
   │ /builds/audi/vms-api/vendor/api-platform/core/src/Bridge/Symfony/Bundle/Test/ApiTestAssertionsTrait.php:109
   │ /builds/audi/vms-api/vendor/api-platform/core/src/Bridge/Symfony/Bundle/Test/ApiTestAssertionsTrait.php:123
   │ /builds/audi/vms-api/tests/Functional/Licence/LicenceCommentaryResourceTest.php:37
   │ 

Possible Solution

I have already tried a solution locally, it seems if the Hydra JsonSchema, SchemaFactory becomes smarter by using the ResourceClassInfoTrait it can resolve wether @context will be an object or string via isResourceClass(string $class) in the trait. The assertions pass afterwards.

I can open a PR if this is enough.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions