Skip to content

Commit

Permalink
feat(graphql): extract directive plugins for entity references
Browse files Browse the repository at this point in the history
  • Loading branch information
pmelab committed Dec 21, 2022
1 parent af81b2e commit cda8e95
Show file tree
Hide file tree
Showing 7 changed files with 364 additions and 48 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Drupal\graphql_directives\Plugin\GraphQL\Directive;


use Drupal\Core\Plugin\PluginBase;
use Drupal\Core\TypedData\TranslatableInterface;
use Drupal\graphql\GraphQL\Resolver\ResolverInterface;
use Drupal\graphql\GraphQL\ResolverBuilder;
use Drupal\graphql_directives\DirectiveInterface;

/**
* @Directive(
* id = "resolveEntityReference",
* arguments = {
* "field" = "String!"
* }
* )
*/
class EntityReference extends PluginBase implements DirectiveInterface {

public function buildResolver(ResolverBuilder $builder, array $arguments): ResolverInterface {
return $builder->produce('entity_reference')
->map('entity', $builder->fromParent())
->map('language', $builder->callback(
fn(TranslatableInterface $value) => $value->language()->getId()
))
->map('field', $builder->fromValue($arguments['field']));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Drupal\graphql_directives\Plugin\GraphQL\Directive;


use Drupal\Core\Plugin\PluginBase;
use Drupal\Core\TypedData\TranslatableInterface;
use Drupal\graphql\GraphQL\Resolver\ResolverInterface;
use Drupal\graphql\GraphQL\ResolverBuilder;
use Drupal\graphql_directives\DirectiveInterface;

/**
* @Directive(
* id = "resolveEntityReferenceRevisions",
* arguments = {
* "field" = "String!"
* }
* )
*/
class EntityReferenceRevisions extends PluginBase implements DirectiveInterface {

public function buildResolver(ResolverBuilder $builder, array $arguments): ResolverInterface {
return $builder->produce('entity_reference_revisions')
->map('entity', $builder->fromParent())
->map('language', $builder->callback(
fn(TranslatableInterface $value) => $value->language()->getId()
))
->map('field', $builder->fromValue($arguments['field']));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "Directives Test - References",
"schemaPath": "./schema.graphqls",
"includes": ["./directives.graphqls"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
type Query {
article(nid: String!, lang: String!): Article
@loadEntity(type: "node", id: "$nid")
@resolveEntityTranslation(lang: "$lang")
}

type Article {
title: String! @resolveEntityLabel
references: [Article!]! @resolveEntityReference(field: "references")
revisions: [Article!]! @resolveEntityReferenceRevisions(field: "revisions")
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\graphql\Entity\Server;
use Drupal\node\Entity\NodeType;
use Drupal\Tests\graphql\Kernel\GraphQLTestBase;
use Drupal\Tests\graphql_directives\Traits\GraphQLDirectivesTestTrait;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,285 @@
<?php

namespace Drupal\Tests\graphql_directives\Kernel;

use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\node\Entity\Node;
use Drupal\node\Entity\NodeType;
use Drupal\Tests\graphql\Kernel\GraphQLTestBase;
use Drupal\Tests\graphql_directives\Traits\GraphQLDirectivesTestTrait;

class EntityReferenceTest extends GraphQLTestBase {

use GraphQLDirectivesTestTrait;

public static $modules = [
'graphql_directives',
'node',
'field',
'entity_reference',
'entity_reference_revisions',
];

protected function setUp(): void {
parent::setUp();
$this->setupDirectableSchema(__DIR__ . '/../../assets/references');
NodeType::create([
'type' => 'article',
'name' => 'Article',
'translatable' => TRUE,
])->save();

$this->container->get('content_translation.manager')->setEnabled(
'node',
'article',
TRUE
);

FieldStorageConfig::create([
'field_name' => 'references',
'type' => 'entity_reference',
'entity_type' => 'node',
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
'settings' => [
'target_type' => 'node',
],
])->save();

FieldConfig::create([
'field_name' => 'references',
'entity_type' => 'node',
'bundle' => 'article',
'label' => 'References',
'settings' => [
'handler' => 'default',
'handler_settings' => [],
],
])->save();

FieldStorageConfig::create([
'field_name' => 'revisions',
'type' => 'entity_reference_revisions',
'entity_type' => 'node',
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
'settings' => [
'target_type' => 'node',
],
])->save();

FieldConfig::create([
'field_name' => 'revisions',
'entity_type' => 'node',
'bundle' => 'article',
'label' => 'Revisions',
'settings' => [
'handler' => 'default',
'handler_settings' => [],
],
])->save();
}

public function testEntityReference() {
$reference = Node::create([
'title' => 'Reference',
'type' => 'article',
'langcode' => 'en',
]);
$reference->save();

$host = Node::create([
'type' => 'article',
'title' => 'Host',
'langcode' => 'en',
'references' => [$reference],
]);
$host->save();

$metadata = $this->defaultCacheMetaData();
$metadata->addCacheableDependency($host);
$metadata->addCacheableDependency($reference);
$metadata->addCacheContexts(['static:language:en']);
$this->assertResults(
'query ($nid: String!) { article(nid: $nid, lang: "en") { title references { title } } }',
[
'nid' => $host->id(),
'lang' => 'en',
], [
'article' => [
'title' => 'Host',
'references' => [
[
'title' => 'Reference',
],
],
],
], $metadata);
}

public function testTranslatedEntityReference() {
$reference = Node::create([
'title' => 'Reference',
'type' => 'article',
]);
$reference->save();
$reference->addTranslation('de', [
'title' => 'Reference (de)',
])->save();

$host = Node::create([
'type' => 'article',
'title' => 'Host',
'references' => [$reference],
]);
$host->save();
$host->addTranslation('de', [
'title' => 'Host (de)',
'references' => [$reference],
])->save();

$metadata = $this->defaultCacheMetaData();
$metadata->addCacheableDependency($host);
$metadata->addCacheableDependency($reference);
$metadata->addCacheContexts(['static:language:de']);
$this->assertResults(
'query ($nid: String!) { article(nid: $nid, lang: "de") { title references { title } } }',
[
'nid' => $host->id(),
'lang' => 'de',
], [
'article' => [
'title' => 'Host (de)',
'references' => [
[
'title' => 'Reference (de)',
],
],
],
], $metadata);
}

public function testUntranslatedEntityReference() {
$reference = Node::create([
'title' => 'Reference',
'type' => 'article',
]);
$reference->save();

$host = Node::create([
'type' => 'article',
'title' => 'Host',
'references' => [$reference],
]);
$host->save();
$host->addTranslation('de', [
'title' => 'Host (de)',
'references' => [$reference],
])->save();

$metadata = $this->defaultCacheMetaData();
$metadata->addCacheableDependency($host);
$metadata->addCacheableDependency($reference);
$metadata->addCacheContexts(['static:language:de']);
$this->assertResults(
'query ($nid: String!) { article(nid: $nid, lang: "de") { title references { title } } }',
[
'nid' => $host->id(),
'lang' => 'de',
], [
'article' => [
'title' => 'Host (de)',
'references' => [
[
'title' => 'Reference',
],
],
],
], $metadata);
}

public function testUntranslatedEntityReferee() {
$reference = Node::create([
'title' => 'Reference',
'type' => 'article',
]);
$reference->save();
$reference->addTranslation('de', [
'title' => 'Reference (de)',
])->save();

$host = Node::create([
'type' => 'article',
'title' => 'Host',
'references' => [$reference],
]);
$host->save();

$metadata = $this->defaultCacheMetaData();
$metadata->addCacheableDependency($host);
$metadata->addCacheableDependency($reference);
$metadata->addCacheContexts(['static:language:en']);
$this->assertResults(
'query ($nid: String!) { article(nid: $nid, lang: "en") { title references { title } } }',
[
'nid' => $host->id(),
'lang' => 'de',
], [
'article' => [
'title' => 'Host',
'references' => [
[
'title' => 'Reference',
],
],
],
], $metadata);
}

public function testRevisionedEntityReference() {
$reference = Node::create([
'title' => 'Reference',
'type' => 'article',
]);
$reference->save();

$host = Node::create([
'type' => 'article',
'title' => 'Host',
'references' => [$reference],
'revisions' => [$reference],
]);
$host->save();

$reference->setNewRevision();
$reference->set('title', 'Reference (rev)');
$reference->save();


$metadata = $this->defaultCacheMetaData();
$metadata->addCacheableDependency($host);
$metadata->addCacheableDependency($reference);
$metadata->addCacheContexts(['static:language:en']);
$this->assertResults(
'query ($nid: String!) { article(nid: $nid, lang: "en") { title references { title } revisions { title } } }',
[
'nid' => $host->id(),
'lang' => 'en',
], [
'article' => [
'title' => 'Host',
'references' => [
[
'title' => 'Reference (rev)',
],
],
'revisions' => [
[
'title' => 'Reference',
],
],
],
], $metadata);
}

}
Loading

0 comments on commit cda8e95

Please sign in to comment.