 .../field/src/Tests/String/StringFieldTest.php     |   2 +-
 core/modules/file/src/FileAccessControlHandler.php |   8 +-
 .../tests/src/Functional/FileManagedAccessTest.php |  18 +-
 .../modules/file/tests/src/Kernel/FileItemTest.php |   9 +
 .../EntityResource/File/FileHalJsonAnonTest.php    | 103 ++++++++++
 .../File/FileHalJsonBasicAuthTest.php              |  24 +++
 .../EntityResource/File/FileHalJsonCookieTest.php  |  19 ++
 .../image/tests/src/Kernel/ImageItemTest.php       |   9 +
 .../EntityResourceRestTestCoverageTest.php         |   9 -
 .../EntityResource/File/FileJsonAnonTest.php       |  24 +++
 .../EntityResource/File/FileJsonBasicAuthTest.php  |  34 +++
 .../EntityResource/File/FileJsonCookieTest.php     |  29 +++
 .../EntityResource/File/FileResourceTestBase.php   | 227 +++++++++++++++++++++
 .../EntityResource/File/FileXmlAnonTest.php        |  26 +++
 .../EntityResource/File/FileXmlBasicAuthTest.php   |  36 ++++
 .../EntityResource/File/FileXmlCookieTest.php      |  31 +++
 .../EntityResource/Media/MediaResourceTestBase.php |   2 +
 17 files changed, 596 insertions(+), 14 deletions(-)

