3 namespace Drupal\Tests\editor\Functional;
5 use Drupal\file\Entity\File;
6 use Drupal\Tests\BrowserTestBase;
7 use Drupal\user\Entity\Role;
8 use Drupal\user\RoleInterface;
11 * Tests Editor module's file reference filter with private files.
15 class EditorPrivateFileReferenceFilterTest extends BrowserTestBase {
22 public static $modules = [
23 // Needed for the config: this is the only module in core that utilizes the
24 // functionality in editor.module to be tested, and depends on that.
26 // Depends on filter.module (indirectly).
28 // Pulls in the config we're using during testing which create a text format
29 // - with the filter_html_image_secure filter DISABLED,
30 // - with the editor set to CKEditor,
31 // - with drupalimage.image_upload.scheme set to 'private',
32 // - with drupalimage.image_upload.directory set to ''.
33 'editor_private_test',
37 * Tests the editor file reference filter with private files.
39 public function testEditorPrivateFileReferenceFilter() {
40 $author = $this->drupalCreateUser();
41 $this->drupalLogin($author);
43 // Create a content type with a body field.
44 $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']);
46 // Create a file in the 'private:// ' stream.
47 $filename = 'test.png';
48 $src = '/system/files/' . $filename;
49 /** @var \Drupal\file\FileInterface $file */
50 $file = File::create([
51 'uri' => 'private://' . $filename,
53 $file->setTemporary();
54 $file->setOwner($author);
55 // Create the file itself.
56 file_put_contents($file->getFileUri(), $this->randomString());
59 // The image should be visible for its author.
60 $this->drupalGet($src);
61 $this->assertSession()->statusCodeEquals(200);
62 // The not-yet-permanent image should NOT be visible for anonymous.
63 $this->drupalLogout();
64 $this->drupalGet($src);
65 $this->assertSession()->statusCodeEquals(403);
67 // Resave the file to be permanent.
68 $file->setPermanent();
71 // Create some nodes to ensure file usage count does not match the ID's
72 // of the nodes we are going to check.
73 for ($i = 0; $i < 5; $i++) {
74 $this->drupalCreateNode([
76 'uid' => $author->id(),
80 // Create a node with its body field properly pointing to the just-created
82 $published_node = $this->drupalCreateNode([
85 'value' => '<img alt="alt" data-entity-type="file" data-entity-uuid="' . $file->uuid() . '" src="' . $src . '" />',
86 'format' => 'private_images',
88 'uid' => $author->id(),
91 // Create an unpublished node with its body field properly pointing to the
93 $unpublished_node = $this->drupalCreateNode([
95 'status' => NODE_NOT_PUBLISHED,
97 'value' => '<img alt="alt" data-entity-type="file" data-entity-uuid="' . $file->uuid() . '" src="' . $src . '" />',
98 'format' => 'private_images',
100 'uid' => $author->id(),
103 // Do the actual test. The image should be visible for anonymous users,
104 // because they can view the published node. Even though they can't view
105 // the unpublished node.
106 $this->drupalGet($published_node->toUrl());
107 $this->assertSession()->statusCodeEquals(200);
108 $this->drupalGet($unpublished_node->toUrl());
109 $this->assertSession()->statusCodeEquals(403);
110 $this->drupalGet($src);
111 $this->assertSession()->statusCodeEquals(200);
113 // When the published node is also unpublished, the image should also
114 // become inaccessible to anonymous users.
115 $published_node->setPublished(FALSE)->save();
117 $this->drupalGet($published_node->toUrl());
118 $this->assertSession()->statusCodeEquals(403);
119 $this->drupalGet($src);
120 $this->assertSession()->statusCodeEquals(403);
122 // Disallow anonymous users to view the entity, which then should also
123 // disallow them to view the image.
124 $published_node->setPublished(TRUE)->save();
125 Role::load(RoleInterface::ANONYMOUS_ID)
126 ->revokePermission('access content')
128 $this->drupalGet($published_node->toUrl());
129 $this->assertSession()->statusCodeEquals(403);
130 $this->drupalGet($src);
131 $this->assertSession()->statusCodeEquals(403);