M4: PWA + Mobile-UX – Manifest/Service-Worker + Icons, Auf/Ab-Reorder, FAB, Touch-Targets + Safe-Area, Nav-Entdupidung, Heute-Highlight, Aktions-Trennung (Abhaken vs. Bearbeiten/Löschen), OIDC-Fixes + PWA-Tests

This commit is contained in:
2026-09-20 13:04:52 +02:00
parent 0db09bf098
commit f4c20d0504
23 changed files with 938 additions and 161 deletions
@@ -0,0 +1,75 @@
<?php
declare(strict_types=1);
namespace App\Tests\Functional\UI\Essen;
use Doctrine\ORM\Tools\SchemaTool;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\BrowserKit\Cookie;
final class PwaSmokeTest extends WebTestCase
{
private static function authedClient(): KernelBrowser
{
$client = self::createClient();
$client->followRedirects(false);
$em = self::getContainer()->get('doctrine')->getManager();
$schemaTool = new SchemaTool($em);
$schemaTool->dropSchema($em->getMetadataFactory()->getAllMetadata());
$schemaTool->createSchema($em->getMetadataFactory()->getAllMetadata());
$session = self::getContainer()->get('session.factory')->createSession();
$session->start();
foreach (['auth_sub' => 'test-sub', 'auth_name' => 'Jens', 'auth_email' => 'jens@ljh31.de'] as $k => $v) {
$session->set($k, $v);
}
$session->save();
$client->getCookieJar()->set(new Cookie($session->getName(), $session->getId()));
return $client;
}
public function testIndexHasPwaAndMobileMarkers(): void
{
$client = self::authedClient();
$client->request('GET', '/mahlzeiten');
self::assertResponseIsSuccessful();
$html = (string) $client->getResponse()->getContent();
self::assertStringContainsString('manifest.webmanifest', $html);
self::assertStringContainsString('class="fab"', $html);
self::assertStringContainsString("register('/sw.js')", $html);
self::assertStringContainsString('href="/mahlzeiten/tage"', $html);
}
public function testTageHighlightsHeutigerTag(): void
{
$client = self::authedClient();
$client->request('POST', '/mahlzeiten', [
'name' => 'Heutiges Gericht',
'notiz' => '',
'wochentage' => [self::heuteWert()],
]);
$client->request('GET', '/mahlzeiten/tage');
self::assertResponseIsSuccessful();
$h2 = $client->getCrawler()->filterXPath('//h2[@data-heute="1"]');
self::assertCount(1, $h2, 'Genau ein <h2> trägt das data-heute-Attribut.');
self::assertSame(self::heuteName(), trim($h2->text()));
}
private static function heuteName(): string
{
$iso = (int) (new \DateTimeImmutable('now', new \DateTimeZone('Europe/Berlin')))->format('N');
return ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So'][$iso - 1];
}
private static function heuteWert(): string
{
$iso = (int) (new \DateTimeImmutable('now', new \DateTimeZone('Europe/Berlin')))->format('N');
return ['mo', 'di', 'mi', 'do', 'fr', 'sa', 'so'][$iso - 1];
}
}