126 lines
4.2 KiB
PHP
126 lines
4.2 KiB
PHP
<?php
|
|
|
|
namespace App\Tests\Service;
|
|
|
|
use App\Entity\ScriptMapping;
|
|
use App\Service\CachePathResolver;
|
|
use App\Service\GitSynchronizer;
|
|
use PHPUnit\Framework\TestCase;
|
|
use ReflectionProperty;
|
|
use Symfony\Component\Filesystem\Filesystem;
|
|
use Symfony\Component\Process\Process;
|
|
|
|
final class GitSynchronizerTest extends TestCase
|
|
{
|
|
private Filesystem $filesystem;
|
|
private string $workDir;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$this->filesystem = new Filesystem();
|
|
$this->workDir = sys_get_temp_dir().'/get-installer-bootstrap-test-'.bin2hex(random_bytes(6));
|
|
$this->filesystem->mkdir($this->workDir);
|
|
}
|
|
|
|
protected function tearDown(): void
|
|
{
|
|
$this->filesystem->remove($this->workDir);
|
|
}
|
|
|
|
public function testSyncCopiesRepositoryScriptToCache(): void
|
|
{
|
|
$repositoryDir = $this->createRepository([
|
|
'install.sh' => "#!/usr/bin/env bash\nprintf 'ok'\n",
|
|
]);
|
|
|
|
$mapping = $this->mapping($repositoryDir, 'install.sh');
|
|
|
|
$synchronizer = $this->synchronizer();
|
|
$synchronizer->sync($mapping);
|
|
|
|
self::assertSame(ScriptMapping::SYNC_STATUS_SYNCED, $mapping->getLastSyncStatus());
|
|
self::assertNotNull($mapping->getLastSuccessfulSyncAt());
|
|
self::assertNull($mapping->getLastSyncError());
|
|
self::assertSame('scripts/42.sh', $mapping->getCacheKey());
|
|
self::assertSame(
|
|
"#!/usr/bin/env bash\nprintf 'ok'\n",
|
|
file_get_contents($this->workDir.'/cache/scripts/42.sh')
|
|
);
|
|
}
|
|
|
|
public function testSyncFailureMarksMappingWithoutTokenLeak(): void
|
|
{
|
|
$repositoryDir = $this->createRepository([
|
|
'install.sh' => "#!/usr/bin/env bash\n",
|
|
]);
|
|
|
|
$mapping = $this->mapping($repositoryDir, 'missing.sh')->setAccessToken('secret-token');
|
|
|
|
$synchronizer = $this->synchronizer();
|
|
|
|
$this->expectExceptionMessage('Git synchronization failed.');
|
|
|
|
try {
|
|
$synchronizer->sync($mapping);
|
|
} finally {
|
|
self::assertSame(ScriptMapping::SYNC_STATUS_FAILED, $mapping->getLastSyncStatus());
|
|
self::assertNotNull($mapping->getLastSyncError());
|
|
self::assertStringContainsString('missing.sh', $mapping->getLastSyncError());
|
|
self::assertStringNotContainsString('secret-token', $mapping->getLastSyncError());
|
|
}
|
|
}
|
|
|
|
/** @param array<string, string> $files */
|
|
private function createRepository(array $files): string
|
|
{
|
|
$repositoryDir = $this->workDir.'/repo';
|
|
$this->filesystem->mkdir($repositoryDir);
|
|
|
|
foreach ($files as $path => $content) {
|
|
$fullPath = $repositoryDir.'/'.$path;
|
|
$this->filesystem->mkdir(dirname($fullPath));
|
|
file_put_contents($fullPath, $content);
|
|
}
|
|
|
|
$this->runGit(['init'], $repositoryDir);
|
|
$this->runGit(['config', 'user.email', 'tests@example.com'], $repositoryDir);
|
|
$this->runGit(['config', 'user.name', 'Tests'], $repositoryDir);
|
|
$this->runGit(['add', '.'], $repositoryDir);
|
|
$this->runGit(['commit', '-m', 'Initial commit'], $repositoryDir);
|
|
$this->runGit(['branch', '-M', 'main'], $repositoryDir);
|
|
|
|
return $repositoryDir;
|
|
}
|
|
|
|
/** @param list<string> $arguments */
|
|
private function runGit(array $arguments, string $cwd): void
|
|
{
|
|
$process = new Process(['git', ...$arguments], $cwd);
|
|
$process->mustRun();
|
|
}
|
|
|
|
private function mapping(string $repositoryUrl, string $repositoryFilePath): ScriptMapping
|
|
{
|
|
$mapping = (new ScriptMapping())
|
|
->setPublicPath('mcp/graylog/install.sh')
|
|
->setRepositoryUrl($repositoryUrl)
|
|
->setGitRef('main')
|
|
->setRepositoryFilePath($repositoryFilePath)
|
|
->setActive(true);
|
|
|
|
return $this->setMappingId($mapping, 42);
|
|
}
|
|
|
|
private function synchronizer(): GitSynchronizer
|
|
{
|
|
return new GitSynchronizer(new CachePathResolver($this->workDir.'/cache', $this->workDir));
|
|
}
|
|
|
|
private function setMappingId(ScriptMapping $mapping, int $id): ScriptMapping
|
|
{
|
|
$property = new ReflectionProperty(ScriptMapping::class, 'id');
|
|
$property->setValue($mapping, $id);
|
|
|
|
return $mapping;
|
|
}
|
|
}
|