diff core/modules/media/tests/src/Functional/MediaAccessTest.php @ 18:af1871eacc83

Update to Drupal core 8.7.1
author Chris Cannam
date Thu, 09 May 2019 15:33:08 +0100
parents 129ea1e6d783
children
line wrap: on
line diff
--- a/core/modules/media/tests/src/Functional/MediaAccessTest.php	Thu Feb 28 13:21:36 2019 +0000
+++ b/core/modules/media/tests/src/Functional/MediaAccessTest.php	Thu May 09 15:33:08 2019 +0100
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\media\Functional;
 
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\media\Entity\Media;
 use Drupal\Tests\system\Functional\Cache\AssertPageCacheContextsAndTagsTrait;
 use Drupal\user\Entity\Role;
@@ -38,8 +40,14 @@
    */
   public function testMediaAccess() {
     $assert_session = $this->assertSession();
+    $media_type = $this->createMediaType('test');
 
-    $media_type = $this->createMediaType('test');
+    \Drupal::configFactory()
+      ->getEditable('media.settings')
+      ->set('standalone_url', TRUE)
+      ->save(TRUE);
+
+    $this->container->get('router.builder')->rebuild();
 
     // Create media.
     $media = Media::create([
@@ -72,17 +80,7 @@
     /** @var \Drupal\user\RoleInterface $role */
     $role = Role::load(RoleInterface::AUTHENTICATED_ID);
 
-    // Test 'view media' permission.
     user_role_revoke_permissions($role->id(), ['view media']);
-    $this->drupalGet('media/' . $media->id());
-    $this->assertCacheContext('user.permissions');
-    $assert_session->statusCodeEquals(403);
-    $access_result = $media->access('view', NULL, TRUE);
-    $this->assertSame("The 'view media' permission is required and the media item must be published.", $access_result->getReason());
-    $this->grantPermissions($role, ['view media']);
-    $this->drupalGet('media/' . $media->id());
-    $this->assertCacheContext('user.permissions');
-    $assert_session->statusCodeEquals(200);
 
     // Test 'create BUNDLE media' permission.
     $this->drupalGet('media/add/' . $media_type->id());
@@ -96,6 +94,24 @@
     user_role_revoke_permissions($role->id(), $permissions);
     $role = Role::load(RoleInterface::AUTHENTICATED_ID);
 
+    // Verify the author can not view the unpublished media item without
+    // 'view own unpublished media' permission.
+    $this->grantPermissions($role, ['view media']);
+    $this->drupalGet('media/' . $user_media->id());
+    $this->assertNoCacheContext('user');
+    $this->assertCacheContext('user.permissions');
+    $assert_session->statusCodeEquals(200);
+    $user_media->setUnpublished()->save();
+    $this->drupalGet('media/' . $user_media->id());
+    $this->assertCacheContext('user.permissions');
+    $assert_session->statusCodeEquals(403);
+    $access_result = $user_media->access('view', NULL, TRUE);
+    $this->assertSame("The user must be the owner and the 'view own unpublished media' permission is required when the media item is unpublished.", $access_result->getReason());
+    $this->grantPermissions($role, ['view own unpublished media']);
+    $this->drupalGet('media/' . $user_media->id());
+    $this->assertCacheContext('user');
+    $assert_session->statusCodeEquals(200);
+
     // Test 'create media' permission.
     $this->drupalGet('media/add/' . $media_type->id());
     $this->assertCacheContext('user.permissions');
@@ -171,4 +187,217 @@
     $assert_session->linkByHrefExists('/media/' . $user_media->id());
   }
 
+  /**
+   * Test view access control on the canonical page.
+   */
+  public function testCanonicalMediaAccess() {
+    $media_type = $this->createMediaType('test');
+    $assert_session = $this->assertSession();
+
+    \Drupal::configFactory()
+      ->getEditable('media.settings')
+      ->set('standalone_url', TRUE)
+      ->save(TRUE);
+
+    $this->container->get('router.builder')->rebuild();
+
+    // Create media.
+    $media = Media::create([
+      'bundle' => $media_type->id(),
+      'name' => 'Unnamed',
+    ]);
+    $media->save();
+    $user_media = Media::create([
+      'bundle' => $media_type->id(),
+      'name' => 'Unnamed',
+      'uid' => $this->nonAdminUser->id(),
+    ]);
+    $user_media->save();
+
+    $this->drupalLogin($this->nonAdminUser);
+    /** @var \Drupal\user\RoleInterface $role */
+    $role = Role::load(RoleInterface::AUTHENTICATED_ID);
+
+    user_role_revoke_permissions($role->id(), ['view media']);
+
+    $this->drupalGet('media/' . $media->id());
+    $this->assertCacheContext('user.permissions');
+    $assert_session->statusCodeEquals(403);
+    $access_result = $media->access('view', NULL, TRUE);
+    $this->assertSame("The 'view media' permission is required when the media item is published.", $access_result->getReason());
+    $this->grantPermissions($role, ['view media']);
+    $this->drupalGet('media/' . $media->id());
+    $this->assertCacheContext('user.permissions');
+    $assert_session->statusCodeEquals(200);
+  }
+
+  /**
+   * Tests unpublished media access.
+   */
+  public function testUnpublishedMediaUserAccess() {
+    \Drupal::configFactory()
+      ->getEditable('media.settings')
+      ->set('standalone_url', TRUE)
+      ->save(TRUE);
+
+    $this->container->get('router.builder')->rebuild();
+
+    $assert_session = $this->assertSession();
+    $media_type = $this->createMediaType('test');
+    $permissions = [
+      'view media',
+      'view own unpublished media',
+    ];
+    $user_one = $this->drupalCreateUser($permissions);
+    $user_two = $this->drupalCreateUser($permissions);
+
+    // Create media as user one.
+    $user_media = Media::create([
+      'bundle' => $media_type->id(),
+      'name' => 'Unnamed',
+      'uid' => $user_one->id(),
+    ]);
+    $user_media->setUnpublished()->save();
+
+    // Make sure user two can't access unpublished media.
+    $this->drupalLogin($user_two);
+    $this->drupalGet('media/' . $user_media->id());
+    $assert_session->statusCodeEquals(403);
+    $this->assertCacheContext('user');
+    $this->drupalLogout();
+
+    // Make sure user one can access own unpublished media.
+    $this->drupalLogin($user_one);
+    $this->drupalGet('media/' . $user_media->id());
+    $assert_session->statusCodeEquals(200);
+    $this->assertCacheContext('user');
+  }
+
+  /**
+   * Tests media access of anonymous user.
+   */
+  public function testMediaAnonymousUserAccess() {
+    \Drupal::configFactory()
+      ->getEditable('media.settings')
+      ->set('standalone_url', TRUE)
+      ->save(TRUE);
+
+    $this->container->get('router.builder')->rebuild();
+
+    $assert_session = $this->assertSession();
+    $media_type = $this->createMediaType('test');
+
+    // Create media as anonymous user.
+    $user_media = Media::create([
+      'bundle' => $media_type->id(),
+      'name' => 'Unnamed',
+      'uid' => 0,
+    ]);
+    $user_media->save();
+
+    $role = Role::load(RoleInterface::ANONYMOUS_ID);
+    $this->grantPermissions($role, ['view media', 'view own unpublished media']);
+    $this->drupalLogout();
+
+    // Make sure anonymous users can access published media.
+    $user_media->setPublished()->save();
+    $this->drupalGet('media/' . $user_media->id());
+    $assert_session->statusCodeEquals(200);
+
+    // Make sure anonymous users can not access unpublished media
+    // even though role has 'view own unpublished media' permission.
+    $user_media->setUnpublished()->save();
+    $this->drupalGet('media/' . $user_media->id());
+    $assert_session->statusCodeEquals(403);
+    $this->assertCacheContext('user');
+  }
+
+  /**
+   * Tests access for embedded medias.
+   */
+  public function testReferencedRendering() {
+    \Drupal::configFactory()
+      ->getEditable('media.settings')
+      ->set('standalone_url', TRUE)
+      ->save(TRUE);
+
+    $this->container->get('router.builder')->rebuild();
+
+    // Create a media type and a entity reference to itself.
+    $media_type = $this->createMediaType('test');
+
+    FieldStorageConfig::create([
+      'field_name' => 'field_reference',
+      'entity_type' => 'media',
+      'type' => 'entity_reference',
+      'settings' => [
+        'target_type' => 'media',
+      ],
+    ])->save();
+
+    FieldConfig::create([
+      'field_name' => 'field_reference',
+      'entity_type' => 'media',
+      'bundle' => $media_type->id(),
+    ])->save();
+
+    $author = $this->drupalCreateUser([
+      'view media',
+      'view own unpublished media',
+    ]);
+    $other_user = $this->drupalCreateUser([
+      'view media',
+      'view own unpublished media',
+    ]);
+    $view_user = $this->drupalCreateUser(['view media']);
+
+    $child_title = 'Child media';
+    $media_child = Media::create([
+      'name' => $child_title,
+      'bundle' => $media_type->id(),
+      'uid' => $author->id(),
+    ]);
+    $media_child->setUnpublished()->save();
+
+    $media_parent = Media::create([
+      'name' => 'Parent media',
+      'bundle' => $media_type->id(),
+      'field_reference' => $media_child->id(),
+    ]);
+    $media_parent->save();
+
+    entity_get_display('media', $media_type->id(), 'full')
+      ->set('content', [])
+      ->setComponent('title', ['type' => 'string'])
+      ->setComponent('field_reference', [
+        'type' => 'entity_reference_label',
+      ])
+      ->save();
+
+    $assert_session = $this->assertSession();
+
+    // The author of the child media items should have access to both the parent
+    // and child.
+    $this->drupalLogin($author);
+    $this->drupalGet($media_parent->toUrl());
+    $this->assertCacheContext('user');
+    $assert_session->pageTextContains($child_title);
+
+    // Other users with the 'view own unpublished media' permission should not
+    // be able to see the unpublished child media item. The 'user' cache context
+    // should be added in this case.
+    $this->drupalLogin($other_user);
+    $this->drupalGet($media_parent->toUrl());
+    $this->assertCacheContext('user');
+    $assert_session->pageTextNotContains($child_title);
+
+    // User with just the 'view media' permission should not be able to see the
+    // child media item. The 'user' cache context should not be added in this
+    // case.
+    $this->drupalLogin($view_user);
+    $this->drupalGet($media_parent->toUrl());
+    $this->assertNoCacheContext('user');
+    $assert_session->pageTextNotContains($child_title);
+  }
+
 }