e348949a737dc37ee05d93aed223f8567965d85e
[yaffs-website] / web / core / modules / file / src / Tests / FileListingTest.php
1 <?php
2
3 namespace Drupal\file\Tests;
4
5 use Drupal\node\Entity\Node;
6 use Drupal\file\Entity\File;
7 use Drupal\entity_test\Entity\EntityTestConstraints;
8
9 /**
10  * Tests file listing page functionality.
11  *
12  * @group file
13  */
14 class FileListingTest extends FileFieldTestBase {
15
16   /**
17    * Modules to enable.
18    *
19    * @var array
20    */
21   public static $modules = ['views', 'file', 'image', 'entity_test'];
22
23   /**
24    * An authenticated user.
25    *
26    * @var \Drupal\user\UserInterface
27    */
28   protected $baseUser;
29
30   protected function setUp() {
31     parent::setUp();
32
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']);
36   }
37
38   /**
39    * Calculates total count of usages for a file.
40    *
41    * @param $usage array
42    *   Array of file usage information as returned from file_usage subsystem.
43    * @return int
44    *   Total usage count.
45    */
46   protected function sumUsages($usage) {
47     $count = 0;
48     foreach ($usage as $module) {
49       foreach ($module as $entity_type) {
50         foreach ($entity_type as $entity) {
51           $count += $entity;
52         }
53       }
54     }
55
56     return $count;
57   }
58
59   /**
60    * Tests file overview with different user permissions.
61    */
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);
68
69     // Log in with user with right permissions and test listing.
70     $this->drupalLogin($this->adminUser);
71
72     for ($i = 0; $i < 5; $i++) {
73       $nodes[] = $this->drupalCreateNode(['type' => 'article']);
74     }
75
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);
81
82     // Create a file with no usage.
83     $file = $this->createFile();
84
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()]));
88
89     foreach ($nodes as &$node) {
90       $this->drupalGet('node/' . $node->id() . '/edit');
91       $file = $this->getTestFile('image');
92
93       $edit = [
94         'files[file_0]' => drupal_realpath($file->getFileUri()),
95       ];
96       $this->drupalPostForm(NULL, $edit, t('Save'));
97       $node = Node::load($node->id());
98     }
99
100     $this->drupalGet('admin/content/files');
101
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());
107     }
108     $this->assertFalse(preg_match('/views-field-status priority-low\">\s*' . t('Temporary') . '/', $this->getRawContent()), 'All files are stored as permanent.');
109
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;
114     $nodes[1]->save();
115
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);
120
121     $file = File::load($used_file);
122     $usage = $this->sumUsages($file_usage->listUsage($file));
123     $this->assertRaw('admin/content/files/usage/' . $file->id() . '">' . $usage);
124
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.');
127
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.');
141           }
142         }
143       }
144       $this->assertLinkByHref('node/' . $node->id(), 0, 'Link to registering entity found on usage page.');
145     }
146   }
147
148   /**
149    * Tests file listing usage page for entities with no canonical link template.
150    */
151   public function testFileListingUsageNoLink() {
152     // Login with user with right permissions and test listing.
153     $this->drupalLogin($this->adminUser);
154
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']);
159
160     // Create file to attach to entity.
161     $file = File::create([
162       'filename' => 'druplicon.txt',
163       'uri' => 'public://druplicon.txt',
164       'filemime' => 'text/plain',
165     ]);
166     $file->setPermanent();
167     file_put_contents($file->getFileUri(), 'hello world');
168     $file->save();
169
170     // Create entity and attach the created file.
171     $entity_name = $this->randomMachineName();
172     $entity = EntityTestConstraints::create([
173       'uid' => 1,
174       'name' => $entity_name,
175       'type' => $bundle,
176       'field_test_file' => [
177         'target_id' => $file->id(),
178       ],
179     ]);
180     $entity->save();
181
182     // Create node entity and attach the created file.
183     $node = $this->drupalCreateNode(['type' => 'article', 'file' => $file]);
184     $node->save();
185
186     // Load the file usage page for the created and attached file.
187     $this->drupalGet('admin/content/files/usage/' . $file->id());
188
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());
195   }
196
197   /**
198    * Creates and saves a test file.
199    *
200    * @return \Drupal\Core\Entity\EntityInterface
201    *   A file entity.
202    */
203   protected function createFile() {
204     // Create a new file entity.
205     $file = File::create([
206       'uid' => 1,
207       'filename' => 'druplicon.txt',
208       'uri' => 'public://druplicon.txt',
209       'filemime' => 'text/plain',
210       'created' => 1,
211       'changed' => 1,
212       'status' => FILE_STATUS_PERMANENT,
213     ]);
214     file_put_contents($file->getFileUri(), 'hello world');
215
216     // Save it, inserting a new record.
217     $file->save();
218
219     return $file;
220   }
221
222 }