Skip to content

Commit

Permalink
fix: download minify.exe
Browse files Browse the repository at this point in the history
  • Loading branch information
smnandre committed Dec 22, 2024
1 parent 74ac9ee commit f59b459
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 20 deletions.
37 changes: 17 additions & 20 deletions src/MinifyInstaller.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 (true !== $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);
}

Expand Down
51 changes: 51 additions & 0 deletions tests/MinifyFactoryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

/*
* This file is part of the SensioLabs MinifyBundle package.
*
* (c) Simon André - Sensiolabs
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sensiolabs\MinifyBundle\Tests;

use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use Sensiolabs\MinifyBundle\Exception\BinaryNotFoundException;
use Sensiolabs\MinifyBundle\Exception\LogicException;
use Sensiolabs\MinifyBundle\Minifier\MinifierInstallerInterface;
use Sensiolabs\MinifyBundle\MinifyFactory;

#[CoversClass(MinifyFactory::class)]
final class MinifyFactoryTest extends TestCase
{
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();
}
}
55 changes: 55 additions & 0 deletions tests/MinifyInstallerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

declare(strict_types=1);

/*
* This file is part of the SensioLabs MinifyBundle package.
*
* (c) Simon André - Sensiolabs
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sensiolabs\MinifyBundle\Tests;

use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use Sensiolabs\MinifyBundle\Exception\InstallException;
use Sensiolabs\MinifyBundle\MinifyInstaller;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;

#[CoversClass(MinifyInstaller::class)]
class MinifyInstallerTest extends TestCase
{
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;
}
}

0 comments on commit f59b459

Please sign in to comment.