annotate core/modules/jsonapi/tests/src/Functional/FileTest.php @ 19:fa3358dc1485 tip

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