From 8f9423bdc9852475d26d3b128a87abdb20d05e58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Andr=C3=A9?= Date: Sun, 22 Dec 2024 21:05:47 +0100 Subject: [PATCH] fix: download minify.exe --- src/MinifyInstaller.php | 37 ++++++++++----------- tests/MinifyFactoryTest.php | 59 +++++++++++++++++++++++++++++++++ tests/MinifyInstallerTest.php | 62 +++++++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+), 20 deletions(-) create mode 100644 tests/MinifyFactoryTest.php create mode 100644 tests/MinifyInstallerTest.php diff --git a/src/MinifyInstaller.php b/src/MinifyInstaller.php index 74238e3..30e5165 100644 --- a/src/MinifyInstaller.php +++ b/src/MinifyInstaller.php @@ -82,32 +82,29 @@ public function download(string $version): void $this->filesystem->appendToFile($downloadFilename, $chunk->getContent(), true); } - if (str_ends_with($downloadFilename, '.zip')) { - $download = function () use ($downloadFilename, $tempDir) { - $archive = new \ZipArchive(); - $archive->open($downloadFilename); - $archive->extractTo($tempDir, 'minify'); - $archive->close(); - }; - } else { - $download = function () use ($downloadFilename, $tempDir) { - $archive = new \PharData($downloadFilename); - $archive->extractTo($tempDir, ['minify'], true); - }; - } - - try { - $download(); - } catch (\Throwable $e) { - throw new InstallException(sprintf('Error extracting the binary from archive "%s".', $downloadFilename), 0, $e->getPrevious()); - } - $this->filesystem->mkdir(dirname($this->getInstallBinaryPath())); + if (str_ends_with($downloadFilename, '.zip')) { + // Windows archive (minify.exe) + $archive = new \ZipArchive(); + if (false === $archive->open($downloadFilename)) { + throw new InstallException(sprintf('Error opening archive "%s".', $downloadFilename)); + } + if (false === $archive->extractTo($tempDir, 'minify.exe')) { + throw new InstallException(sprintf('Error extracting minify.exe from archive "%s".', $downloadFilename)); + } + $archive->close(); $this->filesystem->copy(Path::join($tempDir, 'minify.exe'), $this->getInstallBinaryPath()); } else { + $archive = new \PharData($downloadFilename); + try { + $archive->extractTo($tempDir, ['minify'], true); + } catch (\Exception $e) { + throw new InstallException(sprintf('Error extracting the binary from archive "%s".', $downloadFilename), 0, $e); + } $this->filesystem->copy(Path::join($tempDir, 'minify'), $this->getInstallBinaryPath()); } + $this->filesystem->remove($tempDir); } diff --git a/tests/MinifyFactoryTest.php b/tests/MinifyFactoryTest.php new file mode 100644 index 0000000..a7f0d55 --- /dev/null +++ b/tests/MinifyFactoryTest.php @@ -0,0 +1,59 @@ +create(); + $this->assertInstanceOf(Minify::class, $minify); + } + + public function testExceptionIsThrownWhenBinaryNotFound(): void + { + $this->expectException(BinaryNotFoundException::class); + $factory = new MinifyFactory(false, $this->createMock(MinifierInstallerInterface::class)); + $factory->create(); + } + + public function testExceptionIsThrownWhenInstallerIsNullAndBinaryPathIsFalse(): void + { + $this->expectException(LogicException::class); + $factory = new MinifyFactory(false, null); + $factory->create(); + } + + public function testInstallerIsCalledWhenBinaryNotFound(): void + { + $installer = $this->createMock(MinifierInstallerInterface::class); + $installer->expects($this->once())->method('install'); + $installer->method('isInstalled')->willReturn(false); + $installer->method('getInstallBinaryPath')->willReturn('/usr/local/bin/minify'); + + $this->expectException(BinaryNotFoundException::class); + $factory = new MinifyFactory(false, $installer); + $factory->create(); + } +} diff --git a/tests/MinifyInstallerTest.php b/tests/MinifyInstallerTest.php new file mode 100644 index 0000000..68fdd37 --- /dev/null +++ b/tests/MinifyInstallerTest.php @@ -0,0 +1,62 @@ +install(); + $this->assertTrue($installer->isInstalled()); + } + + public function testExceptionIsThrownWhenBinaryCannotBeDownloaded(): void + { + $httpClient = $this->createMock(HttpClientInterface::class); + $httpClient->method('request')->willReturn($this->createMockResponse(500)); + $installer = new MinifyInstaller('/tmp/minify/'.rand(5, 999), $httpClient); + + $this->expectException(InstallException::class); + $installer->install(); + } + + public function testBinaryIsDownloadedAndInstalledCorrectly(): void + { + $httpClient = $this->createMock(HttpClientInterface::class); + $httpClient->method('request')->willReturn($this->createMockResponse(200, 'binary content')); + $installer = new MinifyInstaller('/tmp/minify', $httpClient); + + $installer->install(); + $this->assertFileExists('/tmp/minify/minify'); + $this->assertTrue(is_executable('/tmp/minify/minify')); + } + + private function createMockResponse(int $statusCode, string $content = ''): ResponseInterface + { + $response = $this->createMock(ResponseInterface::class); + $response->method('getStatusCode')->willReturn($statusCode); + $response->method('getContent')->willReturn($content); + + return $response; + } +}