Split auth login accessibility contracts

This commit is contained in:
2026-03-19 19:12:25 +01:00
parent 2de0039d4f
commit 115723fcd6
8 changed files with 122 additions and 79 deletions

View File

@@ -53,7 +53,10 @@
<file>tests/Architecture/AsideNavigationContractTest.php</file>
<file>tests/Architecture/AuthHelpLinksPageContractTest.php</file>
<file>tests/Architecture/AuthHelpLinksPartialContractTest.php</file>
<file>tests/Architecture/AuthLoginAccessibilityContractTest.php</file>
<file>tests/Architecture/AuthLoginFieldAccessibilityContractTest.php</file>
<file>tests/Architecture/AuthLoginPasswordToggleContractTest.php</file>
<file>tests/Architecture/AuthLoginTemplateAccessibilityContractTest.php</file>
<file>tests/Architecture/AuthLoginTenantSelectionContractTest.php</file>
<file>tests/Architecture/AuthzUiActionContractTest.php</file>
<file>tests/Architecture/AuthzUiLayoutContractTest.php</file>
<file>tests/Architecture/AuthzUiTemplateContractTest.php</file>

View File

@@ -0,0 +1,21 @@
<?php
namespace MintyPHP\Tests\Architecture;
final class AuthLoginAccessibilityContractFiles
{
/**
* @return list<string>
*/
public static function authLoginTemplates(): array
{
return [
'pages/auth/login(login).phtml',
'pages/auth/register(login).phtml',
'pages/auth/forgot(login).phtml',
'pages/auth/reset(login).phtml',
'pages/auth/verify(login).phtml',
'pages/auth/verify-email(login).phtml',
];
}
}

View File

