ZipTestCase.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. <?php
  2. namespace PhpZip\Tests;
  3. use PHPUnit\Framework\TestCase;
  4. use PhpZip\Constants\ZipConstants;
  5. use PhpZip\Util\FilesUtil;
  6. /**
  7. * PHPUnit test case and helper methods.
  8. */
  9. abstract class ZipTestCase extends TestCase
  10. {
  11. /** @var string */
  12. protected $outputFilename;
  13. /** @var string */
  14. protected $outputDirname;
  15. /**
  16. * Before test.
  17. *
  18. * @noinspection PhpMissingParentCallCommonInspection
  19. */
  20. protected function setUp()
  21. {
  22. $id = uniqid('phpzip', true);
  23. $tempDir = sys_get_temp_dir() . '/phpunit-phpzip';
  24. if (!is_dir($tempDir) && !mkdir($tempDir, 0755, true) && !is_dir($tempDir)) {
  25. throw new \RuntimeException('Dir ' . $tempDir . " can't created");
  26. }
  27. $this->outputFilename = $tempDir . '/' . $id . '.zip';
  28. $this->outputDirname = $tempDir . '/' . $id;
  29. }
  30. /**
  31. * After test.
  32. */
  33. protected function tearDown()
  34. {
  35. parent::tearDown();
  36. if ($this->outputFilename !== null && file_exists($this->outputFilename)) {
  37. unlink($this->outputFilename);
  38. }
  39. if ($this->outputDirname !== null && is_dir($this->outputDirname)) {
  40. FilesUtil::removeDir($this->outputDirname);
  41. }
  42. }
  43. /**
  44. * Assert correct zip archive.
  45. *
  46. * @param string $filename
  47. * @param string|null $password
  48. */
  49. public static function assertCorrectZipArchive($filename, $password = null)
  50. {
  51. if (self::existsProgram('unzip')) {
  52. $command = 'unzip';
  53. if ($password !== null) {
  54. $command .= ' -P ' . escapeshellarg($password);
  55. }
  56. $command .= ' -t ' . escapeshellarg($filename);
  57. $command .= ' 2>&1';
  58. exec($command, $output, $returnCode);
  59. $output = implode(\PHP_EOL, $output);
  60. if ($password !== null && $returnCode === 81) {
  61. if (self::existsProgram('7z')) {
  62. /**
  63. * WinZip 99-character limit.
  64. *
  65. * @see https://sourceforge.net/p/p7zip/discussion/383044/thread/c859a2f0/
  66. */
  67. $password = substr($password, 0, 99);
  68. $command = '7z t -p' . escapeshellarg($password) . ' ' . escapeshellarg($filename);
  69. exec($command, $output, $returnCode);
  70. /**
  71. * @var array $output
  72. */
  73. $output = implode(\PHP_EOL, $output);
  74. static::assertSame($returnCode, 0);
  75. static::assertNotContains(' Errors', $output);
  76. static::assertContains(' Ok', $output);
  77. } else {
  78. fwrite(\STDERR, 'Program unzip cannot support this function.' . \PHP_EOL);
  79. fwrite(\STDERR, 'Please install 7z. For Ubuntu-like: sudo apt-get install p7zip-full' . \PHP_EOL);
  80. }
  81. } else {
  82. static::assertSame($returnCode, 0, $output);
  83. static::assertNotContains('incorrect password', $output);
  84. static::assertContains(' OK', $output);
  85. static::assertContains('No errors', $output);
  86. }
  87. }
  88. }
  89. /**
  90. * @param string $program
  91. *
  92. * @return bool
  93. */
  94. protected static function existsProgram($program)
  95. {
  96. if (\DIRECTORY_SEPARATOR !== '\\') {
  97. exec('which ' . escapeshellarg($program), $output, $returnCode);
  98. return $returnCode === 0;
  99. }
  100. // false for Windows
  101. return false;
  102. }
  103. /**
  104. * Assert correct empty zip archive.
  105. *
  106. * @param $filename
  107. */
  108. public static function assertCorrectEmptyZip($filename)
  109. {
  110. if (self::existsProgram('zipinfo')) {
  111. exec('zipinfo ' . escapeshellarg($filename), $output, $returnCode);
  112. $output = implode(\PHP_EOL, $output);
  113. static::assertContains('Empty zipfile', $output);
  114. }
  115. $actualEmptyZipData = pack('VVVVVv', ZipConstants::END_CD, 0, 0, 0, 0, 0);
  116. static::assertStringEqualsFile($filename, $actualEmptyZipData);
  117. }
  118. /**
  119. * @param string $filename
  120. * @param bool $showErrors
  121. *
  122. * @return bool|null If null returned, then the zipalign program is not installed
  123. */
  124. public static function assertVerifyZipAlign($filename, $showErrors = false)
  125. {
  126. if (self::existsProgram('zipalign')) {
  127. exec('zipalign -c -v 4 ' . escapeshellarg($filename), $output, $returnCode);
  128. if ($showErrors && $returnCode !== 0) {
  129. fwrite(\STDERR, implode(\PHP_EOL, $output));
  130. }
  131. return $returnCode === 0;
  132. }
  133. fwrite(\STDERR, "Cannot find the program 'zipalign' for the test" . \PHP_EOL);
  134. return null;
  135. }
  136. /**
  137. * @return bool
  138. */
  139. public static function skipTestForRootUser()
  140. {
  141. /** @noinspection PhpComposerExtensionStubsInspection */
  142. if (\extension_loaded('posix') && posix_getuid() === 0) {
  143. static::markTestSkipped('Skip the test for a user with root privileges');
  144. return true;
  145. }
  146. return false;
  147. }
  148. }