Chris@18
|
1 <?php
|
Chris@18
|
2
|
Chris@18
|
3 namespace Drupal\Tests\jsonapi\Functional;
|
Chris@18
|
4
|
Chris@18
|
5 use Drupal\Core\Entity\EntityInterface;
|
Chris@18
|
6 use Drupal\Core\Url;
|
Chris@18
|
7 use Drupal\file\Entity\File;
|
Chris@18
|
8 use Drupal\media\Entity\Media;
|
Chris@18
|
9 use Drupal\media\Entity\MediaType;
|
Chris@18
|
10 use Drupal\Tests\jsonapi\Traits\CommonCollectionFilterAccessTestPatternsTrait;
|
Chris@18
|
11 use Drupal\user\Entity\User;
|
Chris@18
|
12
|
Chris@18
|
13 /**
|
Chris@18
|
14 * JSON:API integration test for the "Media" content entity type.
|
Chris@18
|
15 *
|
Chris@18
|
16 * @group jsonapi
|
Chris@18
|
17 */
|
Chris@18
|
18 class MediaTest extends ResourceTestBase {
|
Chris@18
|
19
|
Chris@18
|
20 use CommonCollectionFilterAccessTestPatternsTrait;
|
Chris@18
|
21
|
Chris@18
|
22 /**
|
Chris@18
|
23 * {@inheritdoc}
|
Chris@18
|
24 */
|
Chris@18
|
25 public static $modules = ['media'];
|
Chris@18
|
26
|
Chris@18
|
27 /**
|
Chris@18
|
28 * {@inheritdoc}
|
Chris@18
|
29 */
|
Chris@18
|
30 protected static $entityTypeId = 'media';
|
Chris@18
|
31
|
Chris@18
|
32 /**
|
Chris@18
|
33 * {@inheritdoc}
|
Chris@18
|
34 */
|
Chris@18
|
35 protected static $resourceTypeName = 'media--camelids';
|
Chris@18
|
36
|
Chris@18
|
37 /**
|
Chris@18
|
38 * {@inheritdoc}
|
Chris@18
|
39 */
|
Chris@18
|
40 protected static $resourceTypeIsVersionable = TRUE;
|
Chris@18
|
41
|
Chris@18
|
42 /**
|
Chris@18
|
43 * {@inheritdoc}
|
Chris@18
|
44 *
|
Chris@18
|
45 * @var \Drupal\media\MediaInterface
|
Chris@18
|
46 */
|
Chris@18
|
47 protected $entity;
|
Chris@18
|
48
|
Chris@18
|
49 /**
|
Chris@18
|
50 * {@inheritdoc}
|
Chris@18
|
51 */
|
Chris@18
|
52 protected static $patchProtectedFieldNames = [
|
Chris@18
|
53 'changed' => NULL,
|
Chris@18
|
54 ];
|
Chris@18
|
55
|
Chris@18
|
56 /**
|
Chris@18
|
57 * {@inheritdoc}
|
Chris@18
|
58 */
|
Chris@18
|
59 protected function setUpAuthorization($method) {
|
Chris@18
|
60 switch ($method) {
|
Chris@18
|
61 case 'GET':
|
Chris@18
|
62 $this->grantPermissionsToTestedRole(['view media']);
|
Chris@18
|
63 break;
|
Chris@18
|
64
|
Chris@18
|
65 case 'POST':
|
Chris@18
|
66 $this->grantPermissionsToTestedRole(['create camelids media', 'access content']);
|
Chris@18
|
67 break;
|
Chris@18
|
68
|
Chris@18
|
69 case 'PATCH':
|
Chris@18
|
70 $this->grantPermissionsToTestedRole(['edit any camelids media']);
|
Chris@18
|
71 // @todo Remove this in https://www.drupal.org/node/2824851.
|
Chris@18
|
72 $this->grantPermissionsToTestedRole(['access content']);
|
Chris@18
|
73 break;
|
Chris@18
|
74
|
Chris@18
|
75 case 'DELETE':
|
Chris@18
|
76 $this->grantPermissionsToTestedRole(['delete any camelids media']);
|
Chris@18
|
77 break;
|
Chris@18
|
78 }
|
Chris@18
|
79 }
|
Chris@18
|
80
|
Chris@18
|
81 /**
|
Chris@18
|
82 * {@inheritdoc}
|
Chris@18
|
83 */
|
Chris@18
|
84 protected function setUpRevisionAuthorization($method) {
|
Chris@18
|
85 parent::setUpRevisionAuthorization($method);
|
Chris@18
|
86 $this->grantPermissionsToTestedRole(['view all media revisions']);
|
Chris@18
|
87 }
|
Chris@18
|
88
|
Chris@18
|
89 /**
|
Chris@18
|
90 * {@inheritdoc}
|
Chris@18
|
91 */
|
Chris@18
|
92 protected function createEntity() {
|
Chris@18
|
93 if (!MediaType::load('camelids')) {
|
Chris@18
|
94 // Create a "Camelids" media type.
|
Chris@18
|
95 $media_type = MediaType::create([
|
Chris@18
|
96 'name' => 'Camelids',
|
Chris@18
|
97 'id' => 'camelids',
|
Chris@18
|
98 'description' => 'Camelids are large, strictly herbivorous animals with slender necks and long legs.',
|
Chris@18
|
99 'source' => 'file',
|
Chris@18
|
100 ]);
|
Chris@18
|
101 $media_type->save();
|
Chris@18
|
102 // Create the source field.
|
Chris@18
|
103 $source_field = $media_type->getSource()->createSourceField($media_type);
|
Chris@18
|
104 $source_field->getFieldStorageDefinition()->save();
|
Chris@18
|
105 $source_field->save();
|
Chris@18
|
106 $media_type
|
Chris@18
|
107 ->set('source_configuration', [
|
Chris@18
|
108 'source_field' => $source_field->getName(),
|
Chris@18
|
109 ])
|
Chris@18
|
110 ->save();
|
Chris@18
|
111 }
|
Chris@18
|
112
|
Chris@18
|
113 // Create a file to upload.
|
Chris@18
|
114 $file = File::create([
|
Chris@18
|
115 'uri' => 'public://llama.txt',
|
Chris@18
|
116 ]);
|
Chris@18
|
117 $file->setPermanent();
|
Chris@18
|
118 $file->save();
|
Chris@18
|
119
|
Chris@18
|
120 // @see \Drupal\Tests\jsonapi\Functional\MediaTest::testPostIndividual()
|
Chris@18
|
121 $post_file = File::create([
|
Chris@18
|
122 'uri' => 'public://llama2.txt',
|
Chris@18
|
123 ]);
|
Chris@18
|
124 $post_file->setPermanent();
|
Chris@18
|
125 $post_file->save();
|
Chris@18
|
126
|
Chris@18
|
127 // Create a "Llama" media item.
|
Chris@18
|
128 $media = Media::create([
|
Chris@18
|
129 'bundle' => 'camelids',
|
Chris@18
|
130 'field_media_file' => [
|
Chris@18
|
131 'target_id' => $file->id(),
|
Chris@18
|
132 ],
|
Chris@18
|
133 ]);
|
Chris@18
|
134 $media
|
Chris@18
|
135 ->setName('Llama')
|
Chris@18
|
136 ->setPublished()
|
Chris@18
|
137 ->setCreatedTime(123456789)
|
Chris@18
|
138 ->setOwnerId($this->account->id())
|
Chris@18
|
139 ->setRevisionUserId($this->account->id())
|
Chris@18
|
140 ->save();
|
Chris@18
|
141
|
Chris@18
|
142 return $media;
|
Chris@18
|
143 }
|
Chris@18
|
144
|
Chris@18
|
145 /**
|
Chris@18
|
146 * {@inheritdoc}
|
Chris@18
|
147 */
|
Chris@18
|
148 protected function getExpectedDocument() {
|
Chris@18
|
149 $file = File::load(1);
|
Chris@18
|
150 $thumbnail = File::load(3);
|
Chris@18
|
151 $author = User::load($this->entity->getOwnerId());
|
Chris@18
|
152 $base_url = Url::fromUri('base:/jsonapi/media/camelids/' . $this->entity->uuid())->setAbsolute();
|
Chris@18
|
153 $self_url = clone $base_url;
|
Chris@18
|
154 $version_identifier = 'id:' . $this->entity->getRevisionId();
|
Chris@18
|
155 $self_url = $self_url->setOption('query', ['resourceVersion' => $version_identifier]);
|
Chris@18
|
156 $version_query_string = '?resourceVersion=' . urlencode($version_identifier);
|
Chris@18
|
157 return [
|
Chris@18
|
158 'jsonapi' => [
|
Chris@18
|
159 'meta' => [
|
Chris@18
|
160 'links' => [
|
Chris@18
|
161 'self' => ['href' => 'http://jsonapi.org/format/1.0/'],
|
Chris@18
|
162 ],
|
Chris@18
|
163 ],
|
Chris@18
|
164 'version' => '1.0',
|
Chris@18
|
165 ],
|
Chris@18
|
166 'links' => [
|
Chris@18
|
167 'self' => ['href' => $base_url->toString()],
|
Chris@18
|
168 ],
|
Chris@18
|
169 'data' => [
|
Chris@18
|
170 'id' => $this->entity->uuid(),
|
Chris@18
|
171 'type' => 'media--camelids',
|
Chris@18
|
172 'links' => [
|
Chris@18
|
173 'self' => ['href' => $self_url->toString()],
|
Chris@18
|
174 ],
|
Chris@18
|
175 'attributes' => [
|
Chris@18
|
176 'langcode' => 'en',
|
Chris@18
|
177 'name' => 'Llama',
|
Chris@18
|
178 'status' => TRUE,
|
Chris@18
|
179 'created' => '1973-11-29T21:33:09+00:00',
|
Chris@18
|
180 'changed' => (new \DateTime())->setTimestamp($this->entity->getChangedTime())->setTimezone(new \DateTimeZone('UTC'))->format(\DateTime::RFC3339),
|
Chris@18
|
181 'revision_created' => (new \DateTime())->setTimestamp($this->entity->getRevisionCreationTime())->setTimezone(new \DateTimeZone('UTC'))->format(\DateTime::RFC3339),
|
Chris@18
|
182 'default_langcode' => TRUE,
|
Chris@18
|
183 'revision_log_message' => NULL,
|
Chris@18
|
184 // @todo Attempt to remove this in https://www.drupal.org/project/drupal/issues/2933518.
|
Chris@18
|
185 'revision_translation_affected' => TRUE,
|
Chris@18
|
186 'drupal_internal__mid' => 1,
|
Chris@18
|
187 'drupal_internal__vid' => 1,
|
Chris@18
|
188 ],
|
Chris@18
|
189 'relationships' => [
|
Chris@18
|
190 'field_media_file' => [
|
Chris@18
|
191 'data' => [
|
Chris@18
|
192 'id' => $file->uuid(),
|
Chris@18
|
193 'meta' => [
|
Chris@18
|
194 'description' => NULL,
|
Chris@18
|
195 'display' => NULL,
|
Chris@18
|
196 ],
|
Chris@18
|
197 'type' => 'file--file',
|
Chris@18
|
198 ],
|
Chris@18
|
199 'links' => [
|
Chris@18
|
200 'related' => [
|
Chris@18
|
201 'href' => $base_url->toString() . '/field_media_file' . $version_query_string,
|
Chris@18
|
202 ],
|
Chris@18
|
203 'self' => [
|
Chris@18
|
204 'href' => $base_url->toString() . '/relationships/field_media_file' . $version_query_string,
|
Chris@18
|
205 ],
|
Chris@18
|
206 ],
|
Chris@18
|
207 ],
|
Chris@18
|
208 'thumbnail' => [
|
Chris@18
|
209 'data' => [
|
Chris@18
|
210 'id' => $thumbnail->uuid(),
|
Chris@18
|
211 'meta' => [
|
Chris@18
|
212 'alt' => '',
|
Chris@18
|
213 'width' => 180,
|
Chris@18
|
214 'height' => 180,
|
Chris@18
|
215 'title' => NULL,
|
Chris@18
|
216 ],
|
Chris@18
|
217 'type' => 'file--file',
|
Chris@18
|
218 ],
|
Chris@18
|
219 'links' => [
|
Chris@18
|
220 'related' => [
|
Chris@18
|
221 'href' => $base_url->toString() . '/thumbnail' . $version_query_string,
|
Chris@18
|
222 ],
|
Chris@18
|
223 'self' => [
|
Chris@18
|
224 'href' => $base_url->toString() . '/relationships/thumbnail' . $version_query_string,
|
Chris@18
|
225 ],
|
Chris@18
|
226 ],
|
Chris@18
|
227 ],
|
Chris@18
|
228 'bundle' => [
|
Chris@18
|
229 'data' => [
|
Chris@18
|
230 'id' => MediaType::load('camelids')->uuid(),
|
Chris@18
|
231 'type' => 'media_type--media_type',
|
Chris@18
|
232 ],
|
Chris@18
|
233 'links' => [
|
Chris@18
|
234 'related' => [
|
Chris@18
|
235 'href' => $base_url->toString() . '/bundle' . $version_query_string,
|
Chris@18
|
236 ],
|
Chris@18
|
237 'self' => [
|
Chris@18
|
238 'href' => $base_url->toString() . '/relationships/bundle' . $version_query_string,
|
Chris@18
|
239 ],
|
Chris@18
|
240 ],
|
Chris@18
|
241 ],
|
Chris@18
|
242 'uid' => [
|
Chris@18
|
243 'data' => [
|
Chris@18
|
244 'id' => $author->uuid(),
|
Chris@18
|
245 'type' => 'user--user',
|
Chris@18
|
246 ],
|
Chris@18
|
247 'links' => [
|
Chris@18
|
248 'related' => [
|
Chris@18
|
249 'href' => $base_url->toString() . '/uid' . $version_query_string,
|
Chris@18
|
250 ],
|
Chris@18
|
251 'self' => [
|
Chris@18
|
252 'href' => $base_url->toString() . '/relationships/uid' . $version_query_string,
|
Chris@18
|
253 ],
|
Chris@18
|
254 ],
|
Chris@18
|
255 ],
|
Chris@18
|
256 'revision_user' => [
|
Chris@18
|
257 'data' => [
|
Chris@18
|
258 'id' => $author->uuid(),
|
Chris@18
|
259 'type' => 'user--user',
|
Chris@18
|
260 ],
|
Chris@18
|
261 'links' => [
|
Chris@18
|
262 'related' => [
|
Chris@18
|
263 'href' => $base_url->toString() . '/revision_user' . $version_query_string,
|
Chris@18
|
264 ],
|
Chris@18
|
265 'self' => [
|
Chris@18
|
266 'href' => $base_url->toString() . '/relationships/revision_user' . $version_query_string,
|
Chris@18
|
267 ],
|
Chris@18
|
268 ],
|
Chris@18
|
269 ],
|
Chris@18
|
270 ],
|
Chris@18
|
271 ],
|
Chris@18
|
272 ];
|
Chris@18
|
273 }
|
Chris@18
|
274
|
Chris@18
|
275 /**
|
Chris@18
|
276 * {@inheritdoc}
|
Chris@18
|
277 */
|
Chris@18
|
278 protected function getPostDocument() {
|
Chris@18
|
279 $file = File::load(2);
|
Chris@18
|
280 return [
|
Chris@18
|
281 'data' => [
|
Chris@18
|
282 'type' => 'media--camelids',
|
Chris@18
|
283 'attributes' => [
|
Chris@18
|
284 'name' => 'Dramallama',
|
Chris@18
|
285 ],
|
Chris@18
|
286 'relationships' => [
|
Chris@18
|
287 'field_media_file' => [
|
Chris@18
|
288 'data' => [
|
Chris@18
|
289 'id' => $file->uuid(),
|
Chris@18
|
290 'meta' => [
|
Chris@18
|
291 'description' => 'This file is better!',
|
Chris@18
|
292 'display' => NULL,
|
Chris@18
|
293 ],
|
Chris@18
|
294 'type' => 'file--file',
|
Chris@18
|
295 ],
|
Chris@18
|
296 ],
|
Chris@18
|
297 ],
|
Chris@18
|
298 ],
|
Chris@18
|
299 ];
|
Chris@18
|
300 }
|
Chris@18
|
301
|
Chris@18
|
302 /**
|
Chris@18
|
303 * {@inheritdoc}
|
Chris@18
|
304 */
|
Chris@18
|
305 protected function getExpectedUnauthorizedAccessMessage($method) {
|
Chris@18
|
306 switch ($method) {
|
Chris@18
|
307 case 'GET';
|
Chris@18
|
308 return "The 'view media' permission is required when the media item is published.";
|
Chris@18
|
309
|
Chris@18
|
310 case 'POST':
|
Chris@18
|
311 return "The following permissions are required: 'administer media' OR 'create media' OR 'create camelids media'.";
|
Chris@18
|
312
|
Chris@18
|
313 case 'PATCH':
|
Chris@18
|
314 return "The following permissions are required: 'update any media' OR 'update own media' OR 'camelids: edit any media' OR 'camelids: edit own media'.";
|
Chris@18
|
315
|
Chris@18
|
316 case 'DELETE':
|
Chris@18
|
317 return "The following permissions are required: 'delete any media' OR 'delete own media' OR 'camelids: delete any media' OR 'camelids: delete own media'.";
|
Chris@18
|
318
|
Chris@18
|
319 default:
|
Chris@18
|
320 return '';
|
Chris@18
|
321 }
|
Chris@18
|
322 }
|
Chris@18
|
323
|
Chris@18
|
324 /**
|
Chris@18
|
325 * {@inheritdoc}
|
Chris@18
|
326 */
|
Chris@18
|
327 protected function getEditorialPermissions() {
|
Chris@18
|
328 return array_merge(parent::getEditorialPermissions(), ['view any unpublished content']);
|
Chris@18
|
329 }
|
Chris@18
|
330
|
Chris@18
|
331 /**
|
Chris@18
|
332 * {@inheritdoc}
|
Chris@18
|
333 */
|
Chris@18
|
334 protected function getExpectedUnauthorizedAccessCacheability() {
|
Chris@18
|
335 // @see \Drupal\media\MediaAccessControlHandler::checkAccess()
|
Chris@18
|
336 return parent::getExpectedUnauthorizedAccessCacheability()
|
Chris@18
|
337 ->addCacheTags(['media:1']);
|
Chris@18
|
338 }
|
Chris@18
|
339
|
Chris@18
|
340 // @codingStandardsIgnoreStart
|
Chris@18
|
341 /**
|
Chris@18
|
342 * {@inheritdoc}
|
Chris@18
|
343 */
|
Chris@18
|
344 public function testPostIndividual() {
|
Chris@18
|
345 // @todo Mimic \Drupal\Tests\rest\Functional\EntityResource\Media\MediaResourceTestBase::testPost()
|
Chris@18
|
346 // @todo Later, use https://www.drupal.org/project/jsonapi/issues/2958554 to upload files rather than the REST module.
|
Chris@18
|
347 parent::testPostIndividual();
|
Chris@18
|
348 }
|
Chris@18
|
349 // @codingStandardsIgnoreEnd
|
Chris@18
|
350
|
Chris@18
|
351 /**
|
Chris@18
|
352 * {@inheritdoc}
|
Chris@18
|
353 *
|
Chris@18
|
354 * @todo Determine if this override should be removed in https://www.drupal.org/project/jsonapi/issues/2952522
|
Chris@18
|
355 */
|
Chris@18
|
356 protected function getExpectedGetRelationshipDocumentData($relationship_field_name, EntityInterface $entity = NULL) {
|
Chris@18
|
357 $data = parent::getExpectedGetRelationshipDocumentData($relationship_field_name, $entity);
|
Chris@18
|
358 switch ($relationship_field_name) {
|
Chris@18
|
359 case 'thumbnail':
|
Chris@18
|
360 $data['meta'] = [
|
Chris@18
|
361 'alt' => '',
|
Chris@18
|
362 'width' => 180,
|
Chris@18
|
363 'height' => 180,
|
Chris@18
|
364 'title' => NULL,
|
Chris@18
|
365 ];
|
Chris@18
|
366 return $data;
|
Chris@18
|
367
|
Chris@18
|
368 case 'field_media_file':
|
Chris@18
|
369 $data['meta'] = [
|
Chris@18
|
370 'description' => NULL,
|
Chris@18
|
371 'display' => NULL,
|
Chris@18
|
372 ];
|
Chris@18
|
373 return $data;
|
Chris@18
|
374
|
Chris@18
|
375 default:
|
Chris@18
|
376 return $data;
|
Chris@18
|
377 }
|
Chris@18
|
378 }
|
Chris@18
|
379
|
Chris@18
|
380 /**
|
Chris@18
|
381 * {@inheritdoc}
|
Chris@18
|
382 *
|
Chris@18
|
383 * @todo Remove this in https://www.drupal.org/node/2824851.
|
Chris@18
|
384 */
|
Chris@18
|
385 protected function doTestRelationshipMutation(array $request_options) {
|
Chris@18
|
386 $this->grantPermissionsToTestedRole(['access content']);
|
Chris@18
|
387 parent::doTestRelationshipMutation($request_options);
|
Chris@18
|
388 }
|
Chris@18
|
389
|
Chris@18
|
390 /**
|
Chris@18
|
391 * {@inheritdoc}
|
Chris@18
|
392 */
|
Chris@18
|
393 public function testCollectionFilterAccess() {
|
Chris@18
|
394 $this->doTestCollectionFilterAccessForPublishableEntities('name', 'view media', 'administer media');
|
Chris@18
|
395 }
|
Chris@18
|
396
|
Chris@18
|
397 }
|