CluPilotCloud/tests/Feature/SecretVaultModeTest.php

76 lines
3.1 KiB
PHP

<?php
use App\Models\Operator;
use App\Services\Secrets\SecretVault;
use App\Support\OperatingMode;
/**
* Zwei Plätze je Zugangsdatum, und eine Rückfallregel, die für vier von fünf
* Einträgen richtig ist: es gibt bei Hetzner, Uptime Kuma und SSH nur ein
* Konto, und zwei Felder mit zwingend gleichem Inhalt wären eine Attrappe.
*/
beforeEach(function () {
$this->by = Operator::factory()->create();
$this->vault = app(SecretVault::class);
// HETZNER_DNS_TOKEN is real in this operator's .env and, unlike
// STRIPE_WEBHOOK_SECRET, not blanked in phpunit.xml — left alone, the
// fallback-to-environment tests below would silently pass or fail
// depending on whose machine runs them instead of on the code.
config()->set('provisioning.dns.token', null);
});
it('reads the slot of the active mode', function () {
$this->vault->put('dns.token', 'live-token', $this->by, OperatingMode::Live);
$this->vault->put('dns.token', 'test-token', $this->by, OperatingMode::Test);
OperatingMode::set(OperatingMode::Test);
expect($this->vault->get('dns.token'))->toBe('test-token');
OperatingMode::set(OperatingMode::Live);
expect($this->vault->get('dns.token'))->toBe('live-token');
});
it('falls back to the live slot when the test slot is empty', function () {
// Die Regel des Inhabers: wo es keinen Testzugang gibt, wird der echte
// benutzt, damit der Testbetrieb überhaupt arbeiten kann.
$this->vault->put('dns.token', 'live-token', $this->by, OperatingMode::Live);
OperatingMode::set(OperatingMode::Test);
expect($this->vault->get('dns.token'))->toBe('live-token');
});
it('does not fall back from live to test', function () {
// Die andere Richtung wäre absurd: im Livebetrieb einen Testzugang zu
// benutzen, weil der echte fehlt.
$this->vault->put('dns.token', 'test-token', $this->by, OperatingMode::Test);
OperatingMode::set(OperatingMode::Live);
expect($this->vault->get('dns.token'))->toBeNull();
});
it('still falls back to the environment when neither slot is filled', function () {
// Der Weg für eine Installation, in der noch gar nichts gespeichert ist.
// Einwertig und modusfrei — den Anfangszustand gibt es nur einmal.
config()->set('provisioning.dns.token', 'from-env');
expect($this->vault->get('dns.token'))->toBe('from-env');
});
it('reports the source per slot', function () {
$this->vault->put('dns.token', 'live-token', $this->by, OperatingMode::Live);
expect($this->vault->source('dns.token', OperatingMode::Live))->toBe('stored');
expect($this->vault->source('dns.token', OperatingMode::Test))->toBe('none');
});
it('forgets one slot without touching the other', function () {
$this->vault->put('dns.token', 'live-token', $this->by, OperatingMode::Live);
$this->vault->put('dns.token', 'test-token', $this->by, OperatingMode::Test);
$this->vault->forget('dns.token', OperatingMode::Test);
expect($this->vault->source('dns.token', OperatingMode::Test))->toBe('none');
expect($this->vault->source('dns.token', OperatingMode::Live))->toBe('stored');
});