Skip to content

Commit

Permalink
fix(graphql): use depth for nested resource class operation (#5314)
Browse files Browse the repository at this point in the history
* test: add reproducer for bug 5310

* fix(graphql): use depth for nested resource class operation

Co-authored-by: Alan Poulain <contact@alanpoulain.eu>
  • Loading branch information
NicoHaase and alanpoulain committed Jan 12, 2023
1 parent 7fce4eb commit 3d8371a
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 1 deletion.
27 changes: 27 additions & 0 deletions features/graphql/query.feature
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,33 @@ Feature: GraphQL query support
And the JSON node "data.multiRelationsDummy.oneToManyRelations.edges[0].node.name" should be equal to "RelatedOneToManyDummy12"
And the JSON node "data.multiRelationsDummy.oneToManyRelations.edges[2].node.name" should be equal to "RelatedOneToManyDummy32"

@createSchema @!mongodb
Scenario: Retrieve an item with child relation to the same resource
Given there are tree dummies
When I send the following GraphQL request:
"""
{
treeDummies {
edges {
node {
id
children {
totalCount
}
}
}
}
}
"""
Then the response status code should be 200
And the response should be in JSON
And the header "Content-Type" should be equal to "application/json"
And the JSON node "errors" should not exist
And the JSON node "data.treeDummies.edges[0].node.id" should be equal to "/tree_dummies/1"
And the JSON node "data.treeDummies.edges[0].node.children.totalCount" should be equal to "1"
And the JSON node "data.treeDummies.edges[1].node.id" should be equal to "/tree_dummies/2"
And the JSON node "data.treeDummies.edges[1].node.children.totalCount" should be equal to "0"

@createSchema
Scenario: Retrieve a Relay Node
Given there are 2 dummy objects with relatedDummy
Expand Down
2 changes: 1 addition & 1 deletion src/GraphQl/Type/FieldsBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ private function getResourceFieldConfiguration(?string $property, ?string $field
}

$resourceOperation = $rootOperation;
if ($resourceClass && $rootOperation->getClass() && $this->resourceClassResolver->isResourceClass($resourceClass) && $rootOperation->getClass() !== $resourceClass) {
if ($resourceClass && $depth >= 1 && $this->resourceClassResolver->isResourceClass($resourceClass)) {
$resourceMetadataCollection = $this->resourceMetadataCollectionFactory->create($resourceClass);
$resourceOperation = $resourceMetadataCollection->getOperation($isCollectionType ? 'collection_query' : 'item_query');
}
Expand Down
17 changes: 17 additions & 0 deletions tests/Behat/DoctrineContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\SymfonyUuidDummy;
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\Taxon;
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\ThirdLevel;
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\TreeDummy;
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\UrlEncodedId;
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\User;
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\UuidIdentifierDummy;
Expand Down Expand Up @@ -799,6 +800,22 @@ public function thereAreMultiRelationsDummyObjectsHavingEachAManyToOneRelationMa
$this->manager->flush();
}

/**
* @Given there are tree dummies
*/
public function thereAreTreeDummies(): void
{
$parentDummy = new TreeDummy();
$this->manager->persist($parentDummy);

$childDummy = new TreeDummy();
$childDummy->setParent($parentDummy);

$this->manager->persist($childDummy);

$this->manager->flush();
}

/**
* @Given there are :nb dummy objects with dummyDate
* @Given there is :nb dummy object with dummyDate
Expand Down
63 changes: 63 additions & 0 deletions tests/Fixtures/TestBundle/Entity/TreeDummy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?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\Fixtures\TestBundle\Entity;

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\GraphQl\Query;
use ApiPlatform\Metadata\GraphQl\QueryCollection;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

#[ApiResource(graphQlOperations: [new Query(), new QueryCollection()])]
#[ORM\Entity]
class TreeDummy
{
#[ORM\Column(type: 'integer', nullable: true)]
#[ORM\Id]
#[ORM\GeneratedValue(strategy: 'AUTO')]
private ?int $id = null;

#[ORM\ManyToOne(targetEntity: self::class, inversedBy: 'children')]
public ?TreeDummy $parent = null;

/** @var Collection<int, TreeDummy> */
#[ORM\OneToMany(targetEntity: self::class, mappedBy: 'parent')]
public Collection $children;

public function __construct()
{
$this->children = new ArrayCollection();
}

public function getId(): ?int
{
return $this->id;
}

public function getParent(): ?self
{
return $this->parent;
}

public function setParent(?self $parent): void
{
$this->parent = $parent;
}

public function getChildren(): Collection
{
return $this->children;
}
}

0 comments on commit 3d8371a

Please sign in to comment.