@@ -1,77 +0,0 @@
<?php
namespace MintyPHP\Tests\Architecture;
use PHPUnit\Framework\TestCase;
class AuthLoginAccessibilityContractTest extends TestCase
{
use ProjectFileAssertionSupport;
/**
* @return list<string>
*/
private function authLoginTemplates(): array
{
return [
'pages/auth/login(login).phtml',
'pages/auth/register(login).phtml',
'pages/auth/forgot(login).phtml',
'pages/auth/reset(login).phtml',
'pages/auth/verify(login).phtml',
'pages/auth/verify-email(login).phtml',
];
}
public function testAuthLoginTemplatesDoNotUseRoleButtonLinks(): void
{
foreach ($this->authLoginTemplates() as $file) {
$content = $this->readProjectFile($file);
$this->assertStringNotContainsString('role="button"', $content, $file);
}
}
public function testAuthLoginErrorNoticesUseAssertiveLiveRegions(): void
{
foreach ($this->authLoginTemplates() as $file) {
$content = $this->readProjectFile($file);
$this->assertStringContainsString('class="notice" data-variant="error" role="alert" aria-live="assertive"', $content, $file);
}
}
public function testTenantSelectionUsesSemanticFieldsetAndTextLabel(): void
{
$content = $this->readProjectFile('pages/auth/login(login).phtml');
$this->assertStringContainsString('login-tenant-fieldset', $content);
$this->assertStringContainsString('login-tenant-select-label', $content);
$this->assertStringContainsString('login-tenant-choice-text', $content);
$this->assertStringContainsString('login-microsoft-link', $content);
}
public function testAuthLoginFormsExposeErrorDescriptionForInputs(): void
{
$describedByPattern = '/aria-describedby="[^"]*\\$errorNoticeId[^"]*"/';
foreach ($this->authLoginTemplates() as $file) {
$content = $this->readProjectFile($file);
$this->assertMatchesRegularExpression($describedByPattern, $content, $file);
$this->assertStringContainsString('aria-invalid="true"', $content, $file);
}
}
public function testPasswordToggleUsesLocalizedLabelsAndKeyboardFocusableControl(): void
{
$layoutContent = $this->readProjectFile('templates/login.phtml');
$scriptContent = $this->readProjectFile('web/js/components/app-password-toggle.js');
$this->assertStringContainsString('data-password-toggle-show-label', $layoutContent);
$this->assertStringContainsString('data-password-toggle-hide-label', $layoutContent);
$this->assertStringContainsString('passwordToggleShowLabel', $scriptContent);
$this->assertStringContainsString('passwordToggleHideLabel', $scriptContent);
$this->assertStringNotContainsString('toggle.tabIndex = -1;', $scriptContent);
$this->assertStringNotContainsString("'Show password'", $scriptContent);
$this->assertStringNotContainsString("'Hide password'", $scriptContent);
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace MintyPHP\Tests\Architecture;
use PHPUnit\Framework\TestCase;
final class AuthLoginFieldAccessibilityContractTest extends TestCase
{
use ProjectFileAssertionSupport;
public function testAuthLoginFormsExposeErrorDescriptionForInputs(): void
{
$describedByPattern = '/aria-describedby="[^"]*\\$errorNoticeId[^"]*"/';
foreach (AuthLoginAccessibilityContractFiles::authLoginTemplates() as $file) {
$content = $this->readProjectFile($file);
$this->assertMatchesRegularExpression($describedByPattern, $content, $file);
$this->assertStringContainsString('aria-invalid="true"', $content, $file);
}
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace MintyPHP\Tests\Architecture;
use PHPUnit\Framework\TestCase;
final class AuthLoginPasswordToggleContractTest extends TestCase
{
use ProjectFileAssertionSupport;
public function testPasswordToggleUsesLocalizedLabelsAndKeyboardFocusableControl(): void
{
$layoutContent = $this->readProjectFile('templates/login.phtml');
$scriptContent = $this->readProjectFile('web/js/components/app-password-toggle.js');
$this->assertStringContainsString('data-password-toggle-show-label', $layoutContent);
$this->assertStringContainsString('data-password-toggle-hide-label', $layoutContent);
$this->assertStringContainsString('passwordToggleShowLabel', $scriptContent);
$this->assertStringContainsString('passwordToggleHideLabel', $scriptContent);
$this->assertStringNotContainsString('toggle.tabIndex = -1;', $scriptContent);
$this->assertStringNotContainsString("'Show password'", $scriptContent);
$this->assertStringNotContainsString("'Hide password'", $scriptContent);
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace MintyPHP\Tests\Architecture;
use PHPUnit\Framework\TestCase;
final class AuthLoginTemplateAccessibilityContractTest extends TestCase
{
use ProjectFileAssertionSupport;
public function testAuthLoginTemplatesDoNotUseRoleButtonLinks(): void
{
foreach (AuthLoginAccessibilityContractFiles::authLoginTemplates() as $file) {
$content = $this->readProjectFile($file);
$this->assertStringNotContainsString('role="button"', $content, $file);
}
}
public function testAuthLoginErrorNoticesUseAssertiveLiveRegions(): void
{
foreach (AuthLoginAccessibilityContractFiles::authLoginTemplates() as $file) {
$content = $this->readProjectFile($file);
$this->assertStringContainsString(
'class="notice" data-variant="error" role="alert" aria-live="assertive"',
$content,
$file
);
}
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace MintyPHP\Tests\Architecture;
use PHPUnit\Framework\TestCase;
final class AuthLoginTenantSelectionContractTest extends TestCase
{
use ProjectFileAssertionSupport;
public function testTenantSelectionUsesSemanticFieldsetAndTextLabel(): void
{
$content = $this->readProjectFile('pages/auth/login(login).phtml');
$this->assertStringContainsString('login-tenant-fieldset', $content);
$this->assertStringContainsString('login-tenant-select-label', $content);
$this->assertStringContainsString('login-tenant-choice-text', $content);
$this->assertStringContainsString('login-microsoft-link', $content);
}
}

View File

@@ -33,6 +33,6 @@ ohne dass jede Aenderung immer die komplette Suite im Kopf behalten muss.
## Naechste Refactor-Kandidaten
- `tests/Architecture/ContainerFactoryContractTest.php`
- `tests/Architecture/AuthLoginAccessibilityContractTest.php`
- `tests/Architecture/SecurityCryptoContractTest.php`
- `tests/Architecture/AsideNavigationContractTest.php`
- `tests/Architecture/AuthzApiBootstrapContractTest.php`