Mercurial > hg > cmmr2012-drupal-site
comparison core/modules/jsonapi/tests/src/Functional/TermTest.php @ 5:12f9dff5fda9 tip
Update to Drupal core 8.7.1
author | Chris Cannam |
---|---|
date | Thu, 09 May 2019 15:34:47 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
4:a9cd425dd02b | 5:12f9dff5fda9 |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\Tests\jsonapi\Functional; | |
4 | |
5 use Drupal\Component\Serialization\Json; | |
6 use Drupal\Component\Utility\NestedArray; | |
7 use Drupal\Core\Cache\Cache; | |
8 use Drupal\Core\Entity\EntityInterface; | |
9 use Drupal\Core\Url; | |
10 use Drupal\taxonomy\Entity\Term; | |
11 use Drupal\taxonomy\Entity\Vocabulary; | |
12 use Drupal\Tests\jsonapi\Traits\CommonCollectionFilterAccessTestPatternsTrait; | |
13 use GuzzleHttp\RequestOptions; | |
14 | |
15 /** | |
16 * JSON:API integration test for the "Term" content entity type. | |
17 * | |
18 * @group jsonapi | |
19 */ | |
20 class TermTest extends ResourceTestBase { | |
21 | |
22 use CommonCollectionFilterAccessTestPatternsTrait; | |
23 | |
24 /** | |
25 * {@inheritdoc} | |
26 */ | |
27 public static $modules = ['taxonomy', 'path']; | |
28 | |
29 /** | |
30 * {@inheritdoc} | |
31 */ | |
32 protected static $entityTypeId = 'taxonomy_term'; | |
33 | |
34 /** | |
35 * {@inheritdoc} | |
36 */ | |
37 protected static $resourceTypeName = 'taxonomy_term--camelids'; | |
38 | |
39 /** | |
40 * {@inheritdoc} | |
41 */ | |
42 protected static $patchProtectedFieldNames = [ | |
43 'changed' => NULL, | |
44 ]; | |
45 | |
46 /** | |
47 * {@inheritdoc} | |
48 * | |
49 * @var \Drupal\taxonomy\TermInterface | |
50 */ | |
51 protected $entity; | |
52 | |
53 /** | |
54 * {@inheritdoc} | |
55 */ | |
56 protected function setUpAuthorization($method) { | |
57 switch ($method) { | |
58 case 'GET': | |
59 $this->grantPermissionsToTestedRole(['access content']); | |
60 break; | |
61 | |
62 case 'POST': | |
63 $this->grantPermissionsToTestedRole(['create terms in camelids']); | |
64 break; | |
65 | |
66 case 'PATCH': | |
67 // Grant the 'create url aliases' permission to test the case when | |
68 // the path field is accessible, see | |
69 // \Drupal\Tests\rest\Functional\EntityResource\Node\NodeResourceTestBase | |
70 // for a negative test. | |
71 $this->grantPermissionsToTestedRole(['edit terms in camelids', 'create url aliases']); | |
72 break; | |
73 | |
74 case 'DELETE': | |
75 $this->grantPermissionsToTestedRole(['delete terms in camelids']); | |
76 break; | |
77 } | |
78 } | |
79 | |
80 /** | |
81 * {@inheritdoc} | |
82 */ | |
83 protected function createEntity() { | |
84 $vocabulary = Vocabulary::load('camelids'); | |
85 if (!$vocabulary) { | |
86 // Create a "Camelids" vocabulary. | |
87 $vocabulary = Vocabulary::create([ | |
88 'name' => 'Camelids', | |
89 'vid' => 'camelids', | |
90 ]); | |
91 $vocabulary->save(); | |
92 } | |
93 | |
94 // Create a "Llama" taxonomy term. | |
95 $term = Term::create(['vid' => $vocabulary->id()]) | |
96 ->setName('Llama') | |
97 ->setDescription("It is a little known fact that llamas cannot count higher than seven.") | |
98 ->setChangedTime(123456789) | |
99 ->set('path', '/llama'); | |
100 $term->save(); | |
101 | |
102 return $term; | |
103 } | |
104 | |
105 /** | |
106 * {@inheritdoc} | |
107 */ | |
108 protected function getExpectedDocument() { | |
109 $self_url = Url::fromUri('base:/jsonapi/taxonomy_term/camelids/' . $this->entity->uuid())->setAbsolute()->toString(TRUE)->getGeneratedUrl(); | |
110 | |
111 // We test with multiple parent terms, and combinations thereof. | |
112 // @see ::createEntity() | |
113 // @see ::testGetIndividual() | |
114 // @see ::testGetIndividualTermWithParent() | |
115 // @see ::providerTestGetIndividualTermWithParent() | |
116 $parent_term_ids = []; | |
117 for ($i = 0; $i < $this->entity->get('parent')->count(); $i++) { | |
118 $parent_term_ids[$i] = (int) $this->entity->get('parent')[$i]->target_id; | |
119 } | |
120 | |
121 $expected_parent_normalization = FALSE; | |
122 switch ($parent_term_ids) { | |
123 case [0]: | |
124 $expected_parent_normalization = [ | |
125 'data' => [ | |
126 [ | |
127 'id' => 'virtual', | |
128 'type' => 'taxonomy_term--camelids', | |
129 'meta' => [ | |
130 'links' => [ | |
131 'help' => [ | |
132 'href' => 'https://www.drupal.org/docs/8/modules/json-api/core-concepts#virtual', | |
133 'meta' => [ | |
134 'about' => "Usage and meaning of the 'virtual' resource identifier.", | |
135 ], | |
136 ], | |
137 ], | |
138 ], | |
139 ], | |
140 ], | |
141 'links' => [ | |
142 'related' => ['href' => $self_url . '/parent'], | |
143 'self' => ['href' => $self_url . '/relationships/parent'], | |
144 ], | |
145 ]; | |
146 break; | |
147 | |
148 case [2]: | |
149 $expected_parent_normalization = [ | |
150 'data' => [ | |
151 [ | |
152 'id' => Term::load(2)->uuid(), | |
153 'type' => 'taxonomy_term--camelids', | |
154 ], | |
155 ], | |
156 'links' => [ | |
157 'related' => ['href' => $self_url . '/parent'], | |
158 'self' => ['href' => $self_url . '/relationships/parent'], | |
159 ], | |
160 ]; | |
161 break; | |
162 | |
163 case [0, 2]: | |
164 $expected_parent_normalization = [ | |
165 'data' => [ | |
166 [ | |
167 'id' => 'virtual', | |
168 'type' => 'taxonomy_term--camelids', | |
169 'meta' => [ | |
170 'links' => [ | |
171 'help' => [ | |
172 'href' => 'https://www.drupal.org/docs/8/modules/json-api/core-concepts#virtual', | |
173 'meta' => [ | |
174 'about' => "Usage and meaning of the 'virtual' resource identifier.", | |
175 ], | |
176 ], | |
177 ], | |
178 ], | |
179 ], | |
180 [ | |
181 'id' => Term::load(2)->uuid(), | |
182 'type' => 'taxonomy_term--camelids', | |
183 ], | |
184 ], | |
185 'links' => [ | |
186 'related' => ['href' => $self_url . '/parent'], | |
187 'self' => ['href' => $self_url . '/relationships/parent'], | |
188 ], | |
189 ]; | |
190 break; | |
191 | |
192 case [3, 2]: | |
193 $expected_parent_normalization = [ | |
194 'data' => [ | |
195 [ | |
196 'id' => Term::load(3)->uuid(), | |
197 'type' => 'taxonomy_term--camelids', | |
198 ], | |
199 [ | |
200 'id' => Term::load(2)->uuid(), | |
201 'type' => 'taxonomy_term--camelids', | |
202 ], | |
203 ], | |
204 'links' => [ | |
205 'related' => ['href' => $self_url . '/parent'], | |
206 'self' => ['href' => $self_url . '/relationships/parent'], | |
207 ], | |
208 ]; | |
209 break; | |
210 } | |
211 | |
212 return [ | |
213 'jsonapi' => [ | |
214 'meta' => [ | |
215 'links' => [ | |
216 'self' => ['href' => 'http://jsonapi.org/format/1.0/'], | |
217 ], | |
218 ], | |
219 'version' => '1.0', | |
220 ], | |
221 'links' => [ | |
222 'self' => ['href' => $self_url], | |
223 ], | |
224 'data' => [ | |
225 'id' => $this->entity->uuid(), | |
226 'type' => 'taxonomy_term--camelids', | |
227 'links' => [ | |
228 'self' => ['href' => $self_url], | |
229 ], | |
230 'attributes' => [ | |
231 'changed' => (new \DateTime())->setTimestamp($this->entity->getChangedTime())->setTimezone(new \DateTimeZone('UTC'))->format(\DateTime::RFC3339), | |
232 'default_langcode' => TRUE, | |
233 'description' => [ | |
234 'value' => 'It is a little known fact that llamas cannot count higher than seven.', | |
235 'format' => NULL, | |
236 'processed' => "<p>It is a little known fact that llamas cannot count higher than seven.</p>\n", | |
237 ], | |
238 'langcode' => 'en', | |
239 'name' => 'Llama', | |
240 'path' => [ | |
241 'alias' => '/llama', | |
242 'pid' => 1, | |
243 'langcode' => 'en', | |
244 ], | |
245 'weight' => 0, | |
246 'drupal_internal__tid' => 1, | |
247 'status' => TRUE, | |
248 'drupal_internal__revision_id' => 1, | |
249 'revision_created' => (new \DateTime())->setTimestamp($this->entity->getRevisionCreationTime())->setTimezone(new \DateTimeZone('UTC'))->format(\DateTime::RFC3339), | |
250 'revision_log_message' => NULL, | |
251 // @todo Attempt to remove this in https://www.drupal.org/project/drupal/issues/2933518. | |
252 'revision_translation_affected' => TRUE, | |
253 ], | |
254 'relationships' => [ | |
255 'parent' => $expected_parent_normalization, | |
256 'vid' => [ | |
257 'data' => [ | |
258 'id' => Vocabulary::load('camelids')->uuid(), | |
259 'type' => 'taxonomy_vocabulary--taxonomy_vocabulary', | |
260 ], | |
261 'links' => [ | |
262 'related' => ['href' => $self_url . '/vid'], | |
263 'self' => ['href' => $self_url . '/relationships/vid'], | |
264 ], | |
265 ], | |
266 'revision_user' => [ | |
267 'data' => NULL, | |
268 'links' => [ | |
269 'related' => [ | |
270 'href' => $self_url . '/revision_user', | |
271 ], | |
272 'self' => [ | |
273 'href' => $self_url . '/relationships/revision_user', | |
274 ], | |
275 ], | |
276 ], | |
277 ], | |
278 ], | |
279 ]; | |
280 } | |
281 | |
282 /** | |
283 * {@inheritdoc} | |
284 */ | |
285 protected function getExpectedGetRelationshipDocumentData($relationship_field_name, EntityInterface $entity = NULL) { | |
286 $data = parent::getExpectedGetRelationshipDocumentData($relationship_field_name, $entity); | |
287 if ($relationship_field_name === 'parent') { | |
288 $data = [ | |
289 0 => [ | |
290 'id' => 'virtual', | |
291 'type' => 'taxonomy_term--camelids', | |
292 'meta' => [ | |
293 'links' => [ | |
294 'help' => [ | |
295 'href' => 'https://www.drupal.org/docs/8/modules/json-api/core-concepts#virtual', | |
296 'meta' => [ | |
297 'about' => "Usage and meaning of the 'virtual' resource identifier.", | |
298 ], | |
299 ], | |
300 ], | |
301 ], | |
302 ], | |
303 ]; | |
304 } | |
305 return $data; | |
306 } | |
307 | |
308 /** | |
309 * {@inheritdoc} | |
310 */ | |
311 protected function getPostDocument() { | |
312 return [ | |
313 'data' => [ | |
314 'type' => 'taxonomy_term--camelids', | |
315 'attributes' => [ | |
316 'name' => 'Dramallama', | |
317 'description' => [ | |
318 'value' => 'Dramallamas are the coolest camelids.', | |
319 'format' => NULL, | |
320 ], | |
321 ], | |
322 ], | |
323 ]; | |
324 } | |
325 | |
326 /** | |
327 * {@inheritdoc} | |
328 */ | |
329 protected function getExpectedUnauthorizedAccessMessage($method) { | |
330 switch ($method) { | |
331 case 'GET': | |
332 return "The 'access content' permission is required and the taxonomy term must be published."; | |
333 | |
334 case 'POST': | |
335 return "The following permissions are required: 'create terms in camelids' OR 'administer taxonomy'."; | |
336 | |
337 case 'PATCH': | |
338 return "The following permissions are required: 'edit terms in camelids' OR 'administer taxonomy'."; | |
339 | |
340 case 'DELETE': | |
341 return "The following permissions are required: 'delete terms in camelids' OR 'administer taxonomy'."; | |
342 | |
343 default: | |
344 return parent::getExpectedUnauthorizedAccessMessage($method); | |
345 } | |
346 } | |
347 | |
348 /** | |
349 * {@inheritdoc} | |
350 */ | |
351 protected function getExpectedUnauthorizedAccessCacheability() { | |
352 $cacheability = parent::getExpectedUnauthorizedAccessCacheability(); | |
353 $cacheability->addCacheableDependency($this->entity); | |
354 return $cacheability; | |
355 } | |
356 | |
357 /** | |
358 * Tests PATCHing a term's path. | |
359 * | |
360 * For a negative test, see the similar test coverage for Node. | |
361 * | |
362 * @see \Drupal\Tests\jsonapi\Functional\NodeTest::testPatchPath() | |
363 * @see \Drupal\Tests\rest\Functional\EntityResource\Node\NodeResourceTestBase::testPatchPath() | |
364 */ | |
365 public function testPatchPath() { | |
366 $this->setUpAuthorization('GET'); | |
367 $this->setUpAuthorization('PATCH'); | |
368 $this->config('jsonapi.settings')->set('read_only', FALSE)->save(TRUE); | |
369 | |
370 // @todo Remove line below in favor of commented line in https://www.drupal.org/project/jsonapi/issues/2878463. | |
371 $url = Url::fromRoute(sprintf('jsonapi.%s.individual', static::$resourceTypeName), ['entity' => $this->entity->uuid()]); | |
372 /* $url = $this->entity->toUrl('jsonapi'); */ | |
373 $request_options = []; | |
374 $request_options[RequestOptions::HEADERS]['Accept'] = 'application/vnd.api+json'; | |
375 $request_options[RequestOptions::HEADERS]['Content-Type'] = 'application/vnd.api+json'; | |
376 $request_options = NestedArray::mergeDeep($request_options, $this->getAuthenticationRequestOptions()); | |
377 | |
378 // GET term's current normalization. | |
379 $response = $this->request('GET', $url, $request_options); | |
380 $normalization = Json::decode((string) $response->getBody()); | |
381 | |
382 // Change term's path alias. | |
383 $normalization['data']['attributes']['path']['alias'] .= 's-rule-the-world'; | |
384 | |
385 // Create term PATCH request. | |
386 $request_options[RequestOptions::BODY] = Json::encode($normalization); | |
387 | |
388 // PATCH request: 200. | |
389 $response = $this->request('PATCH', $url, $request_options); | |
390 $this->assertResourceResponse(200, FALSE, $response); | |
391 $updated_normalization = Json::decode((string) $response->getBody()); | |
392 $this->assertSame($normalization['data']['attributes']['path']['alias'], $updated_normalization['data']['attributes']['path']['alias']); | |
393 } | |
394 | |
395 /** | |
396 * {@inheritdoc} | |
397 */ | |
398 protected function getExpectedCacheTags(array $sparse_fieldset = NULL) { | |
399 $tags = parent::getExpectedCacheTags($sparse_fieldset); | |
400 if ($sparse_fieldset === NULL || in_array('description', $sparse_fieldset)) { | |
401 $tags = Cache::mergeTags($tags, ['config:filter.format.plain_text', 'config:filter.settings']); | |
402 } | |
403 return $tags; | |
404 } | |
405 | |
406 /** | |
407 * {@inheritdoc} | |
408 */ | |
409 protected function getExpectedCacheContexts(array $sparse_fieldset = NULL) { | |
410 $contexts = parent::getExpectedCacheContexts($sparse_fieldset); | |
411 if ($sparse_fieldset === NULL || in_array('description', $sparse_fieldset)) { | |
412 $contexts = Cache::mergeContexts($contexts, ['languages:language_interface', 'theme']); | |
413 } | |
414 return $contexts; | |
415 } | |
416 | |
417 /** | |
418 * Tests GETting a term with a parent term other than the default <root> (0). | |
419 * | |
420 * @see ::getExpectedNormalizedEntity() | |
421 * | |
422 * @dataProvider providerTestGetIndividualTermWithParent | |
423 */ | |
424 public function testGetIndividualTermWithParent(array $parent_term_ids) { | |
425 // Create all possible parent terms. | |
426 Term::create(['vid' => Vocabulary::load('camelids')->id()]) | |
427 ->setName('Lamoids') | |
428 ->save(); | |
429 Term::create(['vid' => Vocabulary::load('camelids')->id()]) | |
430 ->setName('Wimoids') | |
431 ->save(); | |
432 | |
433 // Modify the entity under test to use the provided parent terms. | |
434 $this->entity->set('parent', $parent_term_ids)->save(); | |
435 | |
436 // @todo Remove line below in favor of commented line in https://www.drupal.org/project/jsonapi/issues/2878463. | |
437 $url = Url::fromRoute(sprintf('jsonapi.%s.individual', static::$resourceTypeName), ['entity' => $this->entity->uuid()]); | |
438 /* $url = $this->entity->toUrl('jsonapi'); */ | |
439 $request_options = []; | |
440 $request_options[RequestOptions::HEADERS]['Accept'] = 'application/vnd.api+json'; | |
441 $request_options = NestedArray::mergeDeep($request_options, $this->getAuthenticationRequestOptions()); | |
442 $this->setUpAuthorization('GET'); | |
443 $response = $this->request('GET', $url, $request_options); | |
444 $this->assertSameDocument($this->getExpectedDocument(), Json::decode($response->getBody())); | |
445 } | |
446 | |
447 /** | |
448 * Data provider for ::testGetIndividualTermWithParent(). | |
449 */ | |
450 public function providerTestGetIndividualTermWithParent() { | |
451 return [ | |
452 'root parent: [0] (= no parent)' => [ | |
453 [0], | |
454 ], | |
455 'non-root parent: [2]' => [ | |
456 [2], | |
457 ], | |
458 'multiple parents: [0,2] (root + non-root parent)' => [ | |
459 [0, 2], | |
460 ], | |
461 'multiple parents: [3,2] (both non-root parents)' => [ | |
462 [3, 2], | |
463 ], | |
464 ]; | |
465 } | |
466 | |
467 /** | |
468 * {@inheritdoc} | |
469 */ | |
470 public function testRelated() { | |
471 $this->markTestSkipped('Remove this in https://www.drupal.org/project/jsonapi/issues/2940339'); | |
472 } | |
473 | |
474 /** | |
475 * {@inheritdoc} | |
476 */ | |
477 public function testCollectionFilterAccess() { | |
478 $this->doTestCollectionFilterAccessBasedOnPermissions('name', 'access content'); | |
479 } | |
480 | |
481 } |