Chris@18
|
1 <?php
|
Chris@18
|
2
|
Chris@18
|
3 namespace Drupal\Tests\jsonapi\Functional;
|
Chris@18
|
4
|
Chris@18
|
5 use Drupal\Component\Serialization\Json;
|
Chris@18
|
6 use Drupal\Core\Entity\EntityInterface;
|
Chris@18
|
7 use Drupal\entity_test\Entity\EntityTestBundle;
|
Chris@18
|
8 use Drupal\entity_test\Entity\EntityTestNoLabel;
|
Chris@18
|
9 use Drupal\entity_test\Entity\EntityTestWithBundle;
|
Chris@18
|
10 use Drupal\Tests\BrowserTestBase;
|
Chris@18
|
11 use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
|
Chris@18
|
12
|
Chris@18
|
13 /**
|
Chris@18
|
14 * Makes assertions about the JSON:API behavior for internal entities.
|
Chris@18
|
15 *
|
Chris@18
|
16 * @group jsonapi
|
Chris@18
|
17 *
|
Chris@18
|
18 * @internal
|
Chris@18
|
19 */
|
Chris@18
|
20 class InternalEntitiesTest extends BrowserTestBase {
|
Chris@18
|
21
|
Chris@18
|
22 use EntityReferenceTestTrait;
|
Chris@18
|
23
|
Chris@18
|
24 /**
|
Chris@18
|
25 * {@inheritdoc}
|
Chris@18
|
26 */
|
Chris@18
|
27 protected static $modules = [
|
Chris@18
|
28 'jsonapi',
|
Chris@18
|
29 'entity_test',
|
Chris@18
|
30 'serialization',
|
Chris@18
|
31 ];
|
Chris@18
|
32
|
Chris@18
|
33 /**
|
Chris@18
|
34 * A test user.
|
Chris@18
|
35 *
|
Chris@18
|
36 * @var \Drupal\user\UserInterface
|
Chris@18
|
37 */
|
Chris@18
|
38 protected $testUser;
|
Chris@18
|
39
|
Chris@18
|
40 /**
|
Chris@18
|
41 * An entity of an internal entity type.
|
Chris@18
|
42 *
|
Chris@18
|
43 * @var \Drupal\Core\Entity\EntityInterface
|
Chris@18
|
44 */
|
Chris@18
|
45 protected $internalEntity;
|
Chris@18
|
46
|
Chris@18
|
47 /**
|
Chris@18
|
48 * An entity referencing an internal entity.
|
Chris@18
|
49 *
|
Chris@18
|
50 * @var \Drupal\Core\Entity\EntityInterface
|
Chris@18
|
51 */
|
Chris@18
|
52 protected $referencingEntity;
|
Chris@18
|
53
|
Chris@18
|
54 /**
|
Chris@18
|
55 * {@inheritdoc}
|
Chris@18
|
56 */
|
Chris@18
|
57 public function setUp() {
|
Chris@18
|
58 parent::setUp();
|
Chris@18
|
59 $this->testUser = $this->drupalCreateUser([
|
Chris@18
|
60 'view test entity',
|
Chris@18
|
61 'administer entity_test_with_bundle content',
|
Chris@18
|
62 ], $this->randomString(), TRUE);
|
Chris@18
|
63 EntityTestBundle::create([
|
Chris@18
|
64 'id' => 'internal_referencer',
|
Chris@18
|
65 'label' => 'Entity Test Internal Referencer',
|
Chris@18
|
66 ])->save();
|
Chris@18
|
67 $this->createEntityReferenceField(
|
Chris@18
|
68 'entity_test_with_bundle',
|
Chris@18
|
69 'internal_referencer',
|
Chris@18
|
70 'field_internal',
|
Chris@18
|
71 'Internal Entities',
|
Chris@18
|
72 'entity_test_no_label'
|
Chris@18
|
73 );
|
Chris@18
|
74 $this->internalEntity = EntityTestNoLabel::create([]);
|
Chris@18
|
75 $this->internalEntity->save();
|
Chris@18
|
76 $this->referencingEntity = EntityTestWithBundle::create([
|
Chris@18
|
77 'type' => 'internal_referencer',
|
Chris@18
|
78 'field_internal' => $this->internalEntity->id(),
|
Chris@18
|
79 ]);
|
Chris@18
|
80 $this->referencingEntity->save();
|
Chris@18
|
81 drupal_flush_all_caches();
|
Chris@18
|
82 }
|
Chris@18
|
83
|
Chris@18
|
84 /**
|
Chris@18
|
85 * Ensures that internal resources types aren't present in the entry point.
|
Chris@18
|
86 */
|
Chris@18
|
87 public function testEntryPoint() {
|
Chris@18
|
88 $document = $this->jsonapiGet('/jsonapi');
|
Chris@18
|
89 $this->assertArrayNotHasKey(
|
Chris@18
|
90 "{$this->internalEntity->getEntityTypeId()}--{$this->internalEntity->bundle()}",
|
Chris@18
|
91 $document['links'],
|
Chris@18
|
92 'The entry point should not contain links to internal resource type routes.'
|
Chris@18
|
93 );
|
Chris@18
|
94 }
|
Chris@18
|
95
|
Chris@18
|
96 /**
|
Chris@18
|
97 * Ensures that internal resources types aren't present in the routes.
|
Chris@18
|
98 */
|
Chris@18
|
99 public function testRoutes() {
|
Chris@18
|
100 // This cannot be in a data provider because it needs values created by the
|
Chris@18
|
101 // setUp method.
|
Chris@18
|
102 $paths = [
|
Chris@18
|
103 'individual' => "/jsonapi/entity_test_no_label/entity_test_no_label/{$this->internalEntity->uuid()}",
|
Chris@18
|
104 'collection' => "/jsonapi/entity_test_no_label/entity_test_no_label",
|
Chris@18
|
105 'related' => "/jsonapi/entity_test_no_label/entity_test_no_label/{$this->internalEntity->uuid()}/field_internal",
|
Chris@18
|
106 ];
|
Chris@18
|
107 $this->drupalLogin($this->testUser);
|
Chris@18
|
108 foreach ($paths as $type => $path) {
|
Chris@18
|
109 $this->drupalGet($path, ['Accept' => 'application/vnd.api+json']);
|
Chris@18
|
110 $this->assertSame(404, $this->getSession()->getStatusCode());
|
Chris@18
|
111 }
|
Chris@18
|
112 }
|
Chris@18
|
113
|
Chris@18
|
114 /**
|
Chris@18
|
115 * Asserts that internal entities are not included in compound documents.
|
Chris@18
|
116 */
|
Chris@18
|
117 public function testIncludes() {
|
Chris@18
|
118 $document = $this->getIndividual($this->referencingEntity, [
|
Chris@18
|
119 'query' => ['include' => 'field_internal'],
|
Chris@18
|
120 ]);
|
Chris@18
|
121 $this->assertArrayNotHasKey(
|
Chris@18
|
122 'included',
|
Chris@18
|
123 $document,
|
Chris@18
|
124 'Internal entities should not be included in compound documents.'
|
Chris@18
|
125 );
|
Chris@18
|
126 }
|
Chris@18
|
127
|
Chris@18
|
128 /**
|
Chris@18
|
129 * Asserts that links to internal relationships aren't generated.
|
Chris@18
|
130 */
|
Chris@18
|
131 public function testLinks() {
|
Chris@18
|
132 $document = $this->getIndividual($this->referencingEntity);
|
Chris@18
|
133 $this->assertArrayNotHasKey(
|
Chris@18
|
134 'related',
|
Chris@18
|
135 $document['data']['relationships']['field_internal']['links'],
|
Chris@18
|
136 'Links to internal-only related routes should not be in the document.'
|
Chris@18
|
137 );
|
Chris@18
|
138 }
|
Chris@18
|
139
|
Chris@18
|
140 /**
|
Chris@18
|
141 * Returns the decoded JSON:API document for the for the given entity.
|
Chris@18
|
142 *
|
Chris@18
|
143 * @param \Drupal\Core\Entity\EntityInterface $entity
|
Chris@18
|
144 * The entity to request.
|
Chris@18
|
145 * @param array $options
|
Chris@18
|
146 * URL options.
|
Chris@18
|
147 *
|
Chris@18
|
148 * @return array
|
Chris@18
|
149 * The decoded response document.
|
Chris@18
|
150 */
|
Chris@18
|
151 protected function getIndividual(EntityInterface $entity, array $options = []) {
|
Chris@18
|
152 $entity_type_id = $entity->getEntityTypeId();
|
Chris@18
|
153 $bundle = $entity->bundle();
|
Chris@18
|
154 $path = "/jsonapi/{$entity_type_id}/{$bundle}/{$entity->uuid()}";
|
Chris@18
|
155 return $this->jsonapiGet($path, $options);
|
Chris@18
|
156 }
|
Chris@18
|
157
|
Chris@18
|
158 /**
|
Chris@18
|
159 * Performs an authenticated request and returns the decoded document.
|
Chris@18
|
160 *
|
Chris@18
|
161 * @param \Drupal\Core\Entity\EntityInterface $entity
|
Chris@18
|
162 * The entity to request.
|
Chris@18
|
163 * @param string $relationship
|
Chris@18
|
164 * The field name of the relationship to request.
|
Chris@18
|
165 * @param array $options
|
Chris@18
|
166 * URL options.
|
Chris@18
|
167 *
|
Chris@18
|
168 * @return array
|
Chris@18
|
169 * The decoded response document.
|
Chris@18
|
170 */
|
Chris@18
|
171 protected function getRelated(EntityInterface $entity, $relationship, array $options = []) {
|
Chris@18
|
172 $entity_type_id = $entity->getEntityTypeId();
|
Chris@18
|
173 $bundle = $entity->bundle();
|
Chris@18
|
174 $path = "/jsonapi/{$entity_type_id}/{$bundle}/{$entity->uuid()}/{$relationship}";
|
Chris@18
|
175 return $this->jsonapiGet($path, $options);
|
Chris@18
|
176 }
|
Chris@18
|
177
|
Chris@18
|
178 /**
|
Chris@18
|
179 * Performs an authenticated request and returns the decoded document.
|
Chris@18
|
180 */
|
Chris@18
|
181 protected function jsonapiGet($path, array $options = []) {
|
Chris@18
|
182 $this->drupalLogin($this->testUser);
|
Chris@18
|
183 $response = $this->drupalGet($path, $options, ['Accept' => 'application/vnd.api+json']);
|
Chris@18
|
184 return Json::decode($response);
|
Chris@18
|
185 }
|
Chris@18
|
186
|
Chris@18
|
187 }
|