CluPilotCloud/tests/Feature/Admin/ConnectionTestFeedbackTest.php

106 lines
4.4 KiB
PHP

<?php
use App\Livewire\Admin\CheckResult;
use App\Livewire\Admin\Integrations;
use App\Support\Settings;
use Illuminate\Support\Facades\Http;
use Livewire\Livewire;
/**
* Zweimal gemeldet, und beide Male war es dieselbe Ursache: die Antwort der
* Verbindungsprüfung stand am SEITENENDE, hinter allen Karten und hinter dem
* Speichern-Knopf. Der Knopf sitzt oben in der Karte.
*
* „der Verbindung-testen-Knopf macht irgendwie nichts"
* „runterscrollen tut niemand, wenn man es nicht weiss"
*
* Eine Antwort, die man suchen muss, ist für den Betreiber keine. Jetzt geht
* ein Modal auf.
*/
beforeEach(function () {
config()->set('admin_access.secrets_key', 'base64:'.base64_encode(random_bytes(32)));
withStripeSecret();
Http::preventStrayRequests();
});
function integrationsUnlockedForCheck()
{
return Livewire::actingAs(operator('Owner'), 'operator')
->test(Integrations::class)
->set('confirmablePassword', 'password')
->call('confirmPassword');
}
it('produces a result at all when the button is pressed', function () {
Http::fake(['api.stripe.com/v1/account' => Http::response([
'id' => 'acct_1', 'settings' => ['dashboard' => ['display_name' => 'CluPilot']],
])]);
expect(integrationsUnlockedForCheck()->call('test', 'stripe.secret')->get('check'))->not->toBeNull();
});
it('opens the answer in a modal instead of leaving it at the foot of the page', function () {
Http::fake(['api.stripe.com/v1/account' => Http::response([
'id' => 'acct_1', 'settings' => ['dashboard' => ['display_name' => 'CluPilot']],
])]);
integrationsUnlockedForCheck()
->call('test', 'stripe.secret')
->assertDispatched('openModal', function (string $event, array $params) {
return $params['component'] === 'admin.check-result'
&& $params['arguments']['entryKey'] === 'stripe.secret'
&& is_array($params['arguments']['result']);
});
});
it('shows the Stripe answer in that modal', function () {
$result = [
'ok' => true, 'account' => 'acct_1', 'business' => 'CluPilot',
'live' => false, 'restricted' => false, 'webhooks' => [],
];
Livewire::actingAs(operator('Owner'), 'operator')
->test(CheckResult::class, ['entryKey' => 'stripe.secret', 'result' => $result])
->assertOk()
->assertSee(__('secrets.check_webhooks_none'));
});
it('shows a DNS answer in that modal without reaching for Stripe fields', function () {
// Der Ergebnisblock las `account`, `live`, `webhooks` — alles nur bei
// Stripe vorhanden. Seit der DNS-Token einen eigenen Testknopf hat, kommt
// hier auch ein DnsTokenCheck-Ergebnis an, und dessen Erfolg heisst
// `writable`, läuft also in genau denselben Zweig.
$result = ['ok' => true, 'reason' => 'writable', 'probe_removed' => true];
Livewire::actingAs(operator('Owner'), 'operator')
->test(CheckResult::class, ['entryKey' => 'dns.token', 'result' => $result])
->assertOk()
->assertSee(__('secrets.check_writable'));
});
it('runs the DNS check against the value that was typed, not the stored one', function () {
// Der Grund, warum das Ergebnis hereingereicht und nicht im Modal erhoben
// wird: geprüft wird der EINGETIPPTE, noch nicht gespeicherte Token. Ein
// Modal, das selbst prüfte, sähe ihn nicht — und DnsTokenCheck legte bei
// jedem Öffnen einen neuen Probeeintrag in der echten Zone an.
Settings::set('provisioning.dns_zone', 'probe.example');
Http::fake([
'api.hetzner.cloud/v1/zones' => Http::response(['zones' => [['id' => 42, 'name' => 'probe.example']]]),
'api.hetzner.cloud/v1/zones/probe.example/rrsets' => Http::response(['rrset' => ['id' => 'x/TXT']], 201),
'api.hetzner.cloud/v1/zones/probe.example/rrsets/*' => Http::response([], 201),
]);
integrationsUnlockedForCheck()
->set('entered.dns_token', 'frisch-eingetippt')
->call('test', 'dns.token');
Http::assertSent(fn ($request) => $request->hasHeader('Authorization', 'Bearer frisch-eingetippt'));
});
it('does not open the modal for somebody without the capability', function () {
// Ein Modal ist OHNE die Route-Middleware der Seite erreichbar.
Livewire::actingAs(operator('Support'), 'operator')
->test(CheckResult::class, ['entryKey' => 'stripe.secret', 'result' => ['ok' => true]])
->assertForbidden();
});