diff --git a/core/modules/hal/tests/src/Kernel/DenormalizeTest.php b/core/modules/hal/tests/src/Kernel/DenormalizeTest.php
index 64c8311f7824fe1c17d69d9a89ca7a1ab2e5e331..8f64049917976381e40fe6afd81f66849653136e 100644
--- a/core/modules/hal/tests/src/Kernel/DenormalizeTest.php
+++ b/core/modules/hal/tests/src/Kernel/DenormalizeTest.php
@@ -7,7 +7,7 @@
 use Symfony\Component\Serializer\Exception\UnexpectedValueException;
 
 /**
- * Tests that entities can be denormalized from HAL.
+ * Tests HAL denormalization edge cases for EntityResource.
  *
  * @group hal
  */
@@ -110,98 +110,4 @@ public function testMarkFieldForDeletion() {
     $this->assertEqual($entity->field_test_text->count(), 0);
   }
 
-  /**
-   * Test that non-reference fields can be denormalized.
-   */
-  public function testBasicFieldDenormalization() {
-    $data = array(
-      '_links' => array(
-        'type' => array(
-          'href' => Url::fromUri('base:rest/type/entity_test/entity_test', array('absolute' => TRUE))->toString(),
-        ),
-      ),
-      'uuid' => array(
-        array(
-          'value' => 'e5c9fb96-3acf-4a8d-9417-23de1b6c3311',
-        ),
-      ),
-      'field_test_text' => array(
-        array(
-          'value' => $this->randomMachineName(),
-          'format' => 'full_html',
-        ),
-      ),
-      'field_test_translatable_text' => array(
-        array(
-          'value' => $this->randomMachineName(),
-          'format' => 'full_html',
-        ),
-        array(
-          'value' => $this->randomMachineName(),
-          'format' => 'filtered_html',
-        ),
-        array(
-          'value' => $this->randomMachineName(),
-          'format' => 'filtered_html',
-          'lang' => 'de',
-        ),
-        array(
-          'value' => $this->randomMachineName(),
-          'format' => 'full_html',
-          'lang' => 'de',
-        ),
-      ),
-    );
-
-    $expected_value_default = array(
-      array (
-        'value' => $data['field_test_translatable_text'][0]['value'],
-        'format' => 'full_html',
-      ),
-      array (
-        'value' => $data['field_test_translatable_text'][1]['value'],
-        'format' => 'filtered_html',
-      ),
-    );
-    $expected_value_de = array(
-      array (
-        'value' => $data['field_test_translatable_text'][2]['value'],
-        'format' => 'filtered_html',
-      ),
-      array (
-        'value' => $data['field_test_translatable_text'][3]['value'],
-        'format' => 'full_html',
-      ),
-    );
-    $denormalized = $this->serializer->denormalize($data, $this->entityClass, $this->format);
-    $this->assertEqual($data['uuid'], $denormalized->get('uuid')->getValue(), 'A preset value (e.g. UUID) is overridden by incoming data.');
-    $this->assertEqual($data['field_test_text'], $denormalized->get('field_test_text')->getValue(), 'A basic text field is denormalized.');
-    $this->assertEqual($expected_value_default, $denormalized->get('field_test_translatable_text')->getValue(), 'Values in the default language are properly handled for a translatable field.');
-    $this->assertEqual($expected_value_de, $denormalized->getTranslation('de')->get('field_test_translatable_text')->getValue(), 'Values in a translation language are properly handled for a translatable field.');
-  }
-
-  /**
-   * Verifies that the denormalized entity is correct in the PATCH context.
-   */
-  public function testPatchDenormalization() {
-    $data = array(
-      '_links' => array(
-        'type' => array(
-          'href' => Url::fromUri('base:rest/type/entity_test/entity_test', array('absolute' => TRUE))->toString(),
-        ),
-      ),
-      'field_test_text' => array(
-        array(
-          'value' => $this->randomMachineName(),
-          'format' => 'full_html',
-        ),
-      ),
-    );
-    $denormalized = $this->serializer->denormalize($data, $this->entityClass, $this->format, array('request_method' => 'patch'));
-    // Check that the one field got populated as expected.
-    $this->assertEqual($data['field_test_text'], $denormalized->get('field_test_text')->getValue());
-    // Check the custom property that contains the list of fields to merge.
-    $this->assertEqual($denormalized->_restSubmittedFields, ['field_test_text']);
-  }
-
 }
diff --git a/core/modules/hal/tests/src/Kernel/EntityNormalizeTest.php b/core/modules/hal/tests/src/Kernel/EntityNormalizeTest.php
deleted file mode 100644
index 88db403da976f0948b23805885ad9836f00f2542..0000000000000000000000000000000000000000
--- a/core/modules/hal/tests/src/Kernel/EntityNormalizeTest.php
+++ /dev/null
@@ -1,206 +0,0 @@
-<?php
-
-namespace Drupal\Tests\hal\Kernel;
-
-use Drupal\comment\Tests\CommentTestTrait;
-use Drupal\comment\Entity\Comment;
-use Drupal\node\Entity\Node;
-use Drupal\user\Entity\User;
-use Drupal\node\Entity\NodeType;
-use Drupal\taxonomy\Entity\Term;
-use Drupal\taxonomy\Entity\Vocabulary;
-
-/**
- * Tests that nodes and terms are correctly normalized and denormalized.
- *
- * @group hal
- */
-class EntityNormalizeTest extends NormalizerTestBase {
-
-  use CommentTestTrait;
-
-  /**
-   * Modules to enable.
-   *
-   * @var array
-   */
-  public static $modules = array('node', 'taxonomy', 'comment');
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-
-    \Drupal::service('router.builder')->rebuild();
-    $this->installSchema('system', array('sequences'));
-    $this->installSchema('comment', array('comment_entity_statistics'));
-    $this->installEntitySchema('taxonomy_term');
-    $this->installConfig(['node', 'comment']);
-  }
-
-  /**
-   * Tests the normalization of nodes.
-   */
-  public function testNode() {
-    $node_type = NodeType::create(['type' => 'example_type']);
-    $node_type->save();
-
-    $user = User::create(['name' => $this->randomMachineName()]);
-    $user->save();
-
-    // Add comment type.
-    $this->container->get('entity.manager')->getStorage('comment_type')->create(array(
-      'id' => 'comment',
-      'label' => 'comment',
-      'target_entity_type_id' => 'node',
-    ))->save();
-
-    $this->addDefaultCommentField('node', 'example_type');
-
-    $node = Node::create([
-      'title' => $this->randomMachineName(),
-      'uid' => $user->id(),
-      'type' => $node_type->id(),
-      'status' => NODE_PUBLISHED,
-      'promote' => 1,
-      'sticky' => 0,
-      'body' => [
-        'value' => $this->randomMachineName(),
-        'format' => $this->randomMachineName()
-      ],
-      'revision_log' => $this->randomString(),
-    ]);
-    $node->save();
-
-    $original_values = $node->toArray();
-
-    $normalized = $this->serializer->normalize($node, $this->format);
-
-    /** @var \Drupal\node\NodeInterface $denormalized_node */
-    $denormalized_node = $this->serializer->denormalize($normalized, 'Drupal\node\Entity\Node', $this->format);
-
-    $this->assertEqual($original_values, $denormalized_node->toArray(), 'Node values are restored after normalizing and denormalizing.');
-  }
-
-  /**
-   * Tests the normalization of terms.
-   */
-  public function testTerm() {
-    $vocabulary = Vocabulary::create(['vid' => 'example_vocabulary']);
-    $vocabulary->save();
-
-    $account = User::create(['name' => $this->randomMachineName()]);
-    $account->save();
-
-    // @todo Until https://www.drupal.org/node/2327935 is fixed, if no parent is
-    // set, the test fails because target_id => 0 is reserialized to NULL.
-    $term_parent = Term::create([
-      'name' => $this->randomMachineName(),
-      'vid' => $vocabulary->id(),
-    ]);
-    $term_parent->save();
-    $term = Term::create([
-      'name' => $this->randomMachineName(),
-      'vid' => $vocabulary->id(),
-      'description' => array(
-        'value' => $this->randomMachineName(),
-        'format' => $this->randomMachineName(),
-      ),
-      'parent' => $term_parent->id(),
-    ]);
-    $term->save();
-
-    $original_values = $term->toArray();
-
-    $normalized = $this->serializer->normalize($term, $this->format, ['account' => $account]);
-
-    /** @var \Drupal\taxonomy\TermInterface $denormalized_term */
-    $denormalized_term = $this->serializer->denormalize($normalized, 'Drupal\taxonomy\Entity\Term', $this->format, ['account' => $account]);
-
-    $this->assertEqual($original_values, $denormalized_term->toArray(), 'Term values are restored after normalizing and denormalizing.');
-  }
-
-  /**
-   * Tests the normalization of comments.
-   */
-  public function testComment() {
-    $node_type = NodeType::create(['type' => 'example_type']);
-    $node_type->save();
-
-    $account = User::create(['name' => $this->randomMachineName()]);
-    $account->save();
-
-    // Add comment type.
-    $this->container->get('entity.manager')->getStorage('comment_type')->create(array(
-      'id' => 'comment',
-      'label' => 'comment',
-      'target_entity_type_id' => 'node',
-    ))->save();
-
-    $this->addDefaultCommentField('node', 'example_type');
-
-    $node = Node::create([
-      'title' => $this->randomMachineName(),
-      'uid' => $account->id(),
-      'type' => $node_type->id(),
-      'status' => NODE_PUBLISHED,
-      'promote' => 1,
-      'sticky' => 0,
-      'body' => [[
-        'value' => $this->randomMachineName(),
-        'format' => $this->randomMachineName()
-      ]],
-    ]);
-    $node->save();
-
-    $parent_comment = Comment::create(array(
-      'uid' => $account->id(),
-      'subject' => $this->randomMachineName(),
-      'comment_body' => [
-        'value' => $this->randomMachineName(),
-        'format' => NULL,
-      ],
-      'entity_id' => $node->id(),
-      'entity_type' => 'node',
-      'field_name' => 'comment',
-    ));
-    $parent_comment->save();
-
-    $comment = Comment::create(array(
-      'uid' => $account->id(),
-      'subject' => $this->randomMachineName(),
-      'comment_body' => [
-        'value' => $this->randomMachineName(),
-        'format' => NULL,
-      ],
-      'entity_id' => $node->id(),
-      'entity_type' => 'node',
-      'field_name' => 'comment',
-      'pid' => $parent_comment->id(),
-      'mail' => 'dries@drupal.org',
-      'homepage' => 'http://buytaert.net',
-    ));
-    $comment->save();
-
-    $original_values = $comment->toArray();
-    // Hostname will always be denied view access.
-    // No value will exist for name as this is only for anonymous users.
-    unset($original_values['hostname'], $original_values['name']);
-
-    $normalized = $this->serializer->normalize($comment, $this->format, ['account' => $account]);
-
-    // Assert that the hostname field does not appear at all in the normalized
-    // data.
-    $this->assertFalse(array_key_exists('hostname', $normalized), 'Hostname was not found in normalized comment data.');
-
-    /** @var \Drupal\comment\CommentInterface $denormalized_comment */
-    $denormalized_comment = $this->serializer->denormalize($normalized, 'Drupal\comment\Entity\Comment', $this->format, ['account' => $account]);
-
-    // Before comparing, unset values that are expected to differ.
-    $denormalized_comment_values = $denormalized_comment->toArray();
-    unset($denormalized_comment_values['hostname'], $denormalized_comment_values['name']);
-    $this->assertEqual($original_values, $denormalized_comment_values, 'The expected comment values are restored after normalizing and denormalizing.');
-  }
-
-}
diff --git a/core/modules/hal/tests/src/Kernel/NormalizeTest.php b/core/modules/hal/tests/src/Kernel/NormalizeTest.php
index 6ed064c3f3cc49cf16c1d89d15dc4ad766429c9e..cfffb4a8652d455f890db44e62733d00a7b6c2f8 100644
--- a/core/modules/hal/tests/src/Kernel/NormalizeTest.php
+++ b/core/modules/hal/tests/src/Kernel/NormalizeTest.php
@@ -7,7 +7,7 @@
 use Drupal\entity_test\Entity\EntityTest;
 
 /**
- * Tests that entities can be normalized in HAL.
+ * Tests HAL normalization edge cases for EntityResource.
  *
  * @group hal
  */
