Harden module runtime: audited listener failures and DI-first resolver

This commit is contained in:
2026-03-25 10:02:03 +01:00
parent a721ec0043
commit cb5f7037b2
12 changed files with 314 additions and 79 deletions

View File

@@ -299,43 +299,11 @@ class LdapAuthServiceTest extends TestCase
return $conn;
}
private function createMockSearchResult(): \LDAP\Result
private function createMockSearchResult(): object
{
// LDAP\Result can't be mocked directly, but since our gateway wraps
// all ldap_* calls, the actual result object is opaque to LdapAuthService.
// The gateway mock returns it, and we just need a type-compatible value.
// Use a real connection + search if ldap is available; otherwise skip.
if (!extension_loaded('ldap')) {
$this->markTestSkipped('LDAP extension not available');
}
// Create a real but unused Result object via reflection workaround.
// Since we mock getEntries(), the actual result content doesn't matter.
// But LDAP\Result has no public constructor, so we use a trick:
// We accept that the gateway returns LDAP\Result|false and our mocks
// already handle this. For this test helper, return a mock-compatible value.
// Since LdapConnectionGateway::search returns \LDAP\Result|false,
// and we mock the gateway, we can use createMock on a stdClass and
// rely on the mock returning it. But PHPUnit mock of LdapConnectionGateway
// allows any return value when configured via willReturn().
// So we just need any object - the gateway mock will return it to the service,
// and the service passes it back to gateway->getEntries().
$conn = ldap_connect('ldap://127.0.0.1:1');
if ($conn === false) {
$this->markTestSkipped('Could not create LDAP connection');
}
// We can't get a real LDAP\Result without a real server, but since
// the service only passes it to the mocked gateway, we can create
// a test double. PHPUnit allows returning any value from willReturn().
// Let's use a simple approach: the gateway mock already handles this.
// For the type system, we use an anonymous class that extends nothing
// but the mock system handles the actual passing.
// Actually, since we mock LdapConnectionGateway::search() to return
// this value, and LdapConnectionGateway::getEntries() is also mocked,
// the value just needs to be truthy (not false).
// We can use createStub to get a compatible value.
return $this->createStub(\LDAP\Result::class);
// The service treats the search handle as opaque and forwards it to
// gateway->getEntries(); in tests the gateway is mocked, so any object
// is sufficient and avoids doubling final internal LDAP classes.
return new \stdClass();
}
}