diff --git a/tests/BaseControllerDependenciesTrait.php b/tests/BaseControllerDependenciesTrait.php index 439046e..578ecdd 100644 --- a/tests/BaseControllerDependenciesTrait.php +++ b/tests/BaseControllerDependenciesTrait.php @@ -119,6 +119,8 @@ protected function getContainer(array $override_settings=[]): \Psr\Container\Con '\\SMVCTools\\Tests\\TestObjects\\', ]; $psr11Container['vespula_auth'] = fn() => $this->newVespulaAuth(); + + $psr11Container['logger'] = fn() => new \SMVCTools\Tests\TestObjects\InMemoryLogger(); //Object for rendering layout files $psr11Container['new_layout_renderer'] = $psr11Container->factory(function () { diff --git a/tests/BaseControllerTest.php b/tests/BaseControllerTest.php index e0b4f34..8a8db3e 100644 --- a/tests/BaseControllerTest.php +++ b/tests/BaseControllerTest.php @@ -1235,6 +1235,183 @@ public function testThat_doLogin_WorksAsExpected() { $result3 ); self::assertFalse($controller->isLoggedIn()); + + //////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////// + + // Call doLogin with an Auth object that always throws a + // \Vespula\Auth\Exception whose message string + // is not in $backendIssues & $usernamePswdMismatchIssues + // everytime the login method is called on it. + + $exceptionThrowingAuth = $this->newVespulaAuth( + \SMVCTools\Tests\TestObjects\AlwaysThrowExceptionOnLoginAuth::class + ); + $originalAuth = $controller->getVespulaAuthObject(); + $controller->setVespulaAuthObject($exceptionThrowingAuth); + + //reset the logger first so that only log messages related to the next + //call of doLogin are present in the log object. + $controller->getContainerItem('logger')->reset(); + + $result4 = $controller->doLoginPublic( + $controller->getVespulaAuthObject(), $bad_credentials, $success_redirect_path + ); + + // Right error message was returned + self::assertEquals( + $controller->getAppSetting('base_controller_do_login_auth_v_auth_exception_general_msg'), + $result4 + ); + + // logger contains expected error message + self::assertTrue( + $this->stringIsContainedInAtLeastOneArrayItem( + $controller->getContainerItem('logger')->getLogEntries(), + \str_replace( + '
', + PHP_EOL, + $controller->getAppSetting('base_controller_do_login_auth_v_auth_exception_general_msg') + ) + ) + ); + + // we should not be logged in + self::assertFalse($controller->isLoggedIn()); + + //////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////// + + // Call doLogin with an Auth object that always throws a + // \Vespula\Auth\Exception whose message string + // is in $backendIssues everytime the login method is called on it. + + $exceptionThrowingAuth->setExceptionMessage('EXCEPTION_LDAP_CONNECT_FAILED'); + + //reset the logger first so that only log messages related to the next + //call of doLogin are present in the log object. + $controller->getContainerItem('logger')->reset(); + + $result5 = $controller->doLoginPublic( + $controller->getVespulaAuthObject(), $bad_credentials, $success_redirect_path + ); + + // Right error message was returned + self::assertEquals( + $controller->getAppSetting('base_controller_do_login_auth_v_auth_exception_back_end_msg'), + $result5 + ); + + // logger contains expected error message + self::assertTrue( + $this->stringIsContainedInAtLeastOneArrayItem( + $controller->getContainerItem('logger')->getLogEntries(), + \str_replace( + '
', + PHP_EOL, + $controller->getAppSetting('base_controller_do_login_auth_v_auth_exception_back_end_msg') + ) + ) + ); + + // we should not be logged in + self::assertFalse($controller->isLoggedIn()); + + //////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////// + + // Call doLogin with a credentials array not having any username or + // password keys, leading to a \Vespula\Auth\Exception being thrown + + $controller->setVespulaAuthObject($originalAuth); + + //reset the logger first so that only log messages related to the next + //call of doLogin are present in the log object. + $controller->getContainerItem('logger')->reset(); + + $credentials_with_no_uname_or_passwd = []; + + $result6 = $controller->doLoginPublic( + $controller->getVespulaAuthObject(), + $credentials_with_no_uname_or_passwd, + $success_redirect_path + ); + + // Right error message was returned + self::assertEquals( + $controller->getAppSetting('base_controller_do_login_auth_v_auth_exception_user_passwd_msg'), + $result6 + ); + + // logger contains expected error message + self::assertTrue( + $this->stringIsContainedInAtLeastOneArrayItem( + $controller->getContainerItem('logger')->getLogEntries(), + \str_replace( + '
', + PHP_EOL, + $controller->getAppSetting('base_controller_do_login_auth_v_auth_exception_user_passwd_msg') + ) + ) + ); + + // we should not be logged in + self::assertFalse($controller->isLoggedIn()); + + //////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////// + + // Call doLogin with an Auth object that throws a general + // \Exception whose message string. + + $exceptionThrowingAuth->setExceptionMessage('Booo Booo!'); + $exceptionThrowingAuth->setExceptionClass(\Exception::class); + $controller->setVespulaAuthObject($exceptionThrowingAuth); + + //reset the logger first so that only log messages related to the next + //call of doLogin are present in the log object. + $controller->getContainerItem('logger')->reset(); + + $result7 = $controller->doLoginPublic( + $controller->getVespulaAuthObject(), $bad_credentials, $success_redirect_path + ); + + // Right error message was returned + self::assertEquals( + $controller->getAppSetting('base_controller_do_login_auth_exception_msg'), + $result7 + ); + + // logger contains expected error message + self::assertTrue( + $this->stringIsContainedInAtLeastOneArrayItem( + $controller->getContainerItem('logger')->getLogEntries(), + \str_replace( + '
', + PHP_EOL, + $controller->getAppSetting('base_controller_do_login_auth_exception_msg') + ) + ) + ); + + // we should not be logged in + self::assertFalse($controller->isLoggedIn()); + } + + protected function stringIsContainedInAtLeastOneArrayItem(array $haystacks, string $needle): bool { + + $contains = false; + + foreach ($haystacks as $haystack) { + + if(str_contains($haystack, $needle)) { + + $contains = true; + break; + } + } + + return $contains; } /** diff --git a/tests/test-objects/AlwaysThrowExceptionOnLoginAuth.php b/tests/test-objects/AlwaysThrowExceptionOnLoginAuth.php new file mode 100644 index 0000000..cac63f2 --- /dev/null +++ b/tests/test-objects/AlwaysThrowExceptionOnLoginAuth.php @@ -0,0 +1,33 @@ +exceptionMessage = $msg; + } + + public function setExceptionClass(string $class) { + + $this->exceptionClass = $class; + } + + public function login(array $credentials): void { + + $exceptionClass = $this->exceptionClass; + + throw new $exceptionClass($this->exceptionMessage); + } +} diff --git a/tests/test-objects/InMemoryLogger.php b/tests/test-objects/InMemoryLogger.php index bdfb1dd..18fab9f 100644 --- a/tests/test-objects/InMemoryLogger.php +++ b/tests/test-objects/InMemoryLogger.php @@ -31,4 +31,14 @@ public function log($level, $message, array $context=[]) { $this->log_entries[] = "[LEVEL: {$level}] [MESSAGE: {$message}]"; } + + public function reset():void { + + $this->log_entries = []; + } + + public function getLogEntries(): array { + + return $this->log_entries; + } }