3 namespace Drupal\file\Tests;
5 use Drupal\node\Entity\Node;
6 use Drupal\file\Entity\File;
7 use Drupal\entity_test\Entity\EntityTestConstraints;
10 * Tests file listing page functionality.
14 class FileListingTest extends FileFieldTestBase {
21 public static $modules = ['views', 'file', 'image', 'entity_test'];
24 * An authenticated user.
26 * @var \Drupal\user\UserInterface
30 protected function setUp() {
33 $this->adminUser = $this->drupalCreateUser(['access files overview', 'bypass node access']);
34 $this->baseUser = $this->drupalCreateUser();
35 $this->createFileField('file', 'node', 'article', [], ['file_extensions' => 'txt png']);
39 * Calculates total count of usages for a file.
42 * Array of file usage information as returned from file_usage subsystem.
46 protected function sumUsages($usage) {
48 foreach ($usage as $module) {
49 foreach ($module as $entity_type) {
50 foreach ($entity_type as $entity) {
60 * Tests file overview with different user permissions.
62 public function testFileListingPages() {
63 $file_usage = $this->container->get('file.usage');
64 // Users without sufficient permissions should not see file listing.
65 $this->drupalLogin($this->baseUser);
66 $this->drupalGet('admin/content/files');
67 $this->assertResponse(403);
69 // Log in with user with right permissions and test listing.
70 $this->drupalLogin($this->adminUser);
72 for ($i = 0; $i < 5; $i++) {
73 $nodes[] = $this->drupalCreateNode(['type' => 'article']);
76 $this->drupalGet('admin/content/files');
77 $this->assertResponse(200);
78 $this->assertText('No files available.');
79 $this->drupalGet('admin/content/files');
80 $this->assertResponse(200);
82 // Create a file with no usage.
83 $file = $this->createFile();
85 $this->drupalGet('admin/content/files/usage/' . $file->id());
86 $this->assertResponse(200);
87 $this->assertTitle(t('File usage information for @file | Drupal', ['@file' => $file->getFilename()]));
89 foreach ($nodes as &$node) {
90 $this->drupalGet('node/' . $node->id() . '/edit');
91 $file = $this->getTestFile('image');
94 'files[file_0]' => drupal_realpath($file->getFileUri()),
96 $this->drupalPostForm(NULL, $edit, t('Save'));
97 $node = Node::load($node->id());
100 $this->drupalGet('admin/content/files');
102 foreach ($nodes as $node) {
103 $file = File::load($node->file->target_id);
104 $this->assertText($file->getFilename());
105 $this->assertLinkByHref(file_create_url($file->getFileUri()));
106 $this->assertLinkByHref('admin/content/files/usage/' . $file->id());
108 $this->assertFalse(preg_match('/views-field-status priority-low\">\s*' . t('Temporary') . '/', $this->getRawContent()), 'All files are stored as permanent.');
110 // Use one file two times and check usage information.
111 $orphaned_file = $nodes[1]->file->target_id;
112 $used_file = $nodes[0]->file->target_id;
113 $nodes[1]->file->target_id = $used_file;
116 $this->drupalGet('admin/content/files');
117 $file = File::load($orphaned_file);
118 $usage = $this->sumUsages($file_usage->listUsage($file));
119 $this->assertRaw('admin/content/files/usage/' . $file->id() . '">' . $usage);
121 $file = File::load($used_file);
122 $usage = $this->sumUsages($file_usage->listUsage($file));
123 $this->assertRaw('admin/content/files/usage/' . $file->id() . '">' . $usage);
125 $result = $this->xpath("//td[contains(@class, 'views-field-status') and contains(text(), :value)]", [':value' => t('Temporary')]);
126 $this->assertEqual(1, count($result), 'Unused file marked as temporary.');
128 // Test file usage page.
129 foreach ($nodes as $node) {
130 $file = File::load($node->file->target_id);
131 $usage = $file_usage->listUsage($file);
132 $this->drupalGet('admin/content/files/usage/' . $file->id());
133 $this->assertResponse(200);
134 $this->assertText($node->getTitle(), 'Node title found on usage page.');
135 $this->assertText('node', 'Registering entity type found on usage page.');
136 $this->assertText('file', 'Registering module found on usage page.');
137 foreach ($usage as $module) {
138 foreach ($module as $entity_type) {
139 foreach ($entity_type as $entity) {
140 $this->assertText($entity, 'Usage count found on usage page.');
144 $this->assertLinkByHref('node/' . $node->id(), 0, 'Link to registering entity found on usage page.');
149 * Tests file listing usage page for entities with no canonical link template.
151 public function testFileListingUsageNoLink() {
152 // Login with user with right permissions and test listing.
153 $this->drupalLogin($this->adminUser);
155 // Create a bundle and attach a File field to the bundle.
156 $bundle = $this->randomMachineName();
157 entity_test_create_bundle($bundle, NULL, 'entity_test_constraints');
158 $this->createFileField('field_test_file', 'entity_test_constraints', $bundle, [], ['file_extensions' => 'txt png']);
160 // Create file to attach to entity.
161 $file = File::create([
162 'filename' => 'druplicon.txt',
163 'uri' => 'public://druplicon.txt',
164 'filemime' => 'text/plain',
166 $file->setPermanent();
167 file_put_contents($file->getFileUri(), 'hello world');
170 // Create entity and attach the created file.
171 $entity_name = $this->randomMachineName();
172 $entity = EntityTestConstraints::create([
174 'name' => $entity_name,
176 'field_test_file' => [
177 'target_id' => $file->id(),
182 // Create node entity and attach the created file.
183 $node = $this->drupalCreateNode(['type' => 'article', 'file' => $file]);
186 // Load the file usage page for the created and attached file.
187 $this->drupalGet('admin/content/files/usage/' . $file->id());
189 $this->assertResponse(200);
190 // Entity name should be displayed, but not linked if Entity::toUrl
191 // throws an exception
192 $this->assertText($entity_name, 'Entity name is added to file usage listing.');
193 $this->assertNoLink($entity_name, 'Linked entity name not added to file usage listing.');
194 $this->assertLink($node->getTitle());
198 * Creates and saves a test file.
200 * @return \Drupal\Core\Entity\EntityInterface
203 protected function createFile() {
204 // Create a new file entity.
205 $file = File::create([
207 'filename' => 'druplicon.txt',
208 'uri' => 'public://druplicon.txt',
209 'filemime' => 'text/plain',
212 'status' => FILE_STATUS_PERMANENT,
214 file_put_contents($file->getFileUri(), 'hello world');
216 // Save it, inserting a new record.