Security update for Core, with self-updated composer
[yaffs-website] / web / core / modules / rest / tests / src / Functional / EntityResource / Node / NodeResourceTestBase.php
index cfbd971611da5eec6979957377df169f670ead2c..492ff642e42eb4ae40d16ce221436ff30d961e30 100644 (file)
@@ -4,15 +4,19 @@ namespace Drupal\Tests\rest\Functional\EntityResource\Node;
 
 use Drupal\node\Entity\Node;
 use Drupal\node\Entity\NodeType;
+use Drupal\Tests\rest\Functional\BcTimestampNormalizerUnixTestTrait;
 use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
 use Drupal\user\Entity\User;
+use GuzzleHttp\RequestOptions;
 
 abstract class NodeResourceTestBase extends EntityResourceTestBase {
 
+  use BcTimestampNormalizerUnixTestTrait;
+
   /**
    * {@inheritdoc}
    */
-  public static $modules = ['node'];
+  public static $modules = ['node', 'path'];
 
   /**
    * {@inheritdoc}
@@ -23,13 +27,13 @@ abstract class NodeResourceTestBase extends EntityResourceTestBase {
    * {@inheritdoc}
    */
   protected static $patchProtectedFieldNames = [
-    'uid',
+    'revision_timestamp',
+    'revision_uid',
     'created',
     'changed',
     'promote',
     'sticky',
-    'revision_timestamp',
-    'revision_uid',
+    'path',
   ];
 
   /**
@@ -49,6 +53,10 @@ abstract class NodeResourceTestBase extends EntityResourceTestBase {
         $this->grantPermissionsToTestedRole(['access content', 'create camelids content']);
         break;
       case 'PATCH':
+        // Do not grant the 'create url aliases' permission to test the case
+        // when the path field is protected/not accessible, see
+        // \Drupal\Tests\rest\Functional\EntityResource\Term\TermResourceTestBase
+        // for a positive test.
         $this->grantPermissionsToTestedRole(['access content', 'edit any camelids content']);
         break;
       case 'DELETE':
@@ -77,6 +85,7 @@ abstract class NodeResourceTestBase extends EntityResourceTestBase {
       ->setCreatedTime(123456789)
       ->setChangedTime(123456789)
       ->setRevisionCreationTime(123456789)
+      ->set('path', '/llama')
       ->save();
 
     return $node;
@@ -120,14 +129,10 @@ abstract class NodeResourceTestBase extends EntityResourceTestBase {
         ],
       ],
       'created' => [
-        [
-          'value' => 123456789,
-        ],
+        $this->formatExpectedTimestampItemValues(123456789),
       ],
       'changed' => [
-        [
-          'value' => $this->entity->getChangedTime(),
-        ],
+        $this->formatExpectedTimestampItemValues($this->entity->getChangedTime()),
       ],
       'promote' => [
         [
@@ -140,9 +145,7 @@ abstract class NodeResourceTestBase extends EntityResourceTestBase {
         ],
       ],
       'revision_timestamp' => [
-        [
-          'value' => 123456789,
-        ],
+        $this->formatExpectedTimestampItemValues(123456789),
       ],
       'revision_translation_affected' => [
         [
@@ -171,6 +174,13 @@ abstract class NodeResourceTestBase extends EntityResourceTestBase {
         ],
       ],
       'revision_log' => [],
+      'path' => [
+        [
+          'alias' => '/llama',
+          'pid' => 1,
+          'langcode' => 'en',
+        ],
+      ],
     ];
   }
 
@@ -206,4 +216,60 @@ abstract class NodeResourceTestBase extends EntityResourceTestBase {
     return parent::getExpectedUnauthorizedAccessMessage($method);
   }
 
+  /**
+   * Tests PATCHing a node's path with and without 'create url aliases'.
+   *
+   * For a positive test, see the similar test coverage for Term.
+   *
+   * @see \Drupal\Tests\rest\Functional\EntityResource\Term\TermResourceTestBase::testPatchPath()
+   */
+  public function testPatchPath() {
+    $this->initAuthentication();
+    $this->provisionEntityResource();
+    $this->setUpAuthorization('GET');
+    $this->setUpAuthorization('PATCH');
+
+    $url = $this->getEntityResourceUrl()->setOption('query', ['_format' => static::$format]);
+
+    // GET node's current normalization.
+    $response = $this->request('GET', $url, $this->getAuthenticationRequestOptions('GET'));
+    $normalization = $this->serializer->decode((string) $response->getBody(), static::$format);
+
+    // @todo In https://www.drupal.org/node/2824851, we will be able to stop
+    //       unsetting these fields from the normalization, because
+    //       EntityResource::patch() will ignore any fields that are sent that
+    //       match the current value (and obviously we're sending the current
+    //       value).
+    $normalization = $this->removeFieldsFromNormalization($normalization, [
+      'revision_timestamp',
+      'revision_uid',
+      'created',
+      'changed',
+      'promote',
+      'sticky',
+    ]);
+
+    // Change node's path alias.
+    $normalization['path'][0]['alias'] .= 's-rule-the-world';
+
+    // Create node PATCH request.
+    $request_options = [];
+    $request_options[RequestOptions::HEADERS]['Content-Type'] = static::$mimeType;
+    $request_options = array_merge_recursive($request_options, $this->getAuthenticationRequestOptions('PATCH'));
+    $request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format);
+
+    // PATCH request: 403 when creating URL aliases unauthorized.
+    $response = $this->request('PATCH', $url, $request_options);
+    $this->assertResourceErrorResponse(403, "Access denied on updating field 'path'.", $response);
+
+    // Grant permission to create URL aliases.
+    $this->grantPermissionsToTestedRole(['create url aliases']);
+
+    // Repeat PATCH request: 200.
+    $response = $this->request('PATCH', $url, $request_options);
+    $this->assertResourceResponse(200, FALSE, $response);
+    $updated_normalization = $this->serializer->decode((string) $response->getBody(), static::$format);
+    $this->assertSame($normalization['path'], $updated_normalization['path']);
+  }
+
 }