diff --git a/core/modules/field/src/Tests/String/StringFieldTest.php b/core/modules/field/src/Tests/String/StringFieldTest.php
index 97e470e..fdedb79 100644
--- a/core/modules/field/src/Tests/String/StringFieldTest.php
+++ b/core/modules/field/src/Tests/String/StringFieldTest.php
@@ -32,7 +32,7 @@ class StringFieldTest extends WebTestBase {
   protected function setUp() {
     parent::setUp();
 
-    $this->webUser = $this->drupalCreateUser(['view test entity', 'administer entity_test content']);
+    $this->webUser = $this->drupalCreateUser(['view test entity', 'administer entity_test content', 'access content']);
     $this->drupalLogin($this->webUser);
   }
 
diff --git a/core/modules/file/src/FileAccessControlHandler.php b/core/modules/file/src/FileAccessControlHandler.php
index f4bda3c..e378b64 100644
--- a/core/modules/file/src/FileAccessControlHandler.php
+++ b/core/modules/file/src/FileAccessControlHandler.php
@@ -22,8 +22,12 @@ protected function checkAccess(EntityInterface $entity, $operation, AccountInter
     /** @var \Drupal\file\FileInterface $entity */
     if ($operation == 'download' || $operation == 'view') {
       if (\Drupal::service('file_system')->uriScheme($entity->getFileUri()) === 'public') {
-        // Always allow access to file in public file system.
-        return AccessResult::allowed();
+        if ($operation === 'download') {
+          return AccessResult::allowed();
+        }
+        else {
+          return AccessResult::allowedIfHasPermission($account, 'access content');
+        }
       }
       elseif ($references = $this->getFileReferences($entity)) {
         foreach ($references as $field_name => $entity_map) {
diff --git a/core/modules/file/tests/src/Functional/FileManagedAccessTest.php b/core/modules/file/tests/src/Functional/FileManagedAccessTest.php
index 01419d4..c62b1cb 100644
--- a/core/modules/file/tests/src/Functional/FileManagedAccessTest.php
+++ b/core/modules/file/tests/src/Functional/FileManagedAccessTest.php
@@ -3,6 +3,7 @@
 namespace Drupal\Tests\file\Functional;
 
 use Drupal\file\Entity\File;
+use Drupal\user\Entity\Role;
 
 /**
  * Tests access to managed files.
@@ -12,6 +13,19 @@
 class FileManagedAccessTest extends FileManagedTestBase {
 
   /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    // Give anonymous users permission to access content, so they can view and
+    // download public files.
+    $anonymous_role = Role::load(Role::ANONYMOUS_ID);
+    $anonymous_role->grantPermission('access content');
+    $anonymous_role->save();
+  }
+
+  /**
    * Tests if public file is always accessible.
    */
   public function testFileAccess() {
@@ -29,7 +43,7 @@ public function testFileAccess() {
     $file->save();
 
     // Create authenticated user to check file access.
-    $account = $this->createUser(['access site reports']);
+    $account = $this->createUser(['access site reports', 'access content']);
 
     $this->assertTrue($file->access('view', $account), 'Public file is viewable to authenticated user');
     $this->assertTrue($file->access('download', $account), 'Public file is downloadable to authenticated user');
@@ -54,7 +68,7 @@ public function testFileAccess() {
     $file->save();
 
     // Create authenticated user to check file access.
-    $account = $this->createUser(['access site reports']);
+    $account = $this->createUser(['access site reports', 'access content']);
 
     $this->assertFalse($file->access('view', $account), 'Private file is not viewable to authenticated user');
     $this->assertFalse($file->access('download', $account), 'Private file is not downloadable to authenticated user');
diff --git a/core/modules/file/tests/src/Kernel/FileItemTest.php b/core/modules/file/tests/src/Kernel/FileItemTest.php
index 8219af1..ac6cd88 100644
--- a/core/modules/file/tests/src/Kernel/FileItemTest.php
+++ b/core/modules/file/tests/src/Kernel/FileItemTest.php
@@ -10,6 +10,7 @@
 use Drupal\Tests\field\Kernel\FieldKernelTestBase;
 use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\file\Entity\File;
+use Drupal\user\Entity\Role;
 
 /**
  * Tests using entity fields of the file field type.
@@ -42,6 +43,14 @@ class FileItemTest extends FieldKernelTestBase {
   protected function setUp() {
     parent::setUp();
 
+    $this->installEntitySchema('user');
+    $this->installConfig(['user']);
+    // Give anonymous users permission to access content, so they can view and
+    // download public files.
+    $anonymous_role = Role::load(Role::ANONYMOUS_ID);
+    $anonymous_role->grantPermission('access content');
+    $anonymous_role->save();
+
     $this->installEntitySchema('file');
     $this->installSchema('file', ['file_usage']);
 
diff --git a/core/modules/hal/tests/src/Functional/EntityResource/File/FileHalJsonAnonTest.php b/core/modules/hal/tests/src/Functional/EntityResource/File/FileHalJsonAnonTest.php
new file mode 100644
index 0000000..cfead8c
--- /dev/null
+++ b/core/modules/hal/tests/src/Functional/EntityResource/File/FileHalJsonAnonTest.php
@@ -0,0 +1,103 @@
+<?php
+
+namespace Drupal\Tests\hal\Functional\EntityResource\File;
+
+use Drupal\Tests\hal\Functional\EntityResource\HalEntityNormalizationTrait;
+use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
+use Drupal\Tests\rest\Functional\EntityResource\File\FileResourceTestBase;
+
+/**
+ * @group hal
+ */
+class FileHalJsonAnonTest extends FileResourceTestBase {
+
+  use HalEntityNormalizationTrait;
+  use AnonResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['hal'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'hal_json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'application/hal+json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getExpectedNormalizedEntity() {
+    $default_normalization = parent::getExpectedNormalizedEntity();
+
+    $normalization = $this->applyHalFieldNormalization($default_normalization);
+
+    $url = file_create_url($this->entity->getFileUri());
+    $normalization['uri'][0]['value'] = $url;
+    $uid = $this->author->id();
+
+    return $normalization + [
+      '_embedded' => [
+        $this->baseUrl . '/rest/relation/file/file/uid' => [
+          [
+            '_links' => [
+              'self' => [
+                'href' => $this->baseUrl . "/user/$uid?_format=hal_json",
+              ],
+              'type' => [
+                'href' => $this->baseUrl . '/rest/type/user/user',
+              ],
+            ],
+            'uuid' => [
+              [
+                'value' => $this->author->uuid(),
+              ],
+            ],
+          ],
+        ],
+      ],
+      '_links' => [
+        'self' => [
+          'href' => $url,
+        ],
+        'type' => [
+          'href' => $this->baseUrl . '/rest/type/file/file',
+        ],
+        $this->baseUrl . '/rest/relation/file/file/uid' => [
+          [
+            'href' => $this->baseUrl . "/user/$uid?_format=hal_json",
+          ],
+        ],
+      ],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getNormalizedPostEntity() {
+    return parent::getNormalizedPostEntity() + [
+      '_links' => [
+        'type' => [
+          'href' => $this->baseUrl . '/rest/type/file/file',
+        ],
+      ],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getExpectedCacheContexts() {
+    return [
+      'url.site',
+      'user.permissions',
+    ];
+  }
+
+}
diff --git a/core/modules/hal/tests/src/Functional/EntityResource/File/FileHalJsonBasicAuthTest.php b/core/modules/hal/tests/src/Functional/EntityResource/File/FileHalJsonBasicAuthTest.php
new file mode 100644
index 0000000..3b1e3fe
--- /dev/null
+++ b/core/modules/hal/tests/src/Functional/EntityResource/File/FileHalJsonBasicAuthTest.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace Drupal\Tests\hal\Functional\EntityResource\File;
+
+use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
+
+/**
+ * @group hal
+ */
+class FileHalJsonBasicAuthTest extends FileHalJsonAnonTest {
+
+  use BasicAuthResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['basic_auth'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $auth = 'basic_auth';
+
+}
diff --git a/core/modules/hal/tests/src/Functional/EntityResource/File/FileHalJsonCookieTest.php b/core/modules/hal/tests/src/Functional/EntityResource/File/FileHalJsonCookieTest.php
new file mode 100644
index 0000000..8d62372
--- /dev/null
+++ b/core/modules/hal/tests/src/Functional/EntityResource/File/FileHalJsonCookieTest.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace Drupal\Tests\hal\Functional\EntityResource\File;
+
+use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
+
+/**
+ * @group hal
+ */
+class FileHalJsonCookieTest extends FileHalJsonAnonTest {
+
+  use CookieResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $auth = 'cookie';
+
+}
diff --git a/core/modules/image/tests/src/Kernel/ImageItemTest.php b/core/modules/image/tests/src/Kernel/ImageItemTest.php
index 951d190..45d9d03 100644
--- a/core/modules/image/tests/src/Kernel/ImageItemTest.php
+++ b/core/modules/image/tests/src/Kernel/ImageItemTest.php
@@ -11,6 +11,7 @@
 use Drupal\Tests\field\Kernel\FieldKernelTestBase;
 use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\file\Entity\File;
+use Drupal\user\Entity\Role;
 
 /**
  * Tests using entity fields of the image field type.
@@ -41,6 +42,14 @@ class ImageItemTest extends FieldKernelTestBase {
   protected function setUp() {
     parent::setUp();
 
+    $this->installEntitySchema('user');
+    $this->installConfig(['user']);
+    // Give anonymous users permission to access content, so that we can view
+    // and download public file.
+    $anonymous_role = Role::load(Role::ANONYMOUS_ID);
+    $anonymous_role->grantPermission('access content');
+    $anonymous_role->save();
+
     $this->installEntitySchema('file');
     $this->installSchema('file', ['file_usage']);
 
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceRestTestCoverageTest.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceRestTestCoverageTest.php
index e26ecd2..d10d55c 100644
--- a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceRestTestCoverageTest.php
+++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceRestTestCoverageTest.php
@@ -124,15 +124,6 @@ public function testEntityTypeRestTestCoverage() {
     }
     $all = count($this->definitions);
     $good = $all - count($problems);
-    // @todo Remove this in https://www.drupal.org/node/2843139. Having this
-    // work-around in here until then means we can ensure we don't add more
-    // entity types without adding REST test coverage.
-    if ($problems === ['file: File (Drupal\file\Entity\File), default normalization (expected tests: FileJsonAnonTest, FileJsonBasicAuthTest, FileJsonCookieTest, FileXmlAnonTest, FileXmlBasicAuthTest, FileXmlCookieTest)', 'file: File (Drupal\file\Entity\File), hal normalization (expected tests: FileHalJsonAnonTest, FileHalJsonBasicAuthTest, FileHalJsonCookieTest)']) {
-      $problems = [];
-    }
-    elseif ($problems === []) {
-      $this->fail('Drupal\file\Entity\File now supports REST test coverage. The work-around for it to pass until that test coverage was added should now be removed.');
-    }
     $this->assertSame([], $problems, $this->getLlamaMessage($good, $all));
   }
 
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/File/FileJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/File/FileJsonAnonTest.php
new file mode 100644
index 0000000..b3adf6e
--- /dev/null
+++ b/core/modules/rest/tests/src/Functional/EntityResource/File/FileJsonAnonTest.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace Drupal\Tests\rest\Functional\EntityResource\File;
+
+use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
+
+/**
+ * @group rest
+ */
+class FileJsonAnonTest extends FileResourceTestBase {
+
+  use AnonResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'application/json';
+
+}
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/File/FileJsonBasicAuthTest.php b/core/modules/rest/tests/src/Functional/EntityResource/File/FileJsonBasicAuthTest.php
new file mode 100644
index 0000000..971555c
--- /dev/null
+++ b/core/modules/rest/tests/src/Functional/EntityResource/File/FileJsonBasicAuthTest.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace Drupal\Tests\rest\Functional\EntityResource\File;
+
+use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
+
+/**
+ * @group rest
+ */
+class FileJsonBasicAuthTest extends FileResourceTestBase {
+
+  use BasicAuthResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['basic_auth'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'application/json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $auth = 'basic_auth';
+
+}
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/File/FileJsonCookieTest.php b/core/modules/rest/tests/src/Functional/EntityResource/File/FileJsonCookieTest.php
new file mode 100644
index 0000000..cffd869
--- /dev/null
+++ b/core/modules/rest/tests/src/Functional/EntityResource/File/FileJsonCookieTest.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Drupal\Tests\rest\Functional\EntityResource\File;
+
+use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
+
+/**
+ * @group rest
+ */
+class FileJsonCookieTest extends FileResourceTestBase {
+
+  use CookieResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'application/json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $auth = 'cookie';
+
+}
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/File/FileResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/File/FileResourceTestBase.php
new file mode 100644
index 0000000..c63853e
--- /dev/null
+++ b/core/modules/rest/tests/src/Functional/EntityResource/File/FileResourceTestBase.php
@@ -0,0 +1,227 @@
+<?php
+
+namespace Drupal\Tests\rest\Functional\EntityResource\File;
+
+use Drupal\file\Entity\File;
+use Drupal\Tests\rest\Functional\BcTimestampNormalizerUnixTestTrait;
+use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
+use Drupal\user\Entity\User;
+
+abstract class FileResourceTestBase extends EntityResourceTestBase {
+
+  use BcTimestampNormalizerUnixTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['file', 'user'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $entityTypeId = 'file';
+
+  /**
+   * @var \Drupal\file\FileInterface
+   */
+  protected $entity;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $patchProtectedFieldNames = [
+    'uri',
+    'filemime',
+    'filesize',
+    'status',
+    'changed',
+  ];
+
+  /**
+   * @var \Drupal\user\UserInterface
+   */
+  protected $author;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUpAuthorization($method) {
+    switch ($method) {
+      case 'GET':
+        $this->grantPermissionsToTestedRole(['access content']);
+        break;
+
+      case 'PATCH':
+      case 'DELETE':
+        // \Drupal\file\FileAccessControlHandler::checkAccess() grants 'update'
+        // and 'delete' access only to the user that owns the file. So there is
+        // no permission to grant: instead, the file owner must be changed from
+        // its default (user 1) to the current user.
+        $this->makeCurrentUserFileOwner();
+        break;
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function grantPermissionsToTestedRole(array $permissions) {
+    // testPatch() and testDelete() test the 'bc_entity_resource_permissions' BC
+    // layer; also call makeCurrentUserFileOwner() then.
+    if ($permissions === ['restful patch entity:file'] || $permissions === ['restful delete entity:file']) {
+      $this->makeCurrentUserFileOwner();
+    }
+    parent::grantPermissionsToTestedRole($permissions);
+  }
+
+  /**
+   * Makes the current user the file owner.
+   */
+  protected function makeCurrentUserFileOwner() {
+    $account = static::$auth ? User::load(2) : User::load(0);
+    $this->entity->setOwnerId($account->id());
+    $this->entity->setOwner($account);
+    $this->entity->save();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function createEntity() {
+    $this->author = User::load(1);
+
+    $file = File::create();
+    $file->setOwnerId($this->author->id());
+    $file->setFilename('drupal.txt');
+    $file->setMimeType('text/plain');
+    $file->setFileUri('public://drupal.txt');
+    $file->set('status', FILE_STATUS_PERMANENT);
+    $file->save();
+
+    file_put_contents($file->getFileUri(), 'Drupal');
+
+    return $file;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getExpectedNormalizedEntity() {
+    return [
+      'changed' => [
+        $this->formatExpectedTimestampItemValues($this->entity->getChangedTime()),
+      ],
+      'created' => [
+        $this->formatExpectedTimestampItemValues((int) $this->entity->getCreatedTime()),
+      ],
+      'fid' => [
+        [
+          'value' => 1,
+        ],
+      ],
+      'filemime' => [
+        [
+          'value' => 'text/plain',
+        ],
+      ],
+      'filename' => [
+        [
+          'value' => 'drupal.txt',
+        ],
+      ],
+      'filesize' => [
+        [
+          'value' => (int) $this->entity->getSize(),
+        ],
+      ],
+      'langcode' => [
+        [
+          'value' => 'en',
+        ],
+      ],
+      'status' => [
+        [
+          'value' => TRUE,
+        ],
+      ],
+      'uid' => [
+        [
+          'target_id' => (int) $this->author->id(),
+          'target_type' => 'user',
+          'target_uuid' => $this->author->uuid(),
+          'url' => base_path() . 'user/' . $this->author->id(),
+        ],
+      ],
+      'uri' => [
+        [
+          'value' => 'public://drupal.txt',
+        ],
+      ],
+      'uuid' => [
+        [
+          'value' => $this->entity->uuid(),
+        ],
+      ],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getNormalizedPostEntity() {
+    return [
+      'uid' => [
+        [
+          'target_id' => $this->author->id(),
+        ],
+      ],
+      'filename' => [
+        [
+          'value' => 'drupal.txt',
+        ],
+      ],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getNormalizedPatchEntity() {
+    return array_diff_key($this->getNormalizedPostEntity(), ['uid' => TRUE]);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getExpectedCacheContexts() {
+    return [
+      'user.permissions',
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function testPost() {
+    // @todo https://www.drupal.org/node/1927648
+    $this->markTestSkipped();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getExpectedUnauthorizedAccessMessage($method) {
+    if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) {
+      return parent::getExpectedUnauthorizedAccessMessage($method);
+    }
+
+    if ($method === 'GET') {
+      return "The 'access content' permission is required.";
+    }
+    if ($method === 'PATCH') {
+      return 'You are not authorized to update this file entity.';
+    }
+    return parent::getExpectedUnauthorizedAccessMessage($method);
+  }
+
+}
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/File/FileXmlAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/File/FileXmlAnonTest.php
new file mode 100644
index 0000000..2fad087
--- /dev/null
+++ b/core/modules/rest/tests/src/Functional/EntityResource/File/FileXmlAnonTest.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace Drupal\Tests\rest\Functional\EntityResource\File;
+
+use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
+use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
+
+/**
+ * @group rest
+ */
+class FileXmlAnonTest extends FileResourceTestBase {
+
+  use AnonResourceTestTrait;
+  use XmlEntityNormalizationQuirksTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'xml';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'text/xml; charset=UTF-8';
+
+}
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/File/FileXmlBasicAuthTest.php b/core/modules/rest/tests/src/Functional/EntityResource/File/FileXmlBasicAuthTest.php
new file mode 100644
index 0000000..55a69c4
--- /dev/null
+++ b/core/modules/rest/tests/src/Functional/EntityResource/File/FileXmlBasicAuthTest.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace Drupal\Tests\rest\Functional\EntityResource\File;
+
+use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
+use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
+
+/**
+ * @group rest
+ */
+class FileXmlBasicAuthTest extends FileResourceTestBase {
+
+  use BasicAuthResourceTestTrait;
+  use XmlEntityNormalizationQuirksTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['basic_auth'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'xml';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'text/xml; charset=UTF-8';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $auth = 'basic_auth';
+
+}
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/File/FileXmlCookieTest.php b/core/modules/rest/tests/src/Functional/EntityResource/File/FileXmlCookieTest.php
new file mode 100644
index 0000000..cd90097
--- /dev/null
+++ b/core/modules/rest/tests/src/Functional/EntityResource/File/FileXmlCookieTest.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Drupal\Tests\rest\Functional\EntityResource\File;
+
+use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
+use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
+
+/**
+ * @group rest
+ */
+class FileXmlCookieTest extends FileResourceTestBase {
+
+  use CookieResourceTestTrait;
+  use XmlEntityNormalizationQuirksTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'xml';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'text/xml; charset=UTF-8';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $auth = 'cookie';
+
+}
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Media/MediaResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/Media/MediaResourceTestBase.php
index bf94261..1875d00 100644
--- a/core/modules/rest/tests/src/Functional/EntityResource/Media/MediaResourceTestBase.php
+++ b/core/modules/rest/tests/src/Functional/EntityResource/Media/MediaResourceTestBase.php
@@ -50,6 +50,8 @@ protected function setUpAuthorization($method) {
 
       case 'PATCH':
         $this->grantPermissionsToTestedRole(['update any media']);
+        // @todo Remove this in https://www.drupal.org/node/2824851.
+        $this->grantPermissionsToTestedRole(['access content']);
         break;
 
       case 'DELETE':
