CluPilotCloud/app/Services/Dns/FakeHetznerDnsClient.php

59 lines
1.8 KiB
PHP

<?php
namespace App\Services\Dns;
use RuntimeException;
/**
* Hands out the same `{name}/{type}` ids as the real client and refuses the
* same fqdns — see RrsetId. A fake that answered `rec-1` would let every test
* that purges a host or prunes a legacy record go green over a teardown that
* throws in production.
*/
class FakeHetznerDnsClient implements HetznerDnsClient
{
/** @var array<string, string> fqdn => rrset id */
public array $records = [];
/** @var array<string, string> fqdn => published value — without this a test
* cannot tell which address ended up in DNS, which is the whole point for
* host records. */
public array $values = [];
public bool $failUpsert = false;
public bool $failDelete = false;
public function upsertRecord(string $fqdn, string $type, string $value): string
{
if ($this->failUpsert) {
throw new RuntimeException('hetzner dns 5xx');
}
// Derived, not counted: the id a caller stores has to be the one the
// real client would store, or the round trip through deleteRecord()
// below proves nothing about the round trip in production.
$id = RrsetId::for($fqdn, $type);
$this->values[$fqdn] = $value;
return $this->records[$fqdn] = $id;
}
public function deleteRecord(string $recordId): void
{
if ($this->failDelete) {
throw new RuntimeException('hetzner dns 5xx');
}
// Lets a legacy id pass exactly like the real client does — a host
// carrying one has to stay purgeable, and a fake that threw here would
// prove the opposite of what the real client does.
if (! RrsetId::isRrsetId($recordId)) {
return;
}
$this->records = array_filter($this->records, fn ($id) => $id !== $recordId);
}
}