Nach dem Anlegen/Bearbeiten eines Projekts im Konfig-Dialog prueft ein neuer Endpunkt
(POST /api/v1/repo-configs/{id}/check), ob fds2610-bot dort Schreibrechte hat und ein
aktiver Webhook auf diese monitor-Instanz zeigt. Das Ergebnis erscheint als gruener Haken
bzw. rotes Kreuz rechts neben den Bearbeiten-/Loeschen-Symbolen, mit Tooltip zum geprueften
Service bzw. zur Fehlerursache.
130 lines
4.8 KiB
PHP
130 lines
4.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Monitor\Api\Tests\Sync;
|
|
|
|
use Monitor\Api\Sync\CodebergApiException;
|
|
use Monitor\Api\Sync\CodebergClient;
|
|
use Monitor\Api\Sync\RepoHealthChecker;
|
|
use PHPUnit\Framework\TestCase;
|
|
use RuntimeException;
|
|
|
|
final class RepoHealthCheckerTest extends TestCase
|
|
{
|
|
public function testWriteAccessOkWhenPushPermissionTrue(): void
|
|
{
|
|
$client = $this->fakeClient(repoPermissions: ['push' => true]);
|
|
|
|
$checks = (new RepoHealthChecker($client))->check('fds2610', 'monitor');
|
|
|
|
self::assertTrue($checks['write_access']['ok']);
|
|
}
|
|
|
|
public function testWriteAccessFailsWhenPushPermissionFalse(): void
|
|
{
|
|
$client = $this->fakeClient(repoPermissions: ['push' => false]);
|
|
|
|
$checks = (new RepoHealthChecker($client))->check('fds2610', 'monitor');
|
|
|
|
self::assertFalse($checks['write_access']['ok']);
|
|
self::assertStringContainsString('keine Schreibrechte', $checks['write_access']['message']);
|
|
}
|
|
|
|
public function testWriteAccessFailsWithNotFoundMessageOn404(): void
|
|
{
|
|
$client = $this->fakeClient(repoPermissionsException: new CodebergApiException(404, 'nope'));
|
|
|
|
$checks = (new RepoHealthChecker($client))->check('fds2610', 'unbekannt');
|
|
|
|
self::assertFalse($checks['write_access']['ok']);
|
|
self::assertStringContainsString('nicht gefunden', $checks['write_access']['message']);
|
|
}
|
|
|
|
public function testWebhookOkWhenActiveJsonHookPointsToOwnEndpoint(): void
|
|
{
|
|
$client = $this->fakeClient(listWebhooks: [
|
|
['active' => true, 'url' => 'https://monitor.example.org/api/v1/webhooks/codeberg', 'content_type' => 'json'],
|
|
]);
|
|
|
|
$checks = (new RepoHealthChecker($client))->check('fds2610', 'monitor');
|
|
|
|
self::assertTrue($checks['webhook']['ok']);
|
|
}
|
|
|
|
public function testWebhookFailsWhenNoMatchingHookPresent(): void
|
|
{
|
|
$client = $this->fakeClient(listWebhooks: [
|
|
['active' => true, 'url' => 'https://example.org/other', 'content_type' => 'json'],
|
|
['active' => false, 'url' => 'https://monitor.example.org/api/v1/webhooks/codeberg', 'content_type' => 'json'],
|
|
]);
|
|
|
|
$checks = (new RepoHealthChecker($client))->check('fds2610', 'monitor');
|
|
|
|
self::assertFalse($checks['webhook']['ok']);
|
|
}
|
|
|
|
public function testWebhookFailsWithPermissionMessageOn403(): void
|
|
{
|
|
$client = $this->fakeClient(listWebhooksException: new CodebergApiException(403, 'forbidden'));
|
|
|
|
$checks = (new RepoHealthChecker($client))->check('fds2610', 'monitor');
|
|
|
|
self::assertFalse($checks['webhook']['ok']);
|
|
self::assertStringContainsString('keine Admin-Rechte', $checks['webhook']['message']);
|
|
}
|
|
|
|
public function testFailsGracefullyWhenCodebergUnreachable(): void
|
|
{
|
|
$client = $this->fakeClient(repoPermissionsException: new RuntimeException('Codeberg-API nicht erreichbar: timeout'));
|
|
|
|
$checks = (new RepoHealthChecker($client))->check('fds2610', 'monitor');
|
|
|
|
self::assertFalse($checks['write_access']['ok']);
|
|
self::assertStringContainsString('nicht erreichbar', $checks['write_access']['message']);
|
|
}
|
|
|
|
/**
|
|
* @param array{push: bool}|null $repoPermissions
|
|
* @param array<int, array{active: bool, url: string, content_type: string}>|null $listWebhooks
|
|
*/
|
|
private function fakeClient(
|
|
?array $repoPermissions = null,
|
|
?RuntimeException $repoPermissionsException = null,
|
|
?array $listWebhooks = null,
|
|
?RuntimeException $listWebhooksException = null,
|
|
): CodebergClient {
|
|
return new class ($repoPermissions, $repoPermissionsException, $listWebhooks, $listWebhooksException) implements CodebergClient {
|
|
public function __construct(
|
|
private readonly ?array $repoPermissions,
|
|
private readonly ?RuntimeException $repoPermissionsException,
|
|
private readonly ?array $listWebhooks,
|
|
private readonly ?RuntimeException $listWebhooksException,
|
|
) {
|
|
}
|
|
|
|
public function listIssues(string $owner, string $repo, string $state): array
|
|
{
|
|
return [];
|
|
}
|
|
|
|
public function repoPermissions(string $owner, string $repo): array
|
|
{
|
|
if ($this->repoPermissionsException !== null) {
|
|
throw $this->repoPermissionsException;
|
|
}
|
|
|
|
return $this->repoPermissions ?? ['push' => true];
|
|
}
|
|
|
|
public function listWebhooks(string $owner, string $repo): array
|
|
{
|
|
if ($this->listWebhooksException !== null) {
|
|
throw $this->listWebhooksException;
|
|
}
|
|
|
|
return $this->listWebhooks ?? [];
|
|
}
|
|
};
|
|
}
|
|
}
|