151 lines
5.2 KiB
PHP
151 lines
5.2 KiB
PHP
<?php
|
|
|
|
namespace App\Tests\Controller\Admin;
|
|
|
|
use App\Entity\ScriptMapping;
|
|
use App\Entity\User;
|
|
use App\Tests\DatabaseWebTestCase;
|
|
use Symfony\Component\Filesystem\Filesystem;
|
|
use Symfony\Component\Process\Process;
|
|
|
|
final class ScriptMappingControllerTest extends DatabaseWebTestCase
|
|
{
|
|
private Filesystem $filesystem;
|
|
private string $workDir;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
$this->filesystem = new Filesystem();
|
|
$this->workDir = sys_get_temp_dir().'/get-installer-bootstrap-controller-test-'.bin2hex(random_bytes(6));
|
|
$this->filesystem->mkdir($this->workDir);
|
|
}
|
|
|
|
protected function tearDown(): void
|
|
{
|
|
$this->filesystem->remove($this->workDir);
|
|
|
|
parent::tearDown();
|
|
}
|
|
|
|
public function testNewMappingRequiresAuthentication(): void
|
|
{
|
|
$this->client->request('GET', '/admin/mappings/new');
|
|
|
|
self::assertResponseRedirects('/admin/login');
|
|
}
|
|
|
|
public function testAdminCanCreateMappingWithNormalizedPaths(): void
|
|
{
|
|
$this->loginAsAdmin();
|
|
|
|
$crawler = $this->client->request('GET', '/admin/mappings/new');
|
|
$form = $crawler->selectButton('Enregistrer')->form([
|
|
'script_mapping[publicPath]' => '/mcp/graylog/install.sh',
|
|
'script_mapping[repositoryUrl]' => 'https://forge.lclr.dev/AI/graylog-mcp.git',
|
|
'script_mapping[gitRef]' => 'main',
|
|
'script_mapping[repositoryFilePath]' => '/install.sh',
|
|
'script_mapping[active]' => '1',
|
|
]);
|
|
|
|
$this->client->submit($form);
|
|
|
|
self::assertResponseRedirects('/admin');
|
|
|
|
$mapping = $this->entityManager->getRepository(ScriptMapping::class)->findOneBy([
|
|
'publicPath' => 'mcp/graylog/install.sh',
|
|
]);
|
|
self::assertInstanceOf(ScriptMapping::class, $mapping);
|
|
self::assertSame('install.sh', $mapping->getRepositoryFilePath());
|
|
}
|
|
|
|
public function testInvalidPublicPathRendersValidationError(): void
|
|
{
|
|
$this->loginAsAdmin();
|
|
|
|
$crawler = $this->client->request('GET', '/admin/mappings/new');
|
|
$form = $crawler->selectButton('Enregistrer')->form([
|
|
'script_mapping[publicPath]' => 'mcp/graylog/install.txt',
|
|
'script_mapping[repositoryUrl]' => 'https://forge.lclr.dev/AI/graylog-mcp.git',
|
|
'script_mapping[gitRef]' => 'main',
|
|
'script_mapping[repositoryFilePath]' => 'install.sh',
|
|
'script_mapping[active]' => '1',
|
|
]);
|
|
|
|
$this->client->submit($form);
|
|
|
|
self::assertResponseStatusCodeSame(422);
|
|
self::assertSelectorTextContains('form', 'Public path must end with .sh.');
|
|
}
|
|
|
|
public function testAdminCanSynchronizeMapping(): void
|
|
{
|
|
$this->loginAsAdmin();
|
|
|
|
$repositoryDir = $this->createRepository([
|
|
'install.sh' => "#!/usr/bin/env bash\nprintf 'synced'\n",
|
|
]);
|
|
$mapping = (new ScriptMapping())
|
|
->setPublicPath('mcp/graylog/install.sh')
|
|
->setRepositoryUrl($repositoryDir)
|
|
->setGitRef('main')
|
|
->setRepositoryFilePath('install.sh')
|
|
->setActive(true);
|
|
$this->entityManager->persist($mapping);
|
|
$this->entityManager->flush();
|
|
|
|
$crawler = $this->client->request('GET', '/admin');
|
|
$form = $crawler->selectButton('Synchroniser')->form();
|
|
|
|
$this->client->submit($form);
|
|
|
|
self::assertResponseRedirects('/admin');
|
|
|
|
$syncedMapping = $this->entityManager->getRepository(ScriptMapping::class)->find($mapping->getId());
|
|
self::assertInstanceOf(ScriptMapping::class, $syncedMapping);
|
|
self::assertSame(
|
|
ScriptMapping::SYNC_STATUS_SYNCED,
|
|
$syncedMapping->getLastSyncStatus(),
|
|
(string) $syncedMapping->getLastSyncError()
|
|
);
|
|
self::assertSame('scripts/'.$mapping->getId().'.sh', $syncedMapping->getCacheKey());
|
|
}
|
|
|
|
private function loginAsAdmin(): void
|
|
{
|
|
$user = (new User())->setUsername('admin')->setPasswordHash('unused');
|
|
$this->entityManager->persist($user);
|
|
$this->entityManager->flush();
|
|
|
|
$this->client->loginUser($user);
|
|
}
|
|
|
|
/** @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
|
|
{
|
|
(new Process(['git', ...$arguments], $cwd))->mustRun();
|
|
}
|
|
}
|