Files
landing-api/tests/Feature/AccessRequestApproverTest.php
2026-07-09 14:51:56 +02:00

99 lines
2.9 KiB
PHP

<?php
namespace Tests\Feature;
use App\Enums\AccessRequestStatus;
use App\Models\AccessRequests;
use App\Models\GameServers;
use App\Models\User;
use App\Services\AccessRequestApprover;
use App\Services\MinecraftRconClient;
use Illuminate\Foundation\Testing\RefreshDatabase;
use RuntimeException;
use Tests\TestCase;
class AccessRequestApproverTest extends TestCase
{
use RefreshDatabase;
public function test_it_accepts_an_access_request_after_running_rcon_add(): void
{
config()->set('rcon.access_command', 'whitelist add {username}');
$rconClient = new FakeMinecraftRconClient;
$this->app->instance(MinecraftRconClient::class, $rconClient);
$reviewer = User::factory()->create();
$accessRequest = $this->pendingAccessRequest('LeonPlayer');
$output = app(AccessRequestApprover::class)->approve($accessRequest, $reviewer);
$this->assertSame('Added LeonPlayer to the whitelist', $output);
$this->assertSame(['whitelist add LeonPlayer'], $rconClient->commands);
$this->assertDatabaseHas('access_requests', [
'id' => $accessRequest->id,
'status' => AccessRequestStatus::ACCEPTED->value,
'reviewed_by' => $reviewer->id,
]);
$this->assertNotNull($accessRequest->fresh()->reviewed_at);
}
public function test_it_does_not_accept_when_rcon_fails(): void
{
$this->app->instance(MinecraftRconClient::class, new FakeMinecraftRconClient(shouldFail: true));
$accessRequest = $this->pendingAccessRequest('LeonPlayer');
$this->expectException(RuntimeException::class);
try {
app(AccessRequestApprover::class)->approve($accessRequest);
} finally {
$this->assertDatabaseHas('access_requests', [
'id' => $accessRequest->id,
'status' => AccessRequestStatus::PENDING->value,
'reviewed_by' => null,
'reviewed_at' => null,
]);
}
}
private function pendingAccessRequest(string $gameUsername): AccessRequests
{
$server = GameServers::create([
'name' => 'Survival',
'slug' => 'survival',
]);
return AccessRequests::create([
'status' => AccessRequestStatus::PENDING,
'game_username' => $gameUsername,
'message' => '',
'server_id' => $server->id,
]);
}
}
class FakeMinecraftRconClient extends MinecraftRconClient
{
/**
* @var array<int, string>
*/
public array $commands = [];
public function __construct(
private readonly bool $shouldFail = false,
) {}
public function command(string $command): string
{
$this->commands[] = $command;
if ($this->shouldFail) {
throw new RuntimeException('rcon failed');
}
return 'Added LeonPlayer to the whitelist';
}
}