diff --git a/core/modules/rest/src/Tests/AuthTest.php b/core/modules/rest/src/Tests/AuthTest.php
deleted file mode 100644
index 9f4224f64f1a58e4ce494f67a0e136e8f9f0b383..0000000000000000000000000000000000000000
--- a/core/modules/rest/src/Tests/AuthTest.php
+++ /dev/null
@@ -1,103 +0,0 @@
-<?php
-
-namespace Drupal\rest\Tests;
-
-use Drupal\Core\Url;
-
-/**
- * Tests authentication provider restrictions.
- *
- * @group rest
- */
-class AuthTest extends RESTTestBase {
-
-  /**
-   * Modules to install.
-   *
-   * @var array
-   */
-  public static $modules = array('basic_auth', 'hal', 'rest', 'entity_test');
-
-  /**
-   * Tests reading from an authenticated resource.
-   */
-  public function testRead() {
-    $entity_type = 'entity_test';
-
-    // Enable a test resource through GET method and basic HTTP authentication.
-    $this->enableService('entity:' . $entity_type, 'GET', NULL, array('basic_auth'));
-
-    // Create an entity programmatically.
-    $entity = $this->entityCreate($entity_type);
-    $entity->save();
-
-    // Try to read the resource as an anonymous user, which should not work.
-    $this->httpRequest($entity->urlInfo()->setRouteParameter('_format', $this->defaultFormat), 'GET');
-    $this->assertResponse('401', 'HTTP response code is 401 when the request is not authenticated and the user is anonymous.');
-    $this->assertRaw(json_encode(['message' => 'A fatal error occurred: No authentication credentials provided.']));
-
-    // Ensure that cURL settings/headers aren't carried over to next request.
-    unset($this->curlHandle);
-
-    // Create a user account that has the required permissions to read
-    // resources via the REST API, but the request is authenticated
-    // with session cookies.
-    $permissions = $this->entityPermissions($entity_type, 'view');
-    $account = $this->drupalCreateUser($permissions);
-    $this->drupalLogin($account);
-
-    // Try to read the resource with session cookie authentication, which is
-    // not enabled and should not work.
-    $this->httpRequest($entity->urlInfo()->setRouteParameter('_format', $this->defaultFormat), 'GET');
-    $this->assertResponse('403', 'HTTP response code is 403 when the request was authenticated by the wrong authentication provider.');
-
-    // Ensure that cURL settings/headers aren't carried over to next request.
-    unset($this->curlHandle);
-
-    // Now read it with the Basic authentication which is enabled and should
-    // work.
-    $this->basicAuthGet($entity->urlInfo()->setRouteParameter('_format', $this->defaultFormat), $account->getUsername(), $account->pass_raw);
-    $this->assertResponse('200', 'HTTP response code is 200 for successfully authenticated requests.');
-    $this->curlClose();
-  }
-
-  /**
-   * Performs a HTTP request with Basic authentication.
-   *
-   * We do not use \Drupal\simpletest\WebTestBase::drupalGet because we need to
-   * set curl settings for basic authentication.
-   *
-   * @param \Drupal\Core\Url $url
-   *   A Url object.
-   * @param string $username
-   *   The user name to authenticate with.
-   * @param string $password
-   *   The password.
-   * @param string $mime_type
-   *   The MIME type for the Accept header.
-   *
-   * @return string
-   *   Curl output.
-   */
-  protected function basicAuthGet(Url $url, $username, $password, $mime_type = NULL) {
-    if (!isset($mime_type)) {
-      $mime_type = $this->defaultMimeType;
-    }
-    $out = $this->curlExec(
-      array(
-        CURLOPT_HTTPGET => TRUE,
-        CURLOPT_URL => $url->setAbsolute()->toString(),
-        CURLOPT_NOBODY => FALSE,
-        CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
-        CURLOPT_USERPWD => $username . ':' . $password,
-        CURLOPT_HTTPHEADER => array('Accept: ' . $mime_type),
-      )
-    );
-
-    $this->verbose('GET request to: ' . $url->toString() .
-      '<hr />' . $out);
-
-    return $out;
-  }
-
-}
diff --git a/core/modules/rest/src/Tests/CreateTest.php b/core/modules/rest/src/Tests/CreateTest.php
deleted file mode 100644
index 2454d2a0cb92b6839470d406002890e3a9fb8c3c..0000000000000000000000000000000000000000
--- a/core/modules/rest/src/Tests/CreateTest.php
+++ /dev/null
@@ -1,484 +0,0 @@
-<?php
-
-namespace Drupal\rest\Tests;
-
-use Drupal\comment\Tests\CommentTestTrait;
-use Drupal\Component\Serialization\Json;
-use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Url;
-use Drupal\entity_test\Entity\EntityTest;
-use Drupal\node\Entity\Node;
-use Drupal\user\Entity\User;
-use Drupal\comment\Entity\Comment;
-
-/**
- * Tests the creation of resources.
- *
- * @group rest
- */
-class CreateTest extends RESTTestBase {
-
-  use CommentTestTrait;
-  /**
-   * Modules to install.
-   *
-   * @var array
-   */
-  public static $modules = array('hal', 'rest', 'entity_test', 'comment', 'node');
-
-  /**
-   * The 'serializer' service.
-   *
-   * @var \Symfony\Component\Serializer\Serializer
-   */
-  protected $serializer;
-
-  protected function setUp() {
-    parent::setUp();
-    $this->addDefaultCommentField('node', 'resttest');
-    // Get the 'serializer' service.
-    $this->serializer = $this->container->get('serializer');
-  }
-
-  /**
-   * Try to create a resource which is not REST API enabled.
-   */
-  public function testCreateResourceRestApiNotEnabled() {
-    $entity_type = 'entity_test';
-    // Enables the REST service for a specific entity type.
-    $this->enableService('entity:' . $entity_type, 'POST');
-
-    // Get the necessary user permissions to create the current entity type.
-    $permissions = $this->entityPermissions($entity_type, 'create');
-
-    // Create the user.
-    $account = $this->drupalCreateUser($permissions);
-    // Populate some entity properties before create the entity.
-    $entity_values = $this->entityValues($entity_type);
-    $entity = EntityTest::create($entity_values);
-
-    // Serialize the entity before the POST request.
-    $serialized = $this->serializer->serialize($entity, $this->defaultFormat, ['account' => $account]);
-
-    // Disable all resource types.
-    $this->enableService(FALSE);
-    $this->drupalLogin($account);
-
-    // POST request to create the current entity. GET request for CSRF token
-    // is included into the httpRequest() method.
-    $this->httpRequest('entity/entity_test', 'POST', $serialized, $this->defaultMimeType);
-
-    // The resource is not enabled. So, we receive a 'not found' response.
-    $this->assertResponse(404);
-    $this->assertFalse(EntityTest::loadMultiple(), 'No entity has been created in the database.');
-  }
-
-  /**
-   * Ensure that an entity cannot be created without the restful permission.
-   */
-  public function testCreateWithoutPermissionIfBcFlagIsOn() {
-    $rest_settings = $this->config('rest.settings');
-    $rest_settings->set('bc_entity_resource_permissions', TRUE)
-      ->save(TRUE);
-
-    $entity_type = 'entity_test';
-    // Enables the REST service for 'entity_test' entity type.
-    $this->enableService('entity:' . $entity_type, 'POST');
-    $permissions = $this->entityPermissions($entity_type, 'create');
-    // Create a user without the 'restful post entity:entity_test permission.
-    $account = $this->drupalCreateUser($permissions);
-    $this->drupalLogin($account);
-    // Populate some entity properties before create the entity.
-    $entity_values = $this->entityValues($entity_type);
-    $entity = EntityTest::create($entity_values);
-
-    // Serialize the entity before the POST request.
-    $serialized = $this->serializer->serialize($entity, $this->defaultFormat, ['account' => $account]);
-
-    // Create the entity over the REST API.
-    $this->httpRequest('entity/' . $entity_type, 'POST', $serialized, $this->defaultMimeType);
-    $this->assertResponse(403);
-    $this->assertFalse(EntityTest::loadMultiple(), 'No entity has been created in the database.');
-
-    // Create a user with the 'restful post entity:entity_test permission and
-    // try again. This time, we should be able to create an entity.
-    $permissions[] = 'restful post entity:' . $entity_type;
-    $account = $this->drupalCreateUser($permissions);
-    $this->drupalLogin($account);
-    $this->httpRequest('entity/' . $entity_type, 'POST', $serialized, $this->defaultMimeType);
-    $this->assertResponse(201);
-  }
-
-  /**
-   * Tests valid and invalid create requests for 'entity_test' entity type.
-   */
-  public function testCreateEntityTest() {
-    $entity_type = 'entity_test';
-    // Enables the REST service for 'entity_test' entity type.
-    $this->enableService('entity:' . $entity_type, 'POST');
-    // Create two accounts with the required permissions to create resources.
-    // The second one has administrative permissions.
-    $accounts = $this->createAccountPerEntity($entity_type);
-
-    // Verify create requests per user.
-    foreach ($accounts as $key => $account) {
-      $this->drupalLogin($account);
-      // Populate some entity properties before create the entity.
-      $entity_values = $this->entityValues($entity_type);
-      $entity = EntityTest::create($entity_values);
-
-      // Serialize the entity before the POST request.
-      $serialized = $this->serializer->serialize($entity, $this->defaultFormat, ['account' => $account]);
-
-      // Create the entity over the REST API.
-      $this->assertCreateEntityOverRestApi($entity_type, $serialized);
-      // Get the entity ID from the location header and try to read it from the
-      // database.
-      $this->assertReadEntityIdFromHeaderAndDb($entity_type, $entity, $entity_values);
-
-      // Try to create an entity with an access protected field.
-      // @see entity_test_entity_field_access()
-      $normalized = $this->serializer->normalize($entity, $this->defaultFormat, ['account' => $account]);
-      $normalized['field_test_text'][0]['value'] = 'no access value';
-      $this->httpRequest('entity/' . $entity_type, 'POST', $this->serializer->serialize($normalized, $this->defaultFormat, ['account' => $account]), $this->defaultMimeType);
-      $this->assertResponse(403);
-      $this->assertFalse(EntityTest::loadMultiple(), 'No entity has been created in the database.');
-
-      // Try to create a field with a text format this user has no access to.
-      $entity->field_test_text->value = $entity_values['field_test_text'][0]['value'];
-      $entity->field_test_text->format = 'full_html';
-
-      $serialized = $this->serializer->serialize($entity, $this->defaultFormat, ['account' => $account]);
-      $this->httpRequest('entity/' . $entity_type, 'POST', $serialized, $this->defaultMimeType);
-      // The value selected is not a valid choice because the format must be
-      // 'plain_txt'.
-      $this->assertResponse(422);
-      $this->assertFalse(EntityTest::loadMultiple(), 'No entity has been created in the database.');
-
-      // Restore the valid test value.
-      $entity->field_test_text->format = 'plain_text';
-      $serialized = $this->serializer->serialize($entity, $this->defaultFormat, ['account' => $account]);
-
-      // Try to send invalid data that cannot be correctly deserialized.
-      $this->assertCreateEntityInvalidData($entity_type);
-
-      // Try to send no data at all, which does not make sense on POST requests.
-      $this->assertCreateEntityNoData($entity_type);
-
-      // Try to send invalid data to trigger the entity validation constraints.
-      // Send a UUID that is too long.
-      $this->assertCreateEntityInvalidSerialized($entity, $entity_type);
-
-      // Try to create an entity without proper permissions.
-      $this->assertCreateEntityWithoutProperPermissions($entity_type, $serialized, ['account' => $account]);
-
-    }
-
-  }
-
-  /**
-   * Tests several valid and invalid create requests for 'node' entity type.
-   */
-  public function testCreateNode() {
-    $entity_type = 'node';
-    // Enables the REST service for 'node' entity type.
-    $this->enableService('entity:' . $entity_type, 'POST');
-    // Create two accounts that have the required permissions to create
-    // resources. The second one has administrative permissions.
-    $accounts = $this->createAccountPerEntity($entity_type);
-
-    // Verify create requests per user.
-    foreach ($accounts as $key => $account) {
-      $this->drupalLogin($account);
-      // Populate some entity properties before create the entity.
-      $entity_values = $this->entityValues($entity_type);
-      $entity = Node::create($entity_values);
-
-      // Verify that user cannot create content when trying to write to fields
-      // where it is not possible.
-      if (!$account->hasPermission('administer nodes')) {
-        $serialized = $this->serializer->serialize($entity, $this->defaultFormat, ['account' => $account]);
-        $this->httpRequest('entity/' . $entity_type, 'POST', $serialized, $this->defaultMimeType);
-        $this->assertResponse(403);
-        // Remove fields where non-administrative users cannot write.
-        $entity = $this->removeNodeFieldsForNonAdminUsers($entity);
-      }
-      else {
-        // Changed and revision_timestamp fields can never be added.
-        $entity->set('changed', NULL);
-        $entity->set('revision_timestamp', NULL);
-      }
-
-      $serialized = $this->serializer->serialize($entity, $this->defaultFormat, ['account' => $account]);
-
-      // Create the entity over the REST API.
-      $this->assertCreateEntityOverRestApi($entity_type, $serialized);
-
-      // Get the new entity ID from the location header and try to read it from
-      // the database.
-      $this->assertReadEntityIdFromHeaderAndDb($entity_type, $entity, $entity_values);
-
-      // Try to send invalid data that cannot be correctly deserialized.
-      $this->assertCreateEntityInvalidData($entity_type);
-
-      // Try to send no data at all, which does not make sense on POST requests.
-      $this->assertCreateEntityNoData($entity_type);
-
-      // Try to send invalid data to trigger the entity validation constraints. Send a UUID that is too long.
-      $this->assertCreateEntityInvalidSerialized($entity, $entity_type);
-
-      // Try to create an entity without proper permissions.
-      $this->assertCreateEntityWithoutProperPermissions($entity_type, $serialized);
-
-    }
-
-  }
-
-  /**
-   * Test comment creation.
-   */
-  protected function testCreateComment() {
-    $node = Node::create([
-      'type' => 'resttest',
-      'title' => 'some node',
-    ]);
-    $node->save();
-    $entity_type = 'comment';
-    // Enable the REST service for 'comment' entity type.
-    $this->enableService('entity:' . $entity_type, 'POST');
-    // Create two accounts that have the required permissions to create
-    // resources, The second one has administrative permissions.
-    $accounts = $this->createAccountPerEntity($entity_type);
-    $account = end($accounts);
-
-    $this->drupalLogin($account);
-    $entity_values = $this->entityValues($entity_type);
-    $entity_values['entity_id'] = $node->id();
-
-    $entity = Comment::create($entity_values);
-
-    // Changed field can never be added.
-    unset($entity->changed);
-
-    $serialized = $this->serializer->serialize($entity, $this->defaultFormat, ['account' => $account]);
-
-    // Create the entity over the REST API.
-    $this->assertCreateEntityOverRestApi($entity_type, $serialized);
-
-    // Get the new entity ID from the location header and try to read it from
-    // the database.
-    $this->assertReadEntityIdFromHeaderAndDb($entity_type, $entity, $entity_values);
-
-    // Try to send invalid data that cannot be correctly deserialized.
-    $this->assertCreateEntityInvalidData($entity_type);
-
-    // Try to send no data at all, which does not make sense on POST requests.
-    $this->assertCreateEntityNoData($entity_type);
-
-    // Try to send invalid data to trigger the entity validation constraints.
-    // Send a UUID that is too long.
-    $this->assertCreateEntityInvalidSerialized($entity, $entity_type);
-  }
-
-  /**
-   * Tests several valid and invalid create requests for 'user' entity type.
-   */
-  public function testCreateUser() {
-    $entity_type = 'user';
-    // Enables the REST service for 'user' entity type.
-    $this->enableService('entity:' . $entity_type, 'POST');
-    // Create two accounts that have the required permissions to create
-    // resources. The second one has administrative permissions.
-    $accounts = $this->createAccountPerEntity($entity_type);
-
-    foreach ($accounts as $key => $account) {
-      $this->drupalLogin($account);
-      $entity_values = $this->entityValues($entity_type);
-      $entity = User::create($entity_values);
-
-      // Verify that only administrative users can create users.
-      if (!$account->hasPermission('administer users')) {
-        $serialized = $this->serializer->serialize($entity, $this->defaultFormat, ['account' => $account]);
-        $this->httpRequest('entity/' . $entity_type, 'POST', $serialized, $this->defaultMimeType);
-        $this->assertResponse(403);
-        continue;
-      }
-
-      // Changed field can never be added.
-      $entity->set('changed', NULL);
-
-      $serialized = $this->serializer->serialize($entity, $this->defaultFormat, ['account' => $account]);
-
-      // Create the entity over the REST API.
-      $this->assertCreateEntityOverRestApi($entity_type, $serialized);
-
-      // Get the new entity ID from the location header and try to read it from
-      // the database.
-      $this->assertReadEntityIdFromHeaderAndDb($entity_type, $entity, $entity_values);
-
-      // Try to send invalid data that cannot be correctly deserialized.
-      $this->assertCreateEntityInvalidData($entity_type);
-
-      // Try to send no data at all, which does not make sense on POST requests.
-      $this->assertCreateEntityNoData($entity_type);
-
-      // Try to send invalid data to trigger the entity validation constraints.
-      // Send a UUID that is too long.
-      $this->assertCreateEntityInvalidSerialized($entity, $entity_type);
-    }
-
-  }
-
-  /**
-   * Creates user accounts that have the required permissions to create
-   * resources via the REST API. The second one has administrative permissions.
-   *
-   * @param string $entity_type
-   *   Entity type needed to apply user permissions.
-   * @return array
-   *   An array that contains user accounts.
-   */
-  public function createAccountPerEntity($entity_type) {
-    $accounts = array();
-    // Get the necessary user permissions for the current $entity_type creation.
-    $permissions = $this->entityPermissions($entity_type, 'create');
-    // Create user without administrative permissions.
-    $accounts[] = $this->drupalCreateUser($permissions);
-    // Add administrative permissions for nodes and users.
-    $permissions[] = 'administer nodes';
-    $permissions[] = 'administer users';
-    $permissions[] = 'administer comments';
-    // Create an administrative user.
-    $accounts[] = $this->drupalCreateUser($permissions);
-
-    return $accounts;
-  }
-
-  /**
-   * Creates the entity over the REST API.
-   *
-   * @param string $entity_type
-   *   The type of the entity that should be created.
-   * @param string $serialized
-   *   The body for the POST request.
-   */
-  public function assertCreateEntityOverRestApi($entity_type, $serialized = NULL) {
-    // Note: this will fail with PHP 5.6 when always_populate_raw_post_data is
-    // set to something other than -1. See https://www.drupal.org/node/2456025.
-    // Try first without the CSRF token, which should fail.
-    $url = Url::fromUri('internal:/entity/' . $entity_type)->setOption('query', ['_format' => $this->defaultFormat]);
-    $this->httpRequest($url, 'POST', $serialized, $this->defaultMimeType, FALSE);
-    $this->assertResponse(403);
-    $this->assertRaw('X-CSRF-Token request header is missing');
-    // Then try with an invalid CSRF token.
-    $this->httpRequest($url, 'POST', $serialized, $this->defaultMimeType, 'invalid-csrf-token');
-    $this->assertResponse(403);
-    $this->assertRaw('X-CSRF-Token request header is invalid');
-    // Then try with the CSRF token.
-    $response = $this->httpRequest($url, 'POST', $serialized, $this->defaultMimeType);
-    $this->assertResponse(201);
-
-    // Make sure that the response includes an entity in the body and check the
-    // UUID as an example.
-    $request = Json::decode($serialized);
-    $response = Json::decode($response);
-    $this->assertEqual($request['uuid'][0]['value'], $response['uuid'][0]['value'], 'Got new entity created as response after successful POST over Rest API');
-  }
-
-  /**
-   * Gets the new entity ID from the location header and tries to read it from
-   * the database.
-   *
-   * @param string $entity_type
-   *   Entity type we need to load the entity from DB.
-   * @param \Drupal\Core\Entity\EntityInterface $entity
-   *   The entity we want to check that was inserted correctly.
-   * @param array $entity_values
-   *   The values of $entity.
-   */
-  public function assertReadEntityIdFromHeaderAndDb($entity_type, EntityInterface $entity, array $entity_values = array()) {
-    // Get the location from the HTTP response header.
-    $location_url = $this->drupalGetHeader('location');
-    $url_parts = explode('/', $location_url);
-    $id = end($url_parts);
-
-    // Get the entity using the ID found.
-    $loaded_entity = \Drupal::entityManager()->getStorage($entity_type)->load($id);
-    $this->assertNotIdentical(FALSE, $loaded_entity, 'The new ' . $entity_type . ' was found in the database.');
-    $this->assertEqual($entity->uuid(), $loaded_entity->uuid(), 'UUID of created entity is correct.');
-
-    // Verify that the field values sent and received from DB are the same.
-    foreach ($entity_values as $property => $value) {
-      $actual_value = $loaded_entity->get($property)->value;
-      $send_value = $entity->get($property)->value;
-      $this->assertEqual($send_value, $actual_value, 'Created property ' . $property . ' expected: ' . $send_value . ', actual: ' . $actual_value);
-    }
-
-    // Delete the entity loaded from DB.
-    $loaded_entity->delete();
-  }
-
-  /**
-   * Try to send invalid data that cannot be correctly deserialized.
-   *
-   * @param string $entity_type
-   *   The type of the entity that should be created.
-   */
-  public function assertCreateEntityInvalidData($entity_type) {
-    $this->httpRequest('entity/' . $entity_type, 'POST', 'kaboom!', $this->defaultMimeType);
-    $this->assertResponse(400);
-  }
-
-  /**
-   * Try to send no data at all, which does not make sense on POST requests.
-   *
-   * @param string $entity_type
-   *   The type of the entity that should be created.
-   */
-  public function assertCreateEntityNoData($entity_type) {
-    $this->httpRequest('entity/' . $entity_type, 'POST', NULL, $this->defaultMimeType);
-    $this->assertResponse(400);
-  }
-
-  /**
-   * Send an invalid UUID to trigger the entity validation.
-   *
-   * @param \Drupal\Core\Entity\EntityInterface $entity
-   *   The entity we want to check that was inserted correctly.
-   * @param string $entity_type
-   *   The type of the entity that should be created.
-   * @param array $context
-   *   Options normalizers/encoders have access to.
-   */
-  public function assertCreateEntityInvalidSerialized(EntityInterface $entity, $entity_type, array $context = array()) {
-    // Add a UUID that is too long.
-    $entity->set('uuid', $this->randomMachineName(129));
-    $invalid_serialized = $this->serializer->serialize($entity, $this->defaultFormat, $context);
-
-    $response = $this->httpRequest(Url::fromRoute("rest.entity.$entity_type.POST")->setRouteParameter('_format', $this->defaultFormat), 'POST', $invalid_serialized, $this->defaultMimeType);
-
-    // Unprocessable Entity as response.
-    $this->assertResponse(422);
-
-    // Verify that the text of the response is correct.
-    $error = Json::decode($response);
-    $this->assertEqual($error['message'], "Unprocessable Entity: validation failed.\nuuid.0.value: <em class=\"placeholder\">UUID</em>: may not be longer than 128 characters.\n");
-  }
-
-  /**
-   * Try to create an entity without proper permissions.
-   *
-   * @param string $entity_type
-   *   The type of the entity that should be created.
-   * @param string $serialized
-   *   The body for the POST request.
-   */
-  public function assertCreateEntityWithoutProperPermissions($entity_type, $serialized = NULL) {
-    $this->drupalLogout();
-    $this->httpRequest('entity/' . $entity_type, 'POST', $serialized, $this->defaultMimeType);
-    // Forbidden Error as response.
-    $this->assertResponse(403);
-    $this->assertFalse(\Drupal::entityManager()->getStorage($entity_type)->loadMultiple(), 'No entity has been created in the database.');
-  }
-
-}
diff --git a/core/modules/rest/src/Tests/CsrfTest.php b/core/modules/rest/src/Tests/CsrfTest.php
deleted file mode 100644
index f0063ad8e1cd4544e08ff78601b19a97b5125aa7..0000000000000000000000000000000000000000
--- a/core/modules/rest/src/Tests/CsrfTest.php
+++ /dev/null
@@ -1,124 +0,0 @@
-<?php
-
-namespace Drupal\rest\Tests;
-
-use Drupal\Core\Url;
-
-/**
- * Tests the CSRF protection.
- *
- * @group rest
- */
-class CsrfTest extends RESTTestBase {
-
-  /**
-   * Modules to install.
-   *
-   * @var array
-   */
-  public static $modules = array('hal', 'rest', 'entity_test', 'basic_auth');
-
-  /**
-   * A testing user account.
-   *
-   * @var \Drupal\user\Entity\User
-   */
-  protected $account;
-
-  /**
-   * The serialized entity.
-   *
-   * @var string
-   */
-  protected $serialized;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-
-    $this->enableService('entity:' . $this->testEntityType, 'POST', 'hal_json', array('basic_auth', 'cookie'));
-
-    // Create a user account that has the required permissions to create
-    // resources via the REST API.
-    $permissions = $this->entityPermissions($this->testEntityType, 'create');
-    $this->account = $this->drupalCreateUser($permissions);
-
-    // Serialize an entity to a string to use in the content body of the POST
-    // request.
-    $serializer = $this->container->get('serializer');
-    $entity_values = $this->entityValues($this->testEntityType);
-    $entity = $this->container->get('entity_type.manager')
-      ->getStorage($this->testEntityType)
-      ->create($entity_values);
-    $this->serialized = $serializer->serialize($entity, $this->defaultFormat);
-  }
-
-  /**
-   * Tests that CSRF check is not triggered for Basic Auth requests.
-   */
-  public function testBasicAuth() {
-    $curl_options = $this->getCurlOptions();
-    $curl_options[CURLOPT_HTTPAUTH] = CURLAUTH_BASIC;
-    $curl_options[CURLOPT_USERPWD] = $this->account->getUsername() . ':' . $this->account->pass_raw;
-    $this->curlExec($curl_options);
-    $this->assertResponse(201);
-    // Ensure that the entity was created.
-    $loaded_entity = $this->loadEntityFromLocationHeader($this->drupalGetHeader('location'));
-    $this->assertTrue($loaded_entity, 'An entity was created in the database');
-  }
-
-  /**
-   * Tests that CSRF check is triggered for Cookie Auth requests.
-   *
-   * @deprecated as of Drupal 8.2.x, will be removed before Drupal 9.0.0. Use
-   *   \Drupal\Tests\system\Functional\CsrfRequestHeaderTest::testRouteAccess
-   *   instead.
-   */
-  public function testCookieAuth() {
-    $this->drupalLogin($this->account);
-
-    $curl_options = $this->getCurlOptions();
-
-    // Try to create an entity without the CSRF token.
-    // Note: this will fail with PHP 5.6 when always_populate_raw_post_data is
-    // set to something other than -1. See https://www.drupal.org/node/2456025.
-    $this->curlExec($curl_options);
-    $this->assertResponse(403);
-    // Ensure that the entity was not created.
-    $storage = $this->container->get('entity_type.manager')
-      ->getStorage($this->testEntityType);
-    $storage->resetCache();
-    $this->assertFalse($storage->loadMultiple(), 'No entity has been created in the database.');
-
-    // Create an entity with the CSRF token.
-    $token = $this->drupalGet('rest/session/token');
-    $curl_options[CURLOPT_HTTPHEADER][] = "X-CSRF-Token: $token";
-    $this->curlExec($curl_options);
-    $this->assertResponse(201);
-    // Ensure that the entity was created.
-    $loaded_entity = $this->loadEntityFromLocationHeader($this->drupalGetHeader('location'));
-    $this->assertTrue($loaded_entity, 'An entity was created in the database');
-  }
-
-  /**
-   * Gets the cURL options to create an entity with POST.
-   *
-   * @return array
-   *   The array of cURL options.
-   */
-  protected function getCurlOptions() {
-    return array(
-      CURLOPT_HTTPGET => FALSE,
-      CURLOPT_POST => TRUE,
-      CURLOPT_POSTFIELDS => $this->serialized,
-      CURLOPT_URL => Url::fromRoute('rest.entity.' . $this->testEntityType . '.POST')->setAbsolute()->toString(),
-      CURLOPT_NOBODY => FALSE,
-      CURLOPT_HTTPHEADER => array(
-        "Content-Type: {$this->defaultMimeType}",
-      ),
-    );
-  }
-
-}
diff --git a/core/modules/rest/src/Tests/DeleteTest.php b/core/modules/rest/src/Tests/DeleteTest.php
deleted file mode 100644
index 88db0fd9df7ca630aa1f766ad3c4b68a0be6ffb8..0000000000000000000000000000000000000000
--- a/core/modules/rest/src/Tests/DeleteTest.php
+++ /dev/null
@@ -1,90 +0,0 @@
-<?php
-
-namespace Drupal\rest\Tests;
-
-use Drupal\Core\Url;
-
-/**
- * Tests the deletion of resources.
- *
- * @group rest
- */
-class DeleteTest extends RESTTestBase {
-
-  /**
-   * Modules to install.
-   *
-   * @var array
-   */
-  public static $modules = array('hal', 'rest', 'entity_test', 'node');
-
-  /**
-   * Tests several valid and invalid delete requests on all entity types.
-   */
-  public function testDelete() {
-    // Define the entity types we want to test.
-    // @todo expand this test to at least users once their access
-    // controllers are implemented.
-    $entity_types = array('entity_test', 'node');
-    foreach ($entity_types as $entity_type) {
-      $this->enableService('entity:' . $entity_type, 'DELETE');
-      // Create a user account that has the required permissions to delete
-      // resources via the REST API.
-      $permissions = $this->entityPermissions($entity_type, 'delete');
-      $account = $this->drupalCreateUser($permissions);
-      $this->drupalLogin($account);
-
-      // Create an entity programmatically.
-      $entity = $this->entityCreate($entity_type);
-      $entity->save();
-      // Try first to delete over REST API without the CSRF token.
-      $url = $entity->toUrl()->setRouteParameter('_format', $this->defaultFormat);
-      $this->httpRequest($url, 'DELETE', NULL, 'application/hal+json', FALSE);
-      $this->assertResponse(403);
-      $this->assertRaw('X-CSRF-Token request header is missing');
-      // Then try with an invalid CSRF token.
-      $this->httpRequest($url, 'DELETE', NULL, 'application/hal+json', 'invalid-csrf-token');
-      $this->assertResponse(403);
-      $this->assertRaw('X-CSRF-Token request header is invalid');
-      // Delete it over the REST API.
-      $response = $this->httpRequest($url, 'DELETE');
-      $this->assertResponse(204);
-      // Clear the static cache with entity_load(), otherwise we won't see the
-      // update.
-      $storage = $this->container->get('entity_type.manager')
-        ->getStorage($entity_type);
-      $storage->resetCache([$entity->id()]);
-      $entity = $storage->load($entity->id());
-      $this->assertFalse($entity, $entity_type . ' entity is not in the DB anymore.');
-      $this->assertResponse('204', 'HTTP response code is correct.');
-      $this->assertEqual($response, '', 'Response body is empty.');
-
-      // Try to delete an entity that does not exist.
-      $response = $this->httpRequest(Url::fromRoute('entity.' . $entity_type . '.canonical', [$entity_type => 9999]), 'DELETE');
-      $this->assertResponse(404);
-      $this->assertText('The requested page could not be found.');
-
-      // Try to delete an entity without proper permissions.
-      $this->drupalLogout();
-      // Re-save entity to the database.
-      $entity = $this->entityCreate($entity_type);
-      $entity->save();
-      $this->httpRequest($entity->urlInfo(), 'DELETE');
-      $this->assertResponse(403);
-      $storage->resetCache([$entity->id()]);
-      $this->assertNotIdentical(FALSE, $storage->load($entity->id()),
-        'The ' . $entity_type . ' entity is still in the database.');
-    }
-    // Try to delete a resource which is not REST API enabled.
-    $this->enableService(FALSE);
-    $account = $this->drupalCreateUser();
-    $this->drupalLogin($account);
-    $this->httpRequest($account->urlInfo(), 'DELETE');
-    $user_storage = $this->container->get('entity.manager')->getStorage('user');
-    $user_storage->resetCache(array($account->id()));
-    $user = $user_storage->load($account->id());
-    $this->assertEqual($account->id(), $user->id(), 'User still exists in the database.');
-    $this->assertResponse(405);
-  }
-
-}
diff --git a/core/modules/rest/src/Tests/NodeTest.php b/core/modules/rest/src/Tests/NodeTest.php
deleted file mode 100644
index 95dc475e0e83d07ecb1ba0af7406cdf054b4cc76..0000000000000000000000000000000000000000
--- a/core/modules/rest/src/Tests/NodeTest.php
+++ /dev/null
@@ -1,197 +0,0 @@
-<?php
-
-namespace Drupal\rest\Tests;
-
-use Drupal\Core\Url;
-use Drupal\node\Entity\Node;
-
-/**
- * Tests special cases for node entities.
- *
- * @group rest
- */
-class NodeTest extends RESTTestBase {
-
-  /**
-   * Modules to install.
-   *
-   * Ensure that the node resource works with comment module enabled.
-   *
-   * @var array
-   */
-  public static $modules = array('hal', 'rest', 'comment', 'node');
-
-  /**
-   * Enables node specific REST API configuration and authentication.
-   *
-   * @param string $method
-   *   The HTTP method to be tested.
-   * @param string $operation
-   *   The operation, one of 'view', 'create', 'update' or 'delete'.
-   */
-  protected function enableNodeConfiguration($method, $operation) {
-    $this->enableService('entity:node', $method);
-    $permissions = $this->entityPermissions('node', $operation);
-    $account = $this->drupalCreateUser($permissions);
-    $this->drupalLogin($account);
-  }
-
-  /**
-   * Serializes and attempts to create a node via a REST "post" http request.
-   *
-   * @param array $data
-   */
-  protected function postNode($data) {
-    // Enable node creation via POST.
-    $this->enableNodeConfiguration('POST', 'create');
-    $this->enableService('entity:node', 'POST', 'json');
-
-    // Create a JSON version of a simple node with the title.
-    $serialized = $this->container->get('serializer')->serialize($data, 'json');
-
-    // Post to the REST service to create the node.
-    $this->httpRequest('/entity/node', 'POST', $serialized, 'application/json');
-  }
-
-  /**
-   * Tests the title on a newly created node.
-   *
-   * @param array $data
-   * @return \Drupal\node\Entity\Node
-   */
-  protected function assertNodeTitleMatch($data) {
-    /** @var \Drupal\node\Entity\Node $node */
-    // Load the newly created node.
-    $node = Node::load(1);
-
-    // Test that the title is the same as what we posted.
-    $this->assertEqual($node->title->value, $data['title'][0]['value']);
-
-    return $node;
-  }
-
-  /**
-   * Performs various tests on nodes and their REST API.
-   */
-  public function testNodes() {
-    $node_storage = $this->container->get('entity.manager')->getStorage('node');
-    $this->enableNodeConfiguration('GET', 'view');
-
-    $node = $this->entityCreate('node');
-    $node->save();
-    $this->httpRequest($node->urlInfo()->setRouteParameter('_format', $this->defaultFormat), 'GET');
-    $this->assertResponse(200);
-    $this->assertHeader('Content-type', $this->defaultMimeType);
-
-    // Also check that JSON works and the routing system selects the correct
-    // REST route.
-    $this->enableService('entity:node', 'GET', 'json');
-    $this->httpRequest($node->urlInfo()->setRouteParameter('_format', 'json'), 'GET');
-    $this->assertResponse(200);
-    $this->assertHeader('Content-type', 'application/json');
-
-    // Check that a simple PATCH update to the node title works as expected.
-    $this->enableNodeConfiguration('PATCH', 'update');
-
-    // Create a PATCH request body that only updates the title field.
-    $new_title = $this->randomString();
-    $data = array(
-      '_links' => array(
-        'type' => array(
-          'href' => Url::fromUri('base:rest/type/node/resttest', array('absolute' => TRUE))->toString(),
-        ),
-      ),
-      'title' => array(
-        array(
-          'value' => $new_title,
-        ),
-      ),
-    );
-    $serialized = $this->container->get('serializer')->serialize($data, $this->defaultFormat);
-    $this->httpRequest($node->urlInfo(), 'PATCH', $serialized, $this->defaultMimeType);
-    $this->assertResponse(200);
-
-    // Reload the node from the DB and check if the title was correctly updated.
-    $node_storage->resetCache(array($node->id()));
-    $updated_node = $node_storage->load($node->id());
-    $this->assertEqual($updated_node->getTitle(), $new_title);
-    // Make sure that the UUID of the node has not changed.
-    $this->assertEqual($node->get('uuid')->getValue(), $updated_node->get('uuid')->getValue(), 'UUID was not changed.');
-  }
-
-  /**
-   * Test creating a node using json serialization.
-   */
-  public function testCreate() {
-    // Data to be used for serialization.
-    $data = [
-      'type' => [['target_id' => 'resttest']],
-      'title' => [['value' => $this->randomString() ]],
-    ];
-
-    $this->postNode($data);
-
-    // Make sure the response is "CREATED".
-    $this->assertResponse(201);
-
-    // Make sure the node was created and the title matches.
-    $node = $this->assertNodeTitleMatch($data);
-
-    // Make sure the request returned a redirect header to view the node.
-    $this->assertHeader('Location', $node->url('canonical', ['absolute' => TRUE]));
-  }
-
-  /**
-   * Test bundle normalization when posting bundle as a simple string.
-   */
-  public function testBundleNormalization() {
-    // Data to be used for serialization.
-    $data = [
-      'type' => 'resttest',
-      'title' => [['value' => $this->randomString() ]],
-    ];
-
-    $this->postNode($data);
-
-    // Make sure the response is "CREATED".
-    $this->assertResponse(201);
-
-    // Make sure the node was created and the title matches.
-    $this->assertNodeTitleMatch($data);
-  }
-
-  /**
-   * Test bundle normalization when posting using a simple string.
-   */
-  public function testInvalidBundle() {
-    // Data to be used for serialization.
-    $data = [
-      'type' => 'bad_bundle_name',
-      'title' => [['value' => $this->randomString() ]],
-    ];
-
-    $this->postNode($data);
-
-    // Make sure the response is "Bad Request".
-    $this->assertResponse(400);
-    $this->assertResponseBody('{"error":"\"bad_bundle_name\" is not a valid bundle type for denormalization."}');
-  }
-
-  /**
-   * Test when the bundle is missing.
-   */
-  public function testMissingBundle() {
-    // Data to be used for serialization.
-    $data = [
-      'title' => [['value' => $this->randomString() ]],
-    ];
-
-    // testing
-    $this->postNode($data);
-
-    // Make sure the response is "Bad Request".
-    $this->assertResponse(400);
-    $this->assertResponseBody('{"error":"A string must be provided as a bundle value."}');
-  }
-
-}
diff --git a/core/modules/rest/src/Tests/PageCacheTest.php b/core/modules/rest/src/Tests/PageCacheTest.php
deleted file mode 100644
index 66e57f5a54d65da3dc37084f845cc0b922afc690..0000000000000000000000000000000000000000
--- a/core/modules/rest/src/Tests/PageCacheTest.php
+++ /dev/null
@@ -1,162 +0,0 @@
-<?php
-
-namespace Drupal\rest\Tests;
-
-use Drupal\Component\Serialization\Json;
-use Drupal\Core\Url;
-use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
-
-/**
- * Tests page caching for REST GET requests.
- *
- * @group rest
- */
-class PageCacheTest extends RESTTestBase {
-
-  use AssertPageCacheContextsAndTagsTrait;
-
-  /**
-   * Modules to install.
-   *
-   * @var array
-   */
-  public static $modules = array('hal');
-
-  /**
-   * The 'serializer' service.
-   *
-   * @var \Symfony\Component\Serializer\Serializer
-   */
-  protected $serializer;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-    // Get the 'serializer' service.
-    $this->serializer = $this->container->get('serializer');
-  }
-
-  /**
-   * Tests that configuration changes also clear the page cache.
-   */
-  public function testConfigChangePageCache() {
-    // Allow anonymous users to issue GET requests.
-    user_role_grant_permissions('anonymous', ['view test entity', 'restful get entity:entity_test']);
-
-    $this->enableService('entity:entity_test', 'POST');
-    $permissions = [
-      'administer entity_test content',
-    ];
-    $account = $this->drupalCreateUser($permissions);
-
-    // Create an entity and test that the response from a post request is not
-    // cacheable.
-    $entity = $this->entityCreate('entity_test');
-    $entity->set('field_test_text', 'custom cache tag value');
-    $serialized = $this->serializer->serialize($entity, $this->defaultFormat);
-    // Log in for creating the entity.
-    $this->drupalLogin($account);
-    $this->httpRequest('entity/entity_test', 'POST', $serialized, $this->defaultMimeType);
-    $this->assertResponse(201);
-
-    if ($this->getCacheHeaderValues('x-drupal-cache')) {
-      $this->fail('Post request is cached.');
-    }
-    $this->drupalLogout();
-
-    $url = Url::fromUri('internal:/entity_test/1?_format=' . $this->defaultFormat);
-
-    // Read it over the REST API.
-    $this->enableService('entity:entity_test', 'GET');
-    $this->httpRequest($url, 'GET', NULL, $this->defaultMimeType);
-    $this->assertResponse(200, 'HTTP response code is correct.');
-    $this->assertHeader('x-drupal-cache', 'MISS');
-    $this->assertCacheTag('config:rest.resource.entity.entity_test');
-    $this->assertCacheTag('entity_test:1');
-    $this->assertCacheTag('entity_test_access:field_test_text');
-
-    // Read it again, should be page-cached now.
-    $this->httpRequest($url, 'GET', NULL, $this->defaultMimeType);
-    $this->assertResponse(200, 'HTTP response code is correct.');
-    $this->assertHeader('x-drupal-cache', 'HIT');
-    $this->assertCacheTag('config:rest.resource.entity.entity_test');
-    $this->assertCacheTag('entity_test:1');
-    $this->assertCacheTag('entity_test_access:field_test_text');
-
-    // Trigger a resource config save which should clear the page cache, so we
-    // should get a cache miss now for the same request.
-    $this->resourceConfigStorage->load('entity.entity_test')->save();
-    $this->httpRequest($url, 'GET', NULL, $this->defaultMimeType);
-    $this->assertResponse(200, 'HTTP response code is correct.');
-    $this->assertHeader('x-drupal-cache', 'MISS');
-    $this->assertCacheTag('config:rest.resource.entity.entity_test');
-    $this->assertCacheTag('entity_test:1');
-    $this->assertCacheTag('entity_test_access:field_test_text');
-
-    // Log in for deleting / updating entity.
-    $this->drupalLogin($account);
-
-    // Test that updating an entity is not cacheable.
-    $this->enableService('entity:entity_test', 'PATCH');
-
-    // Create a second stub entity for overwriting a field.
-    $patch_values['field_test_text'] = [0 => [
-      'value' => 'patched value',
-      'format' => 'plain_text',
-    ]];
-    $patch_entity = $this->container->get('entity_type.manager')
-      ->getStorage('entity_test')
-      ->create($patch_values);
-    // We don't want to overwrite the UUID.
-    $patch_entity->set('uuid', NULL);
-    $serialized = $this->container->get('serializer')
-      ->serialize($patch_entity, $this->defaultFormat);
-
-    // Update the entity over the REST API.
-    $this->httpRequest($url, 'PATCH', $serialized, $this->defaultMimeType);
-    $this->assertResponse(200);
-
-    if ($this->getCacheHeaderValues('x-drupal-cache')) {
-      $this->fail('Patch request is cached.');
-    }
-
-    // Test that the response from a delete request is not cacheable.
-    $this->enableService('entity:entity_test', 'DELETE');
-    $this->httpRequest($url, 'DELETE');
-    $this->assertResponse(204);
-
-    if ($this->getCacheHeaderValues('x-drupal-cache')) {
-      $this->fail('Patch request is cached.');
-    }
-  }
-
-  /**
-   * Tests HEAD support when a REST resource supports GET.
-   */
-  public function testHeadSupport() {
-    user_role_grant_permissions('anonymous', ['view test entity', 'restful get entity:entity_test']);
-
-    // Create an entity programatically.
-    $this->entityCreate('entity_test')->save();
-
-    $url = Url::fromUri('internal:/entity_test/1?_format=' . $this->defaultFormat);
-
-    $this->enableService('entity:entity_test', 'GET');
-
-    $this->httpRequest($url, 'HEAD', NULL, $this->defaultMimeType);
-    $this->assertResponse(200, 'HTTP response code is correct.');
-    $this->assertHeader('X-Drupal-Cache', 'MISS');
-    $this->assertResponseBody('');
-
-    $response = $this->httpRequest($url, 'GET', NULL, $this->defaultMimeType);
-    $this->assertResponse(200, 'HTTP response code is correct.');
-    $this->assertHeader('X-Drupal-Cache', 'HIT');
-    $this->assertCacheTag('config:rest.resource.entity.entity_test');
-    $this->assertCacheTag('entity_test:1');
-    $data = Json::decode($response);
-    $this->assertEqual($data['type'][0]['value'], 'entity_test');
-  }
-
-}
diff --git a/core/modules/rest/src/Tests/RESTTestBase.php b/core/modules/rest/src/Tests/RESTTestBase.php
index 7cb0f1bde4d4993fe593b6ad6c0f7424f1dfda75..c755967eabbe1823e14c098e5382a91fb2caae2a 100644
--- a/core/modules/rest/src/Tests/RESTTestBase.php
+++ b/core/modules/rest/src/Tests/RESTTestBase.php
@@ -9,6 +9,8 @@
 
 /**
  * Test helper class that provides a REST client method to send HTTP requests.
+ *
+ * @deprecated in Drupal 8.3.x-dev and will be removed before Drupal 9.0.0. Use \Drupal\Tests\rest\Functional\ResourceTestBase and \Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase instead. Only retained for contributed module tests that may be using this base class.
  */
 abstract class RESTTestBase extends WebTestBase {
 
diff --git a/core/modules/rest/src/Tests/ReadTest.php b/core/modules/rest/src/Tests/ReadTest.php
deleted file mode 100644
index dc6f5743793df6bc3f42ee7693468a9eb488e8bf..0000000000000000000000000000000000000000
--- a/core/modules/rest/src/Tests/ReadTest.php
+++ /dev/null
@@ -1,205 +0,0 @@
-<?php
-
-namespace Drupal\rest\Tests;
-
-use Drupal\Component\Serialization\Json;
-use Drupal\Core\Config\Entity\ConfigEntityInterface;
-use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Url;
-
-/**
- * Tests the retrieval of resources.
- *
- * @group rest
- */
-class ReadTest extends RESTTestBase {
-
-  /**
-   * Modules to install.
-   *
-   * @var array
-   */
-  public static $modules = [
-    'hal',
-    'rest',
-    'node',
-    'entity_test',
-    'config_test',
-    'taxonomy',
-    'block',
-  ];
-
-  /**
-   * Tests several valid and invalid read requests on all entity types.
-   */
-  public function testRead() {
-    // @todo Expand this at least to users.
-    // Define the entity types we want to test.
-    $entity_types = [
-      'entity_test',
-      'node',
-      'config_test',
-      'taxonomy_vocabulary',
-      'block',
-      'user_role',
-    ];
-    foreach ($entity_types as $entity_type) {
-      $this->enableService('entity:' . $entity_type, 'GET');
-      // Create a user account that has the required permissions to read
-      // resources via the REST API.
-      $permissions = $this->entityPermissions($entity_type, 'view');
-      $account = $this->drupalCreateUser($permissions);
-      $this->drupalLogin($account);
-
-      // Create an entity programmatically.
-      $entity = $this->entityCreate($entity_type);
-      $entity->save();
-
-      // Verify that it exists: use a HEAD request.
-      $this->httpRequest($this->getReadUrl($entity), 'HEAD');
-      $this->assertResponseBody('');
-      $head_headers = $this->drupalGetHeaders();
-
-      // Read it over the REST API.
-      $response = $this->httpRequest($this->getReadUrl($entity), 'GET');
-      $get_headers = $this->drupalGetHeaders();
-      $this->assertResponse('200', 'HTTP response code is correct.');
-
-      // Verify that the GET and HEAD responses are the same, that the only
-      // difference is that there's no body.
-      unset($get_headers['date']);
-      unset($head_headers['date']);
-      unset($get_headers['content-length']);
-      unset($head_headers['content-length']);
-      unset($get_headers['x-drupal-dynamic-cache']);
-      unset($head_headers['x-drupal-dynamic-cache']);
-      $this->assertIdentical($get_headers, $head_headers);
-      $this->assertResponse('200', 'HTTP response code is correct.');
-
-      $this->assertHeader('content-type', $this->defaultMimeType);
-      $data = Json::decode($response);
-      // Only assert one example property here, other properties should be
-      // checked in serialization tests.
-      if ($entity instanceof ConfigEntityInterface) {
-        $this->assertEqual($data['uuid'], $entity->uuid(), 'Entity UUID is correct');
-      }
-      else {
-        $this->assertEqual($data['uuid'][0]['value'], $entity->uuid(), 'Entity UUID is correct');
-      }
-
-      // Try to read the entity with an unsupported mime format.
-      $this->httpRequest($this->getReadUrl($entity, 'wrongformat'), 'GET');
-      $this->assertResponse(406);
-      $this->assertHeader('Content-type', 'application/json');
-
-      // Try to read an entity that does not exist.
-      $response = $this->httpRequest($this->getReadUrl($entity, $this->defaultFormat, 9999), 'GET');
-      $this->assertResponse(404);
-      switch ($entity_type) {
-        case 'node':
-          $path = '/node/{node}';
-          break;
-
-        case 'entity_test':
-          $path = '/entity_test/{entity_test}';
-          break;
-
-        default:
-          $path = "/entity/$entity_type/{" . $entity_type . '}';
-      }
-      $expected_message = Json::encode(['message' => 'The "' . $entity_type . '" parameter was not converted for the path "' . $path . '" (route name: "rest.entity.' . $entity_type . '.GET.hal_json")']);
-      $this->assertIdentical($expected_message, $response, 'Response message is correct.');
-
-      // Make sure that field level access works and that the according field is
-      // not available in the response. Only applies to entity_test.
-      // @see entity_test_entity_field_access()
-      if ($entity_type == 'entity_test') {
-        $entity->field_test_text->value = 'no access value';
-        $entity->save();
-        $response = $this->httpRequest($this->getReadUrl($entity), 'GET');
-        $this->assertResponse(200);
-        $this->assertHeader('content-type', $this->defaultMimeType);
-        $data = Json::decode($response);
-        $this->assertFalse(isset($data['field_test_text']), 'Field access protected field is not visible in the response.');
-      }
-    }
-    // Try to read a resource, the user entity, which is not REST API enabled.
-    $account = $this->drupalCreateUser();
-    $this->drupalLogin($account);
-    $response = $this->httpRequest($this->getReadUrl($account), 'GET');
-
-    // \Drupal\Core\Routing\RequestFormatRouteFilter considers the canonical,
-    // non-REST route a match, but a lower quality one: no format restrictions
-    // means there's always a match and hence when there is no matching REST
-    // route, the non-REST route is used, but can't render into
-    // application/hal+json, so it returns a 406.
-    $this->assertResponse('406', 'HTTP response code is 406 when the resource does not define formats, because it falls back to the canonical, non-REST route.');
-    $this->assertEqual($response, Json::encode([
-      'message' => 'Not acceptable format: hal_json',
-    ]));
-  }
-
-  /**
-   * Tests the resource structure.
-   */
-  public function testResourceStructure() {
-    // Enable a service with a format restriction but no authentication.
-    $this->enableService('entity:node', 'GET', 'json');
-    // Create a user account that has the required permissions to read
-    // resources via the REST API.
-    $permissions = $this->entityPermissions('node', 'view');
-    $account = $this->drupalCreateUser($permissions);
-    $this->drupalLogin($account);
-
-    // Create an entity programmatically.
-    $entity = $this->entityCreate('node');
-    $entity->save();
-
-    // Read it over the REST API.
-    $this->httpRequest($this->getReadUrl($entity, 'json'), 'GET');
-    $this->assertResponse('200', 'HTTP response code is correct.');
-  }
-
-  /**
-   * Gets the read URL object for the entity.
-   *
-   * @param \Drupal\Core\Entity\EntityInterface $entity
-   *   The entity to get the URL for.
-   * @param string $format
-   *   The format to request the entity in.
-   * @param string $entity_id
-   *   The entity ID to use in the URL, defaults to the entity's ID if know
-   *   given.
-   *
-   * @return \Drupal\Core\Url
-   *   The Url object.
-   */
-  protected function getReadUrl(EntityInterface $entity, $format = NULL, $entity_id = NULL) {
-    if (!$format) {
-      $format = $this->defaultFormat;
-    }
-    if (!$entity_id) {
-      $entity_id = $entity->id();
-    }
-    $entity_type = $entity->getEntityTypeId();
-    if ($entity->hasLinkTemplate('canonical')) {
-      $url = $entity->toUrl('canonical');
-    }
-    else {
-      $route_name = 'rest.entity.' . $entity_type . ".GET.";
-      // If testing unsupported format don't use the format to construct route
-      // name. This would give a RouteNotFoundException.
-      if ($format == 'wrongformat') {
-        $route_name .= $this->defaultFormat;
-      }
-      else {
-        $route_name .= $format;
-      }
-      $url = Url::fromRoute($route_name);
-    }
-    $url->setRouteParameter($entity_type, $entity_id);
-    $url->setRouteParameter('_format', $format);
-    return $url;
-  }
-
-}
diff --git a/core/modules/rest/src/Tests/UpdateTest.php b/core/modules/rest/src/Tests/UpdateTest.php
deleted file mode 100644
index d3784ed66691af025548a8bfd69d1478547c16db..0000000000000000000000000000000000000000
--- a/core/modules/rest/src/Tests/UpdateTest.php
+++ /dev/null
@@ -1,396 +0,0 @@
-<?php
-
-namespace Drupal\rest\Tests;
-
-use Drupal\comment\Entity\Comment;
-use Drupal\comment\Tests\CommentTestTrait;
-use Drupal\Component\Serialization\Json;
-use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Session\AccountInterface;
-use Drupal\entity_test\Entity\EntityTest;
-use Symfony\Component\HttpFoundation\Response;
-
-/**
- * Tests the update of resources.
- *
- * @group rest
- */
-class UpdateTest extends RESTTestBase {
-
-  use CommentTestTrait;
-
-  /**
-   * Modules to install.
-   *
-   * @var array
-   */
-  public static $modules = ['hal', 'rest', 'entity_test', 'node', 'comment'];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-    $this->addDefaultCommentField('entity_test', 'entity_test');
-  }
-
-  /**
-   * Tests several valid and invalid partial update requests on test entities.
-   */
-  public function testPatchUpdate() {
-    $serializer = $this->container->get('serializer');
-    // @todo Test all other entity types here as well.
-    $entity_type = 'entity_test';
-
-    $this->enableService('entity:' . $entity_type, 'PATCH');
-    // Create a user account that has the required permissions to create
-    // resources via the REST API.
-    $permissions = $this->entityPermissions($entity_type, 'update');
-    $account = $this->drupalCreateUser($permissions);
-    $this->drupalLogin($account);
-
-    $context = ['account' => $account];
-
-    // Create an entity and save it to the database.
-    $entity = $this->entityCreate($entity_type);
-    $entity->save();
-
-    // Create a second stub entity for overwriting a field.
-    $patch_values['field_test_text'] = array(0 => array(
-      'value' => $this->randomString(),
-      'format' => 'plain_text',
-    ));
-    $patch_entity = $this->container->get('entity_type.manager')
-      ->getStorage($entity_type)
-      ->create($patch_values);
-    // We don't want to overwrite the UUID.
-    $patch_entity->set('uuid', NULL);
-    $serialized = $serializer->serialize($patch_entity, $this->defaultFormat, $context);
-
-    // Update the entity over the REST API but forget to specify a Content-Type
-    // header, this should throw the proper exception.
-    $this->httpRequest($entity->toUrl(), 'PATCH', $serialized, 'none');
-    $this->assertResponse(Response::HTTP_UNSUPPORTED_MEDIA_TYPE);
-    $this->assertRaw('No route found that matches &quot;Content-Type: none&quot;');
-
-    // Update the entity over the REST API.
-    $response = $this->httpRequest($entity->urlInfo(), 'PATCH', $serialized, $this->defaultMimeType);
-    $this->assertResponse(200);
-
-    // Make sure that the response includes an entity in the body, check the
-    // updated field as an example.
-    $request = Json::decode($serialized);
-    $response = Json::decode($response);
-    $this->assertEqual($request['field_test_text'][0]['value'], $response['field_test_text'][0]['value']);
-    unset($request['_links']);
-    unset($response['_links']);
-    unset($response['id']);
-    unset($response['uuid']);
-    unset($response['name']);
-    $this->assertEqual($request, $response);
-
-    // Re-load updated entity from the database.
-    $storage = $this->container->get('entity_type.manager')
-      ->getStorage($entity_type);
-    $storage->resetCache([$entity->id()]);
-    $entity = $storage->load($entity->id());
-    $this->assertEqual($entity->field_test_text->value, $patch_entity->field_test_text->value, 'Field was successfully updated.');
-
-    // Make sure that the field does not get deleted if it is not present in the
-    // PATCH request.
-    $normalized = $serializer->normalize($patch_entity, $this->defaultFormat, $context);
-    unset($normalized['field_test_text']);
-    $serialized = $serializer->encode($normalized, $this->defaultFormat);
-    $this->httpRequest($entity->urlInfo(), 'PATCH', $serialized, $this->defaultMimeType);
-    $this->assertResponse(200);
-
-    $storage->resetCache([$entity->id()]);
-    $entity = $storage->load($entity->id());
-    $this->assertNotNull($entity->field_test_text->value . 'Test field has not been deleted.');
-
-    // Try to empty a field.
-    $normalized['field_test_text'] = array();
-    $serialized = $serializer->encode($normalized, $this->defaultFormat);
-
-    // Update the entity over the REST API.
-    $this->httpRequest($entity->urlInfo(), 'PATCH', $serialized, $this->defaultMimeType);
-    $this->assertResponse(200);
-
-    // Re-load updated entity from the database.
-    $storage->resetCache([$entity->id()]);
-    $entity = $storage->load($entity->id(), TRUE);
-    $this->assertNull($entity->field_test_text->value, 'Test field has been cleared.');
-
-    // Enable access protection for the text field.
-    // @see entity_test_entity_field_access()
-    $entity->field_test_text->value = 'no edit access value';
-    $entity->field_test_text->format = 'plain_text';
-    $entity->save();
-
-    // Try to empty a field that is access protected.
-    $this->httpRequest($entity->urlInfo(), 'PATCH', $serialized, $this->defaultMimeType);
-    $this->assertResponse(403);
-
-    // Re-load the entity from the database.
-    $storage->resetCache([$entity->id()]);
-    $entity = $storage->load($entity->id());
-    $this->assertEqual($entity->field_test_text->value, 'no edit access value', 'Text field was not deleted.');
-
-    // Try to update an access protected field.
-    $normalized = $serializer->normalize($patch_entity, $this->defaultFormat, $context);
-    $normalized['field_test_text'][0]['value'] = 'no access value';
-    $serialized = $serializer->serialize($normalized, $this->defaultFormat, $context);
-    $this->httpRequest($entity->urlInfo(), 'PATCH', $serialized, $this->defaultMimeType);
-    $this->assertResponse(403);
-
-    // Re-load the entity from the database.
-    $storage->resetCache([$entity->id()]);
-    $entity = $storage->load($entity->id());
-    $this->assertEqual($entity->field_test_text->value, 'no edit access value', 'Text field was not updated.');
-
-    // Try to update the field with a text format this user has no access to.
-    // First change the original field value so we're allowed to edit it again.
-    $entity->field_test_text->value = 'test';
-    $entity->save();
-    $patch_entity->set('field_test_text', array(
-      'value' => 'test',
-      'format' => 'full_html',
-    ));
-    $serialized = $serializer->serialize($patch_entity, $this->defaultFormat, $context);
-    $this->httpRequest($entity->urlInfo(), 'PATCH', $serialized, $this->defaultMimeType);
-    $this->assertResponse(422);
-
-    // Re-load the entity from the database.
-    $storage->resetCache([$entity->id()]);
-    $entity = $storage->load($entity->id());
-    $this->assertEqual($entity->field_test_text->format, 'plain_text', 'Text format was not updated.');
-
-    // Restore the valid test value.
-    $entity->field_test_text->value = $this->randomString();
-    $entity->save();
-
-    // Try to send no data at all, which does not make sense on PATCH requests.
-    $this->httpRequest($entity->urlInfo(), 'PATCH', NULL, $this->defaultMimeType);
-    $this->assertResponse(400);
-
-    // Try to update a non-existing entity with ID 9999.
-    $this->httpRequest($entity_type . '/9999', 'PATCH', $serialized, $this->defaultMimeType);
-    $this->assertResponse(404);
-    $storage->resetCache([9999]);
-    $loaded_entity = $storage->load(9999);
-    $this->assertFalse($loaded_entity, 'Entity 9999 was not created.');
-
-    // Try to send invalid data to trigger the entity validation constraints.
-    // Send a UUID that is too long.
-    $entity->set('uuid', $this->randomMachineName(129));
-    $invalid_serialized = $serializer->serialize($entity, $this->defaultFormat, $context);
-    $response = $this->httpRequest($entity->toUrl()->setRouteParameter('_format', $this->defaultFormat), 'PATCH', $invalid_serialized, $this->defaultMimeType);
-    $this->assertResponse(422);
-    $error = Json::decode($response);
-    $this->assertEqual($error['message'], "Unprocessable Entity: validation failed.\nuuid.0.value: <em class=\"placeholder\">UUID</em>: may not be longer than 128 characters.\n");
-
-    // Try to update an entity without proper permissions.
-    $this->drupalLogout();
-    $this->httpRequest($entity->urlInfo(), 'PATCH', $serialized, $this->defaultMimeType);
-    $this->assertResponse(403);
-
-    // Try to update a resource which is not REST API enabled.
-    $this->enableService(FALSE);
-    $this->drupalLogin($account);
-    $this->httpRequest($entity->urlInfo(), 'PATCH', $serialized, $this->defaultMimeType);
-    $this->assertResponse(405);
-  }
-
-  /**
-   * Tests several valid and invalid update requests for the 'user' entity type.
-   */
-  public function testUpdateUser() {
-    $serializer = $this->container->get('serializer');
-    $entity_type = 'user';
-    // Enables the REST service for 'user' entity type.
-    $this->enableService('entity:' . $entity_type, 'PATCH');
-    $permissions = $this->entityPermissions($entity_type, 'update');
-    $account = $this->drupalCreateUser($permissions);
-    $account->set('mail', 'old-email@example.com');
-    $this->drupalLogin($account);
-
-    // Create an entity and save it to the database.
-    $account->save();
-    $account->set('changed', NULL);
-
-    // Try and set a new email without providing the password.
-    $account->set('mail', 'new-email@example.com');
-    $context = ['account' => $account];
-    $normalized = $serializer->normalize($account, $this->defaultFormat, $context);
-    $serialized = $serializer->serialize($normalized, $this->defaultFormat, $context);
-    $response = $this->httpRequest($account->toUrl()->setRouteParameter('_format', $this->defaultFormat), 'PATCH', $serialized, $this->defaultMimeType);
-    $this->assertResponse(422);
-    $error = Json::decode($response);
-    $this->assertEqual($error['message'], "Unprocessable Entity: validation failed.\nmail: Your current password is missing or incorrect; it's required to change the <em class=\"placeholder\">Email</em>.\n");
-
-    // Try and send the new email with a password.
-    $normalized['pass'][0]['existing'] = 'wrong';
-    $serialized = $serializer->serialize($normalized, $this->defaultFormat, $context);
-    $response = $this->httpRequest($account->toUrl()->setRouteParameter('_format', $this->defaultFormat), 'PATCH', $serialized, $this->defaultMimeType);
-    $this->assertResponse(422);
-    $error = Json::decode($response);
-    $this->assertEqual($error['message'], "Unprocessable Entity: validation failed.\nmail: Your current password is missing or incorrect; it's required to change the <em class=\"placeholder\">Email</em>.\n");
-
-    // Try again with the password.
-    $normalized['pass'][0]['existing'] = $account->pass_raw;
-    $serialized = $serializer->serialize($normalized, $this->defaultFormat, $context);
-    $this->httpRequest($account->urlInfo(), 'PATCH', $serialized, $this->defaultMimeType);
-    $this->assertResponse(200);
-
-    // Try to change the password without providing the current password.
-    $new_password = $this->randomString();
-    $normalized = $serializer->normalize($account, $this->defaultFormat, $context);
-    $normalized['pass'][0]['value'] = $new_password;
-    $serialized = $serializer->serialize($normalized, $this->defaultFormat, $context);
-    $response = $this->httpRequest($account->toUrl()->setRouteParameter('_format', $this->defaultFormat), 'PATCH', $serialized, $this->defaultMimeType);
-    $this->assertResponse(422);
-    $error = Json::decode($response);
-    $this->assertEqual($error['message'], "Unprocessable Entity: validation failed.\npass: Your current password is missing or incorrect; it's required to change the <em class=\"placeholder\">Password</em>.\n");
-
-    // Try again with the password.
-    $normalized['pass'][0]['existing'] = $account->pass_raw;
-    $serialized = $serializer->serialize($normalized, $this->defaultFormat, $context);
-    $this->httpRequest($account->urlInfo(), 'PATCH', $serialized, $this->defaultMimeType);
-    $this->assertResponse(200);
-
-    // Verify that we can log in with the new password.
-    $account->pass_raw = $new_password;
-    $this->drupalLogin($account);
-  }
-
-  /**
-   * Test patching a comment using both HAL+JSON and JSON.
-   */
-  public function testUpdateComment() {
-    $entity_type = 'comment';
-    // Enables the REST service for 'comment' entity type.
-    $this->enableService('entity:' . $entity_type, 'PATCH', ['hal_json', 'json']);
-    $permissions = $this->entityPermissions($entity_type, 'update');
-    $account = $this->drupalCreateUser($permissions);
-    $account->set('mail', 'old-email@example.com');
-    $this->drupalLogin($account);
-
-    // Create & save an entity to comment on, plus a comment.
-    $entity_test = EntityTest::create();
-    $entity_test->save();
-    $entity_values = $this->entityValues($entity_type);
-    $entity_values['entity_id'] = $entity_test->id();
-    $entity_values['uid'] = $account->id();
-    $comment = Comment::create($entity_values);
-    $comment->save();
-
-    $this->pass('Test case 1: PATCH comment using HAL+JSON.');
-    $comment->setSubject('Initial subject')->save();
-    $read_only_fields = [
-      'name',
-      'created',
-      'changed',
-      'status',
-      'thread',
-      'entity_type',
-      'field_name',
-      'entity_id',
-      'uid',
-    ];
-    $this->assertNotEqual('Updated subject', $comment->getSubject());
-    $comment->setSubject('Updated subject');
-    $this->patchEntity($comment, $read_only_fields, $account, 'hal_json', 'application/hal+json');
-    $comment = Comment::load($comment->id());
-    $this->assertEqual('Updated subject', $comment->getSubject());
-
-    $this->pass('Test case 1: PATCH comment using JSON.');
-    $comment->setSubject('Initial subject')->save();
-    $read_only_fields = [
-      'pid', // Extra compared to HAL+JSON.
-      'entity_id',
-      'uid',
-      'name',
-      'homepage', // Extra compared to HAL+JSON.
-      'created',
-      'changed',
-      'status',
-      'thread',
-      'entity_type',
-      'field_name',
-    ];
-    $this->assertNotEqual('Updated subject', $comment->getSubject());
-    $comment->setSubject('Updated subject');
-    $this->patchEntity($comment, $read_only_fields, $account, 'json', 'application/json');
-    $comment = Comment::load($comment->id());
-    $this->assertEqual('Updated subject', $comment->getSubject());
-  }
-
-  /**
-   * Patches an existing entity using the passed in (modified) entity.
-   *
-   * @param \Drupal\Core\Entity\EntityInterface $entity
-   *   The updated entity to send.
-   * @param string[] $read_only_fields
-   *   Names of the fields that are read-only, in validation order.
-   * @param \Drupal\Core\Session\AccountInterface $account
-   *   The account to use for serialization.
-   * @param string $format
-   *   A serialization format.
-   * @param string $mime_type
-   *   The MIME type corresponding to the specified serialization format.
-   */
-  protected function patchEntity(EntityInterface $entity, array $read_only_fields, AccountInterface $account, $format, $mime_type) {
-    $serializer = $this->container->get('serializer');
-
-    $url = $entity->toUrl()->setRouteParameter('_format', $this->defaultFormat);
-    $context = ['account' => $account];
-    // Certain fields are always read-only, others this user simply is not
-    // allowed to modify. For all of them, ensure they are not serialized, else
-    // we'll get a 403 plus an error message.
-    for ($i = 0; $i < count($read_only_fields); $i++) {
-      $field = $read_only_fields[$i];
-
-      $normalized = $serializer->normalize($entity, $format, $context);
-      if ($format !== 'hal_json') {
-        // The default normalizer always keeps fields, even if they are unset
-        // here because they should be omitted during a PATCH request. Therefore
-        // manually strip them
-        // @see \Drupal\Core\Entity\ContentEntityBase::__unset()
-        // @see \Drupal\serialization\Normalizer\EntityNormalizer::normalize()
-        // @see \Drupal\hal\Normalizer\ContentEntityNormalizer::normalize()
-        $read_only_fields_so_far = array_slice($read_only_fields, 0, $i);
-        $normalized = array_diff_key($normalized, array_flip($read_only_fields_so_far));
-      }
-      $serialized = $serializer->serialize($normalized, $format, $context);
-
-      $this->httpRequest($url, 'PATCH', $serialized, $mime_type);
-      $this->assertResponse(403);
-      $this->assertResponseBody('{"message":"Access denied on updating field \\u0027' . $field . '\\u0027."}');
-
-      if ($format === 'hal_json') {
-        // We've just tried with this read-only field, now unset it.
-        $entity->set($field, NULL);
-      }
-    }
-
-    // Finally, with all read-only fields unset, the request should succeed.
-    $normalized = $serializer->normalize($entity, $format, $context);
-    if ($format !== 'hal_json') {
-      $normalized = array_diff_key($normalized, array_combine($read_only_fields, $read_only_fields));
-    }
-    $serialized = $serializer->serialize($normalized, $format, $context);
-
-    // Try first without CSRF token which should fail.
-    $this->httpRequest($url, 'PATCH', $serialized, $mime_type, FALSE);
-    $this->assertResponse(403);
-    $this->assertRaw('X-CSRF-Token request header is missing');
-    // Then try with an invalid CSRF token.
-    $this->httpRequest($url, 'PATCH', $serialized, $mime_type, 'invalid-csrf-token');
-    $this->assertResponse(403);
-    $this->assertRaw('X-CSRF-Token request header is invalid');
-    // Then try with CSRF token.
-    $this->httpRequest($url, 'PATCH', $serialized, $mime_type);
-    $this->assertResponse(200);
-  }
-
-}
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
index 70b1de7638b3162b91bd33a8d33eb77d6bbac8dc..c946967d35ff284b2b282273ab4a806b506e7520 100644
--- a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
+++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
@@ -977,6 +977,7 @@ protected function assertNormalizationEdgeCases($method, Url $url, array $reques
 
 
         // DX: 400 when incorrect entity type bundle is specified.
+        // @todo Change to 422 in https://www.drupal.org/node/2827084.
         $response = $this->request($method, $url, $request_options);
         // @todo use this commented line instead of the 3 lines thereafter once https://www.drupal.org/node/2813853 lands.
         //      $this->assertResourceErrorResponse(400, '"bad_bundle_name" is not a valid bundle type for denormalization.', $response);
@@ -991,6 +992,7 @@ protected function assertNormalizationEdgeCases($method, Url $url, array $reques
 
 
       // DX: 400 when no entity type bundle is specified.
+      // @todo Change to 422 in https://www.drupal.org/node/2827084.
       $response = $this->request($method, $url, $request_options);
       // @todo use this commented line instead of the 3 lines thereafter once https://www.drupal.org/node/2813853 lands.
       // $this->assertResourceErrorResponse(400, 'A string must be provided as a bundle value.', $response);