ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
ZipTest.php
Go to the documentation of this file.
1 <?php
2 
19 namespace ILIAS\Filesystem\Util;
20 
28 
37 class ZipTest extends TestCase
38 {
39  public const ZIPPED_ZIP = 'zipped.zip';
40  protected string $zips_dir = __DIR__ . '/zips/';
41  protected string $unzips_dir = __DIR__ . '/unzips/';
42 
43  protected function setUp(): void
44  {
45  if (file_exists($this->unzips_dir . self::ZIPPED_ZIP)) {
46  unlink($this->unzips_dir . self::ZIPPED_ZIP);
47  }
48  if (!file_exists($this->unzips_dir)) {
49  mkdir($this->unzips_dir);
50  }
51  }
52 
53  protected function tearDown(): void
54  {
55  if (file_exists($this->unzips_dir)) {
56  $this->recurseRmdir($this->unzips_dir);
57  }
58  }
59 
60  public function testZip(): void
61  {
62  $zip_options = new ZipOptions();
63  $streams = [
64  Streams::ofResource(fopen($this->zips_dir . '1_folder_1_file_mac.zip', 'r')),
65  Streams::ofResource(fopen($this->zips_dir . '1_folder_win.zip', 'r')),
66  ];
67  $zip = new Zip($zip_options, ...$streams);
68  $zip_stream = $zip->get();
69  $this->assertGreaterThan(0, $zip_stream->getSize());
70 
71  $unzip_again = new Unzip(new UnzipOptions(), $zip_stream);
72  $this->assertEquals(2, $unzip_again->getAmountOfFiles());
73  }
74 
75  public function testLegacyZip(): void
76  {
77  $legacy = new LegacyArchives();
78 
79  define('CLIENT_WEB_DIR', __DIR__);
80  define('ILIAS_WEB_DIR', 'public/data');
81  define('CLIENT_ID', 'test');
82  define('CLIENT_DATA_DIR', __DIR__);
83  define('ILIAS_ABSOLUTE_PATH', __DIR__);
84 
85  $legacy->zip($this->zips_dir, $this->unzips_dir . self::ZIPPED_ZIP, false);
86  $this->assertFileExists($this->unzips_dir . self::ZIPPED_ZIP);
87 
88  $unzip_again = new Unzip(new UnzipOptions(), Streams::ofResource(fopen($this->unzips_dir . self::ZIPPED_ZIP, 'r')));
89  $this->assertEquals(5, $unzip_again->getAmountOfFiles());
90 
91  $depth = 0;
92  foreach ($unzip_again->getPaths() as $path) {
93  $parts = explode('/', $path);
94  $depth = max($depth, count($parts));
95  }
96  $this->assertEquals(2, $depth);
97  $this->recurseRmdir($this->unzips_dir);
98  }
99 
100  public function LegacyZipWithTop(): void
101  {
102  $legacy = new LegacyArchives();
103 
104  define('CLIENT_WEB_DIR', __DIR__);
105  define('ILIAS_WEB_DIR', 'public/data');
106  define('CLIENT_ID', 'test');
107  define('CLIENT_DATA_DIR', __DIR__);
108  define('ILIAS_ABSOLUTE_PATH', __DIR__);
109 
110  mkdir($this->unzips_dir);
111  $legacy->zip($this->zips_dir, $this->unzips_dir . self::ZIPPED_ZIP, true);
112  $this->assertFileExists($this->unzips_dir . self::ZIPPED_ZIP);
113 
114  $unzip_again = new Unzip(new UnzipOptions(), Streams::ofResource(fopen($this->unzips_dir . self::ZIPPED_ZIP, 'r')));
115  $this->assertEquals(5, $unzip_again->getAmountOfFiles());
116 
117  $depth = 0;
118  foreach ($unzip_again->getPaths() as $path) {
119  $parts = explode('/', $path);
120  $depth = max($depth, count($parts));
121  }
122  $this->assertEquals(2, $depth);
123  $this->recurseRmdir($this->unzips_dir);
124  }
125 
131  public function testUnzip(
132  string $zip,
133  bool $has_multiple_root_entries,
134  int $expected_amount_directories,
135  array $expected_directories,
136  int $expected_amount_files,
137  array $expected_files
138  ): void {
139  $this->assertStringContainsString('.zip', $zip);
140  $zip_path = $this->zips_dir . $zip;
141  $this->assertFileExists($zip_path);
142 
143  $stream = Streams::ofResource(fopen($zip_path, 'rb'));
144  $options = new UnzipOptions();
145  $unzip = new Unzip($options, $stream);
146 
147  $this->assertFalse($unzip->hasZipReadingError());
148  $this->assertEquals($has_multiple_root_entries, $unzip->hasMultipleRootEntriesInZip());
149  $this->assertEquals($expected_amount_directories, $unzip->getAmountOfDirectories());
150  $this->assertEquals($expected_directories, iterator_to_array($unzip->getDirectories()));
151  $this->assertEquals($expected_amount_files, $unzip->getAmountOfFiles());
152  $this->assertEquals($expected_files, iterator_to_array($unzip->getFiles()));
153  }
154 
155  public function testWrongZip(): void
156  {
157  $stream = Streams::ofResource(fopen(__FILE__, 'rb'));
158  $options = new UnzipOptions();
159  $unzip = new Unzip($options, $stream);
160  $this->assertTrue($unzip->hasZipReadingError());
161  $this->assertFalse($unzip->hasMultipleRootEntriesInZip());
162  $this->assertEquals(0, iterator_count($unzip->getFiles()));
163  $this->assertEquals(0, iterator_count($unzip->getDirectories()));
164  $this->assertEquals(0, iterator_count($unzip->getPaths()));
165  $this->assertEquals([], iterator_to_array($unzip->getDirectories()));
166  $this->assertEquals([], iterator_to_array($unzip->getFiles()));
167  }
168 
169 
170  public function testLargeZIPs(): void
171  {
172  // get ulimit
173  $ulimit = (int) shell_exec('ulimit -n');
174  $limit = 2500;
175  if ($ulimit >= $limit) {
176  $this->markTestSkipped('ulimit is too high and would take too much resources');
177  }
178  $this->assertLessThan($limit, $ulimit);
179 
180  $zip = new Zip(new ZipOptions());
181 
182  $file_names = [];
183 
184  for ($i = 0; $i < $ulimit * 2; $i++) {
185  $path_inside_zip = $file_names[] = 'test' . $i;
186  $zip->addStream(Streams::ofString('-'), $path_inside_zip);
187  }
188  $this->assertTrue(true); // no warning or error
189 
190  // check if the zip now contains all files
191  $unzip = new Unzip(new UnzipOptions(), $zip->get());
192  $file_names_in_zip = iterator_to_array($unzip->getFiles());
193  sort($file_names);
194  sort($file_names_in_zip);
195  $this->assertEquals($file_names, $file_names_in_zip);
196  }
197 
203  public function testLegacyUnzip(
204  string $zip,
205  bool $has_multiple_root_entries,
206  int $expected_amount_directories,
207  array $expected_directories,
208  int $expected_amount_files,
209  array $expected_files
210  ): void {
211  $legacy = new LegacyArchives();
212 
213  $this->assertStringContainsString('.zip', $zip);
214  $zip_path = $this->zips_dir . $zip;
215  $this->assertFileExists($zip_path);
216 
217  $temp_unzip_path = $this->unzips_dir . uniqid('unzip', true);
218 
219  $return = $legacy->unzip(
220  $zip_path,
221  $temp_unzip_path
222  );
223 
224  $this->assertTrue($return);
225 
226  $unzipped_files = $this->directoryToArray($temp_unzip_path);
227  $expected_paths = array_merge($expected_directories, $expected_files);
228  sort($expected_paths);
229  $this->assertEquals($expected_paths, $unzipped_files);
230  $this->assertTrue($this->recurseRmdir($temp_unzip_path));
231  }
232 
233  private function recurseRmdir(string $path_to_directory): bool
234  {
235  $files = array_diff(scandir($path_to_directory), ['.', '..']);
236  foreach ($files as $file) {
237  (is_dir("$path_to_directory/$file") && !is_link("$path_to_directory/$file")) ? $this->recurseRmdir(
238  "$path_to_directory/$file"
239  ) : unlink("$path_to_directory/$file");
240  }
241  return rmdir($path_to_directory);
242  }
243 
247  private function directoryToArray(string $path_to_directory): array
248  {
249  $iterator = new \RecursiveIteratorIterator(
250  new \RecursiveDirectoryIterator($path_to_directory, \RecursiveDirectoryIterator::SKIP_DOTS),
251  \RecursiveIteratorIterator::SELF_FIRST,
252  \RecursiveIteratorIterator::CATCH_GET_CHILD
253  );
254  $paths = [];
255  foreach ($iterator as $item) {
256  $relative_path = str_replace($path_to_directory . '/', '', $item->getPathname());
257  $paths[] = $item->isDir() ? $relative_path . '/' : $relative_path;
258  }
259 
260  sort($paths);
261 
262  return $paths;
263  }
264 
265  // PROVIDERS
266 
267  public static function getZips(): array
268  {
269  return [
270  ['1_folder_mac.zip', false, 10, self::$directories_one, 15, self::$files_one],
271  ['1_folder_win.zip', false, 10, self::$directories_one, 15, self::$files_one],
272  ['3_folders_mac.zip', true, 9, self::$directories_three, 12, self::$files_three],
273  ['3_folders_win.zip', true, 9, self::$directories_three, 12, self::$files_three],
274  ['1_folder_1_file_mac.zip', true, 3, self::$directories_mixed, 5, self::$files_mixed]
275  ];
276  }
277 
278  protected static array $files_mixed = [
279  0 => '03_Test.pdf',
280  1 => 'Ordner A/01_Test.pdf',
281  2 => 'Ordner A/02_Test.pdf',
282  3 => 'Ordner A/Ordner A_2/07_Test.pdf',
283  4 => 'Ordner A/Ordner A_2/08_Test.pdf'
284  ];
285 
286  protected static array $directories_mixed = [
287  0 => 'Ordner A/',
288  1 => 'Ordner A/Ordner A_1/',
289  2 => 'Ordner A/Ordner A_2/'
290  ];
291 
292  protected static array $directories_one = [
293  0 => 'Ordner 0/',
294  1 => 'Ordner 0/Ordner A/',
295  2 => 'Ordner 0/Ordner A/Ordner A_1/',
296  3 => 'Ordner 0/Ordner A/Ordner A_2/',
297  4 => 'Ordner 0/Ordner B/',
298  5 => 'Ordner 0/Ordner B/Ordner B_1/',
299  6 => 'Ordner 0/Ordner B/Ordner B_2/',
300  7 => 'Ordner 0/Ordner C/',
301  8 => 'Ordner 0/Ordner C/Ordner C_1/',
302  9 => 'Ordner 0/Ordner C/Ordner C_2/'
303  ];
304  protected static array $directories_three = [
305  0 => 'Ordner A/',
306  1 => 'Ordner A/Ordner A_1/',
307  2 => 'Ordner A/Ordner A_2/',
308  3 => 'Ordner B/',
309  4 => 'Ordner B/Ordner B_1/',
310  5 => 'Ordner B/Ordner B_2/',
311  6 => 'Ordner C/',
312  7 => 'Ordner C/Ordner C_1/',
313  8 => 'Ordner C/Ordner C_2/'
314  ];
315 
316  protected static array $files_one = [
317  0 => 'Ordner 0/13_Test.pdf',
318  1 => 'Ordner 0/14_Test.pdf',
319  2 => 'Ordner 0/15_Test.pdf',
320  3 => 'Ordner 0/Ordner A/01_Test.pdf',
321  4 => 'Ordner 0/Ordner A/02_Test.pdf',
322  5 => 'Ordner 0/Ordner A/Ordner A_2/07_Test.pdf',
323  6 => 'Ordner 0/Ordner A/Ordner A_2/08_Test.pdf',
324  7 => 'Ordner 0/Ordner B/03_Test.pdf',
325  8 => 'Ordner 0/Ordner B/04_Test.pdf',
326  9 => 'Ordner 0/Ordner B/Ordner B_2/09_Test.pdf',
327  10 => 'Ordner 0/Ordner B/Ordner B_2/10_Test.pdf',
328  11 => 'Ordner 0/Ordner C/05_Test.pdf',
329  12 => 'Ordner 0/Ordner C/06_Test.pdf',
330  13 => 'Ordner 0/Ordner C/Ordner C_2/11_Test.pdf',
331  14 => 'Ordner 0/Ordner C/Ordner C_2/12_Test.pdf'
332  ];
333 
334  protected static array $files_three = [
335  0 => 'Ordner A/01_Test.pdf',
336  1 => 'Ordner A/02_Test.pdf',
337  2 => 'Ordner A/Ordner A_2/07_Test.pdf',
338  3 => 'Ordner A/Ordner A_2/08_Test.pdf',
339  4 => 'Ordner B/03_Test.pdf',
340  5 => 'Ordner B/04_Test.pdf',
341  6 => 'Ordner B/Ordner B_2/09_Test.pdf',
342  7 => 'Ordner B/Ordner B_2/10_Test.pdf',
343  8 => 'Ordner C/05_Test.pdf',
344  9 => 'Ordner C/06_Test.pdf',
345  10 => 'Ordner C/Ordner C_2/11_Test.pdf',
346  11 => 'Ordner C/Ordner C_2/12_Test.pdf',
347  ];
348 }
static array static array static array static array $directories_three
Definition: ZipTest.php:304
if($clientAssertionType !='urn:ietf:params:oauth:client-assertion-type:jwt-bearer'|| $grantType !='client_credentials') $parts
Definition: ltitoken.php:64
static array static array static array static array static array $files_one
Definition: ZipTest.php:316
directoryToArray(string $path_to_directory)
Definition: ZipTest.php:247
static array static array static array $directories_one
Definition: ZipTest.php:292
$path
Definition: ltiservices.php:32
testLegacyUnzip(string $zip, bool $has_multiple_root_entries, int $expected_amount_directories, array $expected_directories, int $expected_amount_files, array $expected_files)
getZips
Definition: ZipTest.php:203
static array static array $directories_mixed
Definition: ZipTest.php:286
testUnzip(string $zip, bool $has_multiple_root_entries, int $expected_amount_directories, array $expected_directories, int $expected_amount_files, array $expected_files)
getZips
Definition: ZipTest.php:131
recurseRmdir(string $path_to_directory)
Definition: ZipTest.php:233
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static array static array static array static array static array static array $files_three
Definition: ZipTest.php:334