comparison core/modules/jsonapi/tests/src/Functional/FileTest.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\Url;
8 use Drupal\file\Entity\File;
9 use Drupal\Tests\jsonapi\Traits\CommonCollectionFilterAccessTestPatternsTrait;
10 use Drupal\Tests\rest\Functional\BcTimestampNormalizerUnixTestTrait;
11 use Drupal\user\Entity\User;
12 use GuzzleHttp\RequestOptions;
13
14 /**
15 * JSON:API integration test for the "File" content entity type.
16 *
17 * @group jsonapi
18 */
19 class FileTest extends ResourceTestBase {
20
21 use BcTimestampNormalizerUnixTestTrait;
22 use CommonCollectionFilterAccessTestPatternsTrait;
23
24 /**
25 * {@inheritdoc}
26 */
27 public static $modules = ['file', 'user'];
28
29 /**
30 * {@inheritdoc}
31 */
32 protected static $entityTypeId = 'file';
33
34 /**
35 * {@inheritdoc}
36 */
37 protected static $resourceTypeName = 'file--file';
38
39 /**
40 * {@inheritdoc}
41 *
42 * @var \Drupal\file\FileInterface
43 */
44 protected $entity;
45
46 /**
47 * {@inheritdoc}
48 */
49 protected static $patchProtectedFieldNames = [
50 'uri' => NULL,
51 'filemime' => NULL,
52 'filesize' => NULL,
53 'status' => NULL,
54 'changed' => NULL,
55 ];
56
57 /**
58 * The file author.
59 *
60 * @var \Drupal\user\UserInterface
61 */
62 protected $author;
63
64 /**
65 * {@inheritdoc}
66 */
67 protected function setUpAuthorization($method) {
68 switch ($method) {
69 case 'GET':
70 $this->grantPermissionsToTestedRole(['access content']);
71 break;
72
73 case 'PATCH':
74 case 'DELETE':
75 // \Drupal\file\FileAccessControlHandler::checkAccess() grants 'update'
76 // and 'delete' access only to the user that owns the file. So there is
77 // no permission to grant: instead, the file owner must be changed from
78 // its default (user 1) to the current user.
79 $this->makeCurrentUserFileOwner();
80 break;
81 }
82 }
83
84 /**
85 * Makes the current user the file owner.
86 */
87 protected function makeCurrentUserFileOwner() {
88 $account = User::load(2);
89 $this->entity->setOwnerId($account->id());
90 $this->entity->setOwner($account);
91 $this->entity->save();
92 }
93
94 /**
95 * {@inheritdoc}
96 */
97 protected function createEntity() {
98 $this->author = User::load(1);
99
100 $file = File::create();
101 $file->setOwnerId($this->author->id());
102 $file->setFilename('drupal.txt');
103 $file->setMimeType('text/plain');
104 $file->setFileUri('public://drupal.txt');
105 $file->set('status', FILE_STATUS_PERMANENT);
106 $file->save();
107
108 file_put_contents($file->getFileUri(), 'Drupal');
109
110 return $file;
111 }
112
113 /**
114 * {@inheritdoc}
115 */
116 protected function createAnotherEntity($key) {
117 /* @var \Drupal\file\FileInterface $duplicate */
118 $duplicate = parent::createAnotherEntity($key);
119 $duplicate->setFileUri("public://$key.txt");
120 $duplicate->save();
121 return $duplicate;
122 }
123
124 /**
125 * {@inheritdoc}
126 */
127 protected function getExpectedDocument() {
128 $self_url = Url::fromUri('base:/jsonapi/file/file/' . $this->entity->uuid())->setAbsolute()->toString(TRUE)->getGeneratedUrl();
129 return [
130 'jsonapi' => [
131 'meta' => [
132 'links' => [
133 'self' => ['href' => 'http://jsonapi.org/format/1.0/'],
134 ],
135 ],
136 'version' => '1.0',
137 ],
138 'links' => [
139 'self' => ['href' => $self_url],
140 ],
141 'data' => [
142 'id' => $this->entity->uuid(),
143 'type' => 'file--file',
144 'links' => [
145 'self' => ['href' => $self_url],
146 ],
147 'attributes' => [
148 'created' => (new \DateTime())->setTimestamp($this->entity->getCreatedTime())->setTimezone(new \DateTimeZone('UTC'))->format(\DateTime::RFC3339),
149 'changed' => (new \DateTime())->setTimestamp($this->entity->getChangedTime())->setTimezone(new \DateTimeZone('UTC'))->format(\DateTime::RFC3339),
150 'filemime' => 'text/plain',
151 'filename' => 'drupal.txt',
152 'filesize' => (int) $this->entity->getSize(),
153 'langcode' => 'en',
154 'status' => TRUE,
155 'uri' => [
156 'url' => base_path() . $this->siteDirectory . '/files/drupal.txt',
157 'value' => 'public://drupal.txt',
158 ],
159 'drupal_internal__fid' => 1,
160 ],
161 'relationships' => [
162 'uid' => [
163 'data' => [
164 'id' => $this->author->uuid(),
165 'type' => 'user--user',
166 ],
167 'links' => [
168 'related' => ['href' => $self_url . '/uid'],
169 'self' => ['href' => $self_url . '/relationships/uid'],
170 ],
171 ],
172 ],
173 ],
174 ];
175 }
176
177 /**
178 * {@inheritdoc}
179 */
180 protected function getPostDocument() {
181 return [
182 'data' => [
183 'type' => 'file--file',
184 'attributes' => [
185 'filename' => 'drupal.txt',
186 ],
187 ],
188 ];
189 }
190
191 /**
192 * {@inheritdoc}
193 */
194 public function testPostIndividual() {
195 // @todo https://www.drupal.org/node/1927648
196 $this->markTestSkipped();
197 }
198
199 /**
200 * {@inheritdoc}
201 */
202 protected function getExpectedUnauthorizedAccessMessage($method) {
203 if ($method === 'GET') {
204 return "The 'access content' permission is required.";
205 }
206 if ($method === 'PATCH' || $method === 'DELETE') {
207 return "Only the file owner can update or delete the file entity.";
208 }
209 return parent::getExpectedUnauthorizedAccessMessage($method);
210 }
211
212 /**
213 * {@inheritdoc}
214 */
215 public function testCollectionFilterAccess() {
216 $label_field_name = 'filename';
217 // Verify the expected behavior in the common case: when the file is public.
218 $this->doTestCollectionFilterAccessBasedOnPermissions($label_field_name, 'access content');
219
220 $collection_url = Url::fromRoute('jsonapi.entity_test--bar.collection');
221 $collection_filter_url = $collection_url->setOption('query', ["filter[spotlight.$label_field_name]" => $this->entity->label()]);
222 $request_options = [];
223 $request_options[RequestOptions::HEADERS]['Accept'] = 'application/vnd.api+json';
224 $request_options = NestedArray::mergeDeep($request_options, $this->getAuthenticationRequestOptions());
225
226 // 1 result because the current user is the file owner, even though the file
227 // is private.
228 $this->entity->setFileUri('private://drupal.txt');
229 $this->entity->setOwner($this->account);
230 $this->entity->save();
231 $response = $this->request('GET', $collection_filter_url, $request_options);
232 $doc = Json::decode((string) $response->getBody());
233 $this->assertCount(1, $doc['data']);
234
235 // 0 results because the current user is no longer the file owner and the
236 // file is private.
237 $this->entity->setOwner(User::load(0));
238 $this->entity->save();
239 $response = $this->request('GET', $collection_filter_url, $request_options);
240 $doc = Json::decode((string) $response->getBody());
241 $this->assertCount(0, $doc['data']);
242 }
243
244 }