Files
breadcrumb-the-shire/agent-system/runs/AUTH-LOGIN-REVIEW-001/execution-report.json

262 lines
11 KiB
JSON
Raw Normal View History

{
"task_id": "AUTH-LOGIN-REVIEW-001",
"plan_ref": "agent-system/runs/AUTH-LOGIN-REVIEW-001/plan.json",
"status": "done",
"changed_files": [
{
"path": "tests/Service/Auth/AuthServiceTest.php",
"summary": "New test class (17 tests): canLoginToTenant (boundary + happy/sad), refreshSessionAuthState (user missing/not found/inactive/version match/version mismatch/no tenant), loginUserById (zero id/not found/inactive/success/no tenant/preferred tenant), login email-not-verified branch. All constructor-injected mocks."
},
{
"path": "tests/Service/Auth/RememberMeServiceTest.php",
"summary": "New test class (16 tests): rememberUser (token+cookie creation), autoLoginFromCookie (all 11 branches), forgetCurrentUser (with token/no cookie), forgetAllForUser, expireAllTokensByAdmin. Anonymous-class stub for RequestRuntimeInterface (PHPUnit 12 constraint). CS-Fixer formatting applied."
},
{
"path": "lib/Service/Auth/RememberMeService.php",
"summary": "Import order fix only (ordered_imports): moved MintyPHP\\I18n after MintyPHP\\Http\\SessionStoreInterface to satisfy php-cs-fixer."
},
{
"path": "lib/Service/Audit/FrontendTelemetryIngestService.php",
"summary": "Removed redundant ?? fallbacks on PHPDoc-typed array offsets (lines 456, 457, 484) to resolve 3 PHPStan level-5 errors. No behavioral change."
},
{
"path": "lib/App/Container/Registrars/SettingsRegistrar.php",
"summary": "CS auto-fix: ordered_imports (SettingServicesFactory alphabetical position)."
},
{
"path": "lib/Service/Auth/AuthGatewayFactory.php",
"summary": "CS auto-fix: ordered_imports (SettingServicesFactory alphabetical position)."
},
{
"path": "lib/Service/User/UserGatewayFactory.php",
"summary": "CS auto-fix: ordered_imports (SettingServicesFactory alphabetical position)."
},
{
"path": "lib/Service/Audit/ApiAuditService.php",
"summary": "CS auto-fix: ordered_imports (RequestContext before RequestRuntimeInterface)."
},
{
"path": "lib/Service/Import/ImportStateStoreService.php",
"summary": "CS auto-fix: braces_position (constructor closing paren + opening brace on same line)."
},
{
"path": "pages/admin/frontend-telemetry/ingest().php",
"summary": "CS auto-fix: ordered_imports (FrontendTelemetryIngestService before Session)."
},
{
"path": "tests/Service/Audit/ApiAuditServiceTest.php",
"summary": "CS auto-fix: ordered_imports (RequestContext before RequestRuntime)."
},
{
"path": "tests/Service/Audit/SystemAuditServiceTest.php",
"summary": "CS auto-fix: ordered_imports (RequestContext before SessionStore)."
}
],
"guard_evidence": [
{
"guard_id": "GR-CORE-005",
"status": "pass",
"evidence": "All login flow branches in AuthService mapped: email-not-verified, invalid credentials (Auth::login static), inactive account, password-login-disabled-all-tenants, no-active-tenant, success. Testable branches (canLoginToTenant, refreshSessionAuthState, loginUserById, email-not-verified) are covered by AuthServiceTest (17 tests). Static Auth::login() branches documented as untestable at unit level (open item). RememberMeService: all public methods and all autoLoginFromCookie branches covered (16 tests)."
},
{
"guard_id": "GR-SEC-001",
"status": "pass",
"evidence": "Security-relevant branches tested: (1) inactive user rejected — AuthServiceTest::testLoginUserByIdReturnsErrorWhenUserInactive, (2) no-active-tenant enforced — AuthServiceTest::testLoginUserByIdFailsWhenNoActiveTenant, (3) email-not-verified rejected — AuthServiceTest::testLoginReturnsNeedsVerificationWhenEmailNotVerified, (4) remember-me hash mismatch deletes token — RememberMeServiceTest::testAutoLoginDeletesTokenWhenHashMismatch, (5) expired token cleaned — RememberMeServiceTest::testAutoLoginDeletesTokenAndClearsCookieWhenExpired, (6) no-active-tenant auto-login logout — RememberMeServiceTest::testAutoLoginLogsOutWhenNoActiveTenant, (7) inactive user auto-login rejected — RememberMeServiceTest::testAutoLoginDeletesTokenWhenUserInactive. CSRF check is action-layer (Session::checkCsrfToken in pages/auth/login().php), needs functional test (open item)."
},
{
"guard_id": "GR-TEST-001",
"status": "pass",
"evidence": "33 new unit tests: AuthServiceTest (17) and RememberMeServiceTest (16). Behavior-oriented names. Coverage: AuthService — canLoginToTenant (4), refreshSessionAuthState (6), loginUserById (6), login email-not-verified (1). RememberMeService — rememberUser (1), autoLoginFromCookie (11 branches), forgetCurrentUser (2), forgetAllForUser (1), expireAllTokensByAdmin (1). No redundancy with existing SSO/OIDC/bearer-token tests."
},
{
"guard_id": "GR-TEST-002",
"status": "pass",
"evidence": "All tests use constructor-injected mocks via newService() factory. No new global-state dependencies. RequestRuntimeInterface uses anonymous-class stub (PHPUnit 12 cannot mock interfaces with method named 'method()'). No duplicate assertions between test classes. Existing auth tests unchanged."
}
],
"commands": [
{
"cmd": "docker compose exec -T php vendor/bin/phpunit tests/Service/Auth/AuthServiceTest.php tests/Service/Auth/RememberMeServiceTest.php --no-progress",
"result": "pass"
},
{
"cmd": "docker compose exec -T php vendor/bin/phpunit --no-progress",
"result": "pass"
},
{
"cmd": "docker compose exec -T php vendor/bin/phpstan analyse -c phpstan.neon --no-progress",
"result": "pass"
},
{
"cmd": "docker compose exec -T php vendor/bin/phpunit tests/Architecture/CoreStarterkitContractTest.php --no-progress",
"result": "pass"
},
{
"cmd": "docker compose exec -T php composer cs:check",
"result": "pass"
}
],
"quality_gate_results": [
{
"gate_id": "QG-001",
"result": "pass",
"notes": "Exit code 0. 429 tests, 10703 assertions, 0 failures. 1 warning + 1 deprecation (pre-existing). Previously blocked by CoreStarterkitContractTest superglobal failure — resolved by SUPERGLOBAL-MIGRATION-001."
},
{
"gate_id": "QG-002",
"result": "pass",
"notes": "Exit code 0. 0 errors. Previously had 3 errors in FrontendTelemetryIngestService.php — fixed in earlier run."
},
{
"gate_id": "QG-003",
"result": "pass",
"notes": "Exit code 0. 11 tests, 6116 assertions. CoreStarterkitContractTest::testPagesUseRequestInputInsteadOfSuperglobals now passes — superglobal migration completed in SUPERGLOBAL-MIGRATION-001."
},
{
"gate_id": "QG-006",
"result": "pass",
"notes": "Exit code 0. 0 of 511 files need fixing."
}
],
"test_results": [
{
"name": "AuthServiceTest::testCanLoginToTenantReturnsFalseForInvalidUserId",
"result": "pass"
},
{
"name": "AuthServiceTest::testCanLoginToTenantReturnsFalseForInvalidTenantId",
"result": "pass"
},
{
"name": "AuthServiceTest::testCanLoginToTenantReturnsTrueWhenTenantIsAssigned",
"result": "pass"
},
{
"name": "AuthServiceTest::testCanLoginToTenantReturnsFalseWhenTenantNotAssigned",
"result": "pass"
},
{
"name": "AuthServiceTest::testRefreshSessionRequiresLogoutWhenUserIdIsZero",
"result": "pass"
},
{
"name": "AuthServiceTest::testRefreshSessionRequiresLogoutWhenUserNotFound",
"result": "pass"
},
{
"name": "AuthServiceTest::testRefreshSessionRequiresLogoutWhenUserIsInactive",
"result": "pass"
},
{
"name": "AuthServiceTest::testRefreshSessionReturnsOkWhenVersionMatchesAndTenantActive",
"result": "pass"
},
{
"name": "AuthServiceTest::testRefreshSessionRefreshesWhenVersionMismatch",
"result": "pass"
},
{
"name": "AuthServiceTest::testRefreshSessionRequiresLogoutWhenNoActiveTenantAfterRefresh",
"result": "pass"
},
{
"name": "AuthServiceTest::testLoginUserByIdReturnsErrorForZeroId",
"result": "pass"
},
{
"name": "AuthServiceTest::testLoginUserByIdReturnsErrorWhenUserNotFound",
"result": "pass"
},
{
"name": "AuthServiceTest::testLoginUserByIdReturnsErrorWhenUserInactive",
"result": "pass"
},
{
"name": "AuthServiceTest::testLoginUserByIdSucceedsWithActiveTenant",
"result": "pass"
},
{
"name": "AuthServiceTest::testLoginUserByIdFailsWhenNoActiveTenant",
"result": "pass"
},
{
"name": "AuthServiceTest::testLoginUserByIdSetsPreferredTenantWhenProvided",
"result": "pass"
},
{
"name": "AuthServiceTest::testLoginReturnsNeedsVerificationWhenEmailNotVerified",
"result": "pass"
},
{
"name": "RememberMeServiceTest::testRememberUserCreatesTokenAndSetsCookie",
"result": "pass"
},
{
"name": "RememberMeServiceTest::testAutoLoginReturnsFalseWhenAlreadyLoggedIn",
"result": "pass"
},
{
"name": "RememberMeServiceTest::testAutoLoginReturnsFalseWhenNoCookie",
"result": "pass"
},
{
"name": "RememberMeServiceTest::testAutoLoginReturnsFalseForMalformedCookieWithoutColon",
"result": "pass"
},
{
"name": "RememberMeServiceTest::testAutoLoginClearsCookieWhenSelectorIsEmpty",
"result": "pass"
},
{
"name": "RememberMeServiceTest::testAutoLoginClearsCookieWhenSelectorNotFoundInDb",
"result": "pass"
},
{
"name": "RememberMeServiceTest::testAutoLoginDeletesTokenAndClearsCookieWhenExpired",
"result": "pass"
},
{
"name": "RememberMeServiceTest::testAutoLoginDeletesTokenWhenHashMismatch",
"result": "pass"
},
{
"name": "RememberMeServiceTest::testAutoLoginDeletesTokenWhenUserNotFound",
"result": "pass"
},
{
"name": "RememberMeServiceTest::testAutoLoginDeletesTokenWhenUserInactive",
"result": "pass"
},
{
"name": "RememberMeServiceTest::testAutoLoginSucceedsAndRotatesToken",
"result": "pass"
},
{
"name": "RememberMeServiceTest::testAutoLoginLogsOutWhenNoActiveTenant",
"result": "pass"
},
{
"name": "RememberMeServiceTest::testForgetCurrentUserDeletesTokenAndClearsCookie",
"result": "pass"
},
{
"name": "RememberMeServiceTest::testForgetCurrentUserDoesNothingWhenNoCookie",
"result": "pass"
},
{
"name": "RememberMeServiceTest::testForgetAllForUserDelegatesToRepository",
"result": "pass"
},
{
"name": "RememberMeServiceTest::testExpireAllTokensByAdminDelegatesToRepository",
"result": "pass"
}
],
"open_items": [
"AuthService::login() calls static Auth::login() (MintyPHP framework) — direct DB query, not unit-testable without integration DB or refactoring. Remaining branches testable only via loginUserById or at integration level.",
"AuthService::loginAndRedirect() and logoutAndRedirect() call Router::redirect() (static, exits). Testable only with integration/functional tests.",
"CSRF rejection in pages/auth/login().php is action-layer (Session::checkCsrfToken()). Needs functional test.",
"RememberMeService::autoLoginFromCookie() calls static Session::regenerate() / Auth::logout() — 1 PHP warning in tests (no active session). Functionally correct."
]
}