CluPilotCloud/tests/Feature/Admin/OpenWorkTest.php

100 lines
4.2 KiB
PHP

<?php
use App\Support\Navigation;
use App\Support\OpenWork;
use Illuminate\Support\Facades\File;
/**
* Die Seite mit den offenen Punkten.
*
* Sie existiert, weil „was ist noch nicht fertig" bis dahin in Köpfen und
* Notizen stand. Was diese Tests festhalten, ist nicht die Liste selbst — die
* soll sich ändern, das ist ihr Zweck —, sondern dass jeder Eintrag
* vollständig ist und die Seite nichts verschweigt.
*/
it('zeigt jeden offenen Punkt, ohne einen zu verschlucken', function () {
$this->actingAs(admin(), 'operator')
->get(route('admin.open-work'))
->assertOk()
->assertSee(__('open_work.title'));
$html = $this->actingAs(admin(), 'operator')->get(route('admin.open-work'))->getContent();
foreach (OpenWork::all() as $item) {
expect($html)->toContain(e($item['title']));
}
});
it('nennt zu jedem Punkt wo, was fehlt und was passiert, wenn es so bleibt', function () {
// Ohne den dritten Satz ist so eine Liste ein Wunschzettel: er entscheidet
// die Reihenfolge, nicht das Gefühl.
foreach (OpenWork::all() as $item) {
foreach (['title', 'state', 'where', 'missing', 'risk'] as $field) {
expect($item[$field] ?? '')->not->toBe('', "{$item['title']}\" hat kein Feld {$field}.");
}
// Ein Zustand ohne Übersetzung wäre ein Kasten mit „open_work.state.x".
expect(__('open_work.state.'.$item['state']))->not->toBe('open_work.state.'.$item['state']);
}
});
it('führt die zwei bezahlten Module, die nichts tun, als solche', function () {
// Der Anlass für die ganze Seite. Verschwinden sie hier stillschweigend,
// ist die Liste wertlos — sie kosten Geld, solange sie offen sind.
$sold = collect(OpenWork::all())->where('state', OpenWork::SOLD)->pluck('title')->implode(' ');
expect($sold)->toContain('Sicherungsort')
->and($sold)->toContain('Office');
});
it('steht jedem offen, der die Konsole öffnen darf', function () {
// Kein eigenes Recht: wer hier arbeitet, soll wissen, worauf er sich
// verlassen kann und worauf nicht.
$entry = collect(Navigation::console())
->flatMap(fn (array $g) => $g['items'])
->firstWhere(0, 'admin.open-work');
expect($entry)->not->toBeNull()
->and($entry[3])->toBeNull();
});
it('stellt das nach vorne, was gerade Schaden anrichtet', function () {
// Nicht in der Reihenfolge, in der es geschrieben wurde — sondern danach,
// was ein Punkt HEUTE anrichtet. „Verkauft, nicht geliefert" kostet in
// diesem Moment Geld; „beschlossen" tut gar nichts, bis jemand anfängt.
expect(array_keys(OpenWork::grouped()))
->toBe(array_values(array_filter(
OpenWork::ORDER,
fn (string $s) => (OpenWork::counts()[$s] ?? 0) > 0,
)));
// Und der Sammelsatz oben nennt den dringendsten Zustand, der wirklich
// vorkommt — nicht einen festen.
expect(OpenWork::worst())->toBe(array_key_first(OpenWork::grouped()));
});
it('lässt keine leere Gruppe stehen', function () {
// Eine Überschrift ohne Inhalt liest sich wie ein Ladefehler. Derselbe
// Fehler, der in der Seitenleiste schon einmal zuschlug.
foreach (OpenWork::grouped() as $state => $items) {
expect($items)->not->toBeEmpty("Gruppe {$state} ist leer.");
}
});
it('folgt der Formensprache der Bereitschaftsseite, nicht der eines Formulars', function () {
// Die erste Fassung nahm das Muster der Anlegen-Seite: `lbl`-Etikett,
// große Kopfzeile, pro Punkt eine eigene Karte. Für eine Liste mit
// Zuständen gibt es in dieser Konsole längst ein Muster, und zwei Muster
// für ein Problem sind zwei Sprachen.
$page = File::get(resource_path('views/livewire/admin/open-work.blade.php'));
expect($page)->toContain('divide-y divide-line')
// Und keine Zustands-Plakette je Zeile: die Karte darüber sagt den
// Zustand, alle Zeilen darin teilen ihn. Sie wiederholte dasselbe Wort
// dreimal pro Bildschirm.
->and($page)->not->toContain('<x-ui.badge')
// Kein Etikett und keine Formular-Kopfzeile.
->and($page)->not->toContain('lbl">')
->and($page)->not->toContain('min-[901px]:text-[30px]');
});