From 4967095bb8046dcb8e1627c4d63c96135bf294e1 Mon Sep 17 00:00:00 2001 From: fs Date: Mon, 13 Apr 2026 19:06:12 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20resolve=20all=20quality=20gate=20failure?= =?UTF-8?q?s=20=E2=80=94=20i18n=20key,=20typography=20tokens,=20PHPStan=20?= =?UTF-8?q?errors,=20style?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add missing i18n key "LDAP attribute map could not be encoded" (de+en) - Replace raw font-weight/line-height with design tokens in app-topbar.css - Fix import ordering in SchedulerRunService.php (php-cs-fixer) - Fix PHPStan mock chain errors in DebitorDetailServiceTest and TenantSsoServiceTest (PHPUnit 12 API) - Simplify redundant comparison in NotificationService dedupe window - Add PHPStan type hint for mock callback array in SchedulerJobFailedNotificationListenerTest - Fix undefined variable and add flow-analysis suppression in login().php - Increase dev PHP memory_limit to 1G for PHPStan (prod stays 256M) All 6 quality gates now pass: QG-001 (1618 tests), QG-002 (0 errors), QG-003 (6630 assertions), QG-006 (0 fixable), QG-008, QG-009. Co-Authored-By: Claude Opus 4.6 --- docker/php/php.ini | 2 +- i18n/default_de.json | 1 + i18n/default_en.json | 1 + lib/Service/Scheduler/SchedulerRunService.php | 2 +- .../Module/Helpdesk/Service/DebitorDetailServiceTest.php | 2 +- .../Module/Notifications/Service/NotificationService.php | 2 +- .../SchedulerJobFailedNotificationListenerTest.php | 1 + pages/auth/login().php | 6 +++--- tests/Service/Auth/TenantSsoServiceTest.php | 2 +- web/css/layout/app-topbar.css | 4 ++-- 10 files changed, 13 insertions(+), 10 deletions(-) diff --git a/docker/php/php.ini b/docker/php/php.ini index 597a797..4ae18b8 100644 --- a/docker/php/php.ini +++ b/docker/php/php.ini @@ -5,7 +5,7 @@ error_reporting=E_ALL & ~E_DEPRECATED log_errors=1 ; --- Resource limits --- -memory_limit=256M +memory_limit=1G upload_max_filesize=10M post_max_size=12M diff --git a/i18n/default_de.json b/i18n/default_de.json index fd00a25..a2ca18a 100644 --- a/i18n/default_de.json +++ b/i18n/default_de.json @@ -1434,6 +1434,7 @@ "Write-only. Leave empty to keep current value.": "Nur Schreibzugriff. Leer lassen, um den aktuellen Wert beizubehalten.", "Your account is deactivated.": "Ihr Konto ist deaktiviert.", "LDAP": "LDAP", + "LDAP attribute map could not be encoded": "LDAP-Attributzuordnung konnte nicht kodiert werden", "Drop file here or click to select": "Datei hierher ziehen oder klicken", "Remove selected file": "Ausgewaehlte Datei entfernen", "Replace": "Ersetzen", diff --git a/i18n/default_en.json b/i18n/default_en.json index 9ff5db6..0f4ab91 100644 --- a/i18n/default_en.json +++ b/i18n/default_en.json @@ -1434,6 +1434,7 @@ "Write-only. Leave empty to keep current value.": "Write-only. Leave empty to keep current value.", "Your account is deactivated.": "Your account is deactivated.", "LDAP": "LDAP", + "LDAP attribute map could not be encoded": "LDAP attribute map could not be encoded", "Drop file here or click to select": "Drop file here or click to select", "Remove selected file": "Remove selected file", "Replace": "Replace", diff --git a/lib/Service/Scheduler/SchedulerRunService.php b/lib/Service/Scheduler/SchedulerRunService.php index 0ff686c..eeadeb4 100644 --- a/lib/Service/Scheduler/SchedulerRunService.php +++ b/lib/Service/Scheduler/SchedulerRunService.php @@ -2,13 +2,13 @@ namespace MintyPHP\Service\Scheduler; +use MintyPHP\App\Module\ModuleEventDispatcher; use MintyPHP\Domain\Taxonomy\ScheduledJobRunStatus; use MintyPHP\Domain\Taxonomy\ScheduledJobTriggerType; use MintyPHP\Domain\Taxonomy\SchedulerRuntimeResult; use MintyPHP\Repository\Scheduler\ScheduledJobRepositoryInterface; use MintyPHP\Repository\Scheduler\ScheduledJobRunRepositoryInterface; use MintyPHP\Repository\Scheduler\SchedulerRuntimeRepositoryInterface; -use MintyPHP\App\Module\ModuleEventDispatcher; use MintyPHP\Repository\Support\DatabaseSessionRepository; use MintyPHP\Repository\Support\RepoQuery; use MintyPHP\Service\Audit\AuditRecorderInterface; diff --git a/modules/helpdesk/tests/Module/Helpdesk/Service/DebitorDetailServiceTest.php b/modules/helpdesk/tests/Module/Helpdesk/Service/DebitorDetailServiceTest.php index 1bf5800..8896661 100644 --- a/modules/helpdesk/tests/Module/Helpdesk/Service/DebitorDetailServiceTest.php +++ b/modules/helpdesk/tests/Module/Helpdesk/Service/DebitorDetailServiceTest.php @@ -1350,7 +1350,7 @@ class DebitorDetailServiceTest extends TestCase { $futureDate = date('Y-m-d', strtotime('+7 days')); $gateway = $this->createMock(BcODataGateway::class); - $gateway->method('getMeetingsForCustomer')->with('10254')->willReturn([ + $gateway->expects($this->any())->method('getMeetingsForCustomer')->with('10254')->willReturn([ ['Entry_No' => 1, 'Appointment_Date' => $futureDate, 'Customer_No' => '10254', 'Customer_Name' => 'Test GmbH', 'Salesperson_Code' => 'MER', 'Comment' => 'Workshop', 'Released_by' => '', 'Release_Date' => '0001-01-01'], ]); diff --git a/modules/notifications/lib/Module/Notifications/Service/NotificationService.php b/modules/notifications/lib/Module/Notifications/Service/NotificationService.php index 216107f..70cabb0 100644 --- a/modules/notifications/lib/Module/Notifications/Service/NotificationService.php +++ b/modules/notifications/lib/Module/Notifications/Service/NotificationService.php @@ -236,7 +236,7 @@ class NotificationService } $windowMinutes = self::DEDUPE_TYPES[$type]; - $windowMinutes = is_int($windowMinutes) && $windowMinutes > 0 ? $windowMinutes : self::DEDUPE_WINDOW_MINUTES; + $windowMinutes = is_int($windowMinutes) ? $windowMinutes : self::DEDUPE_WINDOW_MINUTES; $tenantScope = $tenantId !== null && $tenantId > 0 ? $tenantId : 0; $raw = implode('|', [ diff --git a/modules/notifications/tests/Module/Notifications/Listeners/SchedulerJobFailedNotificationListenerTest.php b/modules/notifications/tests/Module/Notifications/Listeners/SchedulerJobFailedNotificationListenerTest.php index 9f25259..298332f 100644 --- a/modules/notifications/tests/Module/Notifications/Listeners/SchedulerJobFailedNotificationListenerTest.php +++ b/modules/notifications/tests/Module/Notifications/Listeners/SchedulerJobFailedNotificationListenerTest.php @@ -39,6 +39,7 @@ class SchedulerJobFailedNotificationListenerTest extends TestCase [30, [2, 3]], ]); + /** @var list $calls */ $calls = []; $this->notifService->expects($this->exactly(4)) ->method('createFromMessage') diff --git a/pages/auth/login().php b/pages/auth/login().php index f89e2e8..6615b01 100644 --- a/pages/auth/login().php +++ b/pages/auth/login().php @@ -88,14 +88,14 @@ $resolveLoginCandidates = static function (string $inputEmail) use ($userReadRep $isKnownActiveUser = $user && (int) ($user['active'] ?? 0) === 1 && (int) ($user['id'] ?? 0) > 0; $tenants = []; - $discovery = false; - if ($isKnownActiveUser) { $userId = (int) $user['id']; $tenants = $userTenantContextService->getAssignedActiveTenants($userId); } // Fallback: domain-based SSO discovery for users not yet provisioned locally + $discovery = false; + $discoveryMethodsByTenantId = []; if (!$tenants) { $discoveryResults = $tenantSsoService->discoverTenantsByEmailDomain($emailValue); if (!$discoveryResults) { @@ -103,7 +103,6 @@ $resolveLoginCandidates = static function (string $inputEmail) use ($userReadRep } $discovery = true; $tenants = array_map(static fn (array $r): array => $r['tenant'], $discoveryResults); - $discoveryMethodsByTenantId = []; foreach ($discoveryResults as $r) { $discoveryMethodsByTenantId[(int) $r['id']] = $r['methods']; } @@ -120,6 +119,7 @@ $resolveLoginCandidates = static function (string $inputEmail) use ($userReadRep if ($tenantSlug === '') { continue; } + /** @phpstan-ignore ternary.alwaysFalse ($discovery is set to true inside the !$tenants branch that also reassigns $tenants) */ $methods = $discovery ? ($discoveryMethodsByTenantId[$tenantId] ?? ['local' => false, 'microsoft' => false, 'microsoft_reason' => '', 'ldap' => false, 'ldap_reason' => '']) : $tenantSsoService->resolveTenantLoginMethods($tenantId); diff --git a/tests/Service/Auth/TenantSsoServiceTest.php b/tests/Service/Auth/TenantSsoServiceTest.php index 37eb1a1..b34f8a0 100644 --- a/tests/Service/Auth/TenantSsoServiceTest.php +++ b/tests/Service/Auth/TenantSsoServiceTest.php @@ -467,7 +467,7 @@ class TenantSsoServiceTest extends TestCase $tenantGateway->method('findById')->willReturn(['id' => 5, 'status' => 'active', 'uuid' => 'abc', 'description' => 'Acme']); $microsoftRepo = $this->createMock(TenantMicrosoftAuthRepositoryInterface::class); - $microsoftRepo->method('findEnabledWithExplicitDomain')->with('acme.com')->willReturn([ + $microsoftRepo->expects($this->any())->method('findEnabledWithExplicitDomain')->with('acme.com')->willReturn([ ['tenant_id' => 5, 'allowed_domains' => 'acme.com'], ]); $microsoftRepo->method('findByTenantId')->willReturn([ diff --git a/web/css/layout/app-topbar.css b/web/css/layout/app-topbar.css index 62e1c1d..24b6686 100644 --- a/web/css/layout/app-topbar.css +++ b/web/css/layout/app-topbar.css @@ -174,8 +174,8 @@ box-shadow: none; color: var(--app-topbar-muted); font-size: inherit; - font-weight: normal; - line-height: 1; + font-weight: var(--font-regular); + line-height: var(--leading-none); cursor: pointer; transition: background-color var(--app-transition),