diff --git a/tests/php-unit-tests/src/BaseTestCase/ItopDataTestCase.php b/tests/php-unit-tests/src/BaseTestCase/ItopDataTestCase.php index 30a94d743..d0a4aa408 100644 --- a/tests/php-unit-tests/src/BaseTestCase/ItopDataTestCase.php +++ b/tests/php-unit-tests/src/BaseTestCase/ItopDataTestCase.php @@ -925,11 +925,12 @@ abstract class ItopDataTestCase extends ItopTestCase * * @param $iExpectedCount Number of MySQL queries that should be executed * @param callable $oFunction Operations to perform + * @param string $sMessage Message to display in case of failure * * @throws \MySQLException * @throws \MySQLQueryHasNoResultException */ - protected function assertDBQueryCount($iExpectedCount, callable $oFunction) + protected function assertDBQueryCount($iExpectedCount, callable $oFunction, $sMessage = '') { $iInitialCount = (int) CMDBSource::QueryToScalar("SHOW SESSION STATUS LIKE 'Queries'", 1); $oFunction(); @@ -937,7 +938,13 @@ abstract class ItopDataTestCase extends ItopTestCase $iCount = $iFinalCount - 1 - $iInitialCount; if ($iCount != $iExpectedCount) { - $this->fail("Expected $iExpectedCount queries. $iCount have been executed."); + if ($sMessage === '') { + $sMessage = "Expected $iExpectedCount queries. $iCount have been executed."; + } + else { + $sMessage .= " - Expected $iExpectedCount queries. $iCount have been executed."; + } + $this->fail($sMessage); } else { @@ -960,6 +967,18 @@ abstract class ItopDataTestCase extends ItopTestCase $this->assertEquals($iExpectedCount, $iCount, "Found $iCount changes for object $sClass::$iId"); } + /** + * @since 3.2.1 + */ + protected static function assertIsDBObject(string $sExpectedClass, ?int $iExpectedKey, $oObject, ?string $sMessage = '') + { + self::assertNotNull($oObject, $sMessage); + self::assertInstanceOf($sExpectedClass, $oObject, $sMessage); + if ($iExpectedKey !== null) { + self::assertEquals($iExpectedKey, $oObject->GetKey(), $sMessage); + } + } + /** * Import a set of XML files describing a consistent set of iTop objects * @param string[] $aFiles diff --git a/tests/php-unit-tests/unitary-tests/core/UserRightsTest.php b/tests/php-unit-tests/unitary-tests/core/UserRightsTest.php index 6a3d3d7a2..5a743a0e8 100644 --- a/tests/php-unit-tests/unitary-tests/core/UserRightsTest.php +++ b/tests/php-unit-tests/unitary-tests/core/UserRightsTest.php @@ -491,52 +491,65 @@ class UserRightsTest extends ItopDataTestCase public function testFindUser_ExistingInternalUser() { - $sLogin = 'UserRightsFindUser'.uniqid(); - $iKey = $this->CreateUser($sLogin, self::$aURP_Profiles['Administrator'])->GetKey(); - $oUser = $this->InvokeNonPublicStaticMethod(UserRights::class, "FindUser", [$sLogin]); + $sLogin = 'AnInternalUser'.uniqid(); + $iKey = $this->GivenObjectInDB(\UserLocal::class, ['login' => $sLogin]); - $this->assertNotNull($oUser); - $this->assertEquals($iKey, $oUser->GetKey()); - $this->assertEquals(\UserLocal::class, get_class($oUser)); + $this->assertDBQueryCount( + 1, + fn() => $this->FindUserAndAssertItHasBeenFound($sLogin, $iKey), + 'A query should be performed the first time FindUser is called' + ); - $this->assertDBQueryCount(0, function() use ($sLogin, $iKey){ - $oUser = $this->InvokeNonPublicStaticMethod(UserRights::class, "FindUser", [$sLogin]); - static::assertEquals($iKey, $oUser->GetKey()); - static::assertEquals(\UserLocal::class, get_class($oUser)); - }); + $this->assertDBQueryCount( + 0, + fn() => $this->FindUserAndAssertItHasBeenFound($sLogin, $iKey), + 'The cache should prevent additional queries on subsequent calls' + ); } public function testFindUser_ExistingExternalUser() { - $sLogin = 'UserRightsFindUser'.uniqid(); + $sLogin = 'AnExternalUser'.uniqid(); + $iKey = $this->GivenObjectInDB(\UserExternal::class, ['login' => $sLogin]); - $iKey = $this->GivenObjectInDB(\UserExternal::class, [ - 'login' => $sLogin, - 'language' => 'EN US', - ]); + $this->assertDBQueryCount( + 2, + fn() => $this->FindUserAndAssertItHasBeenFound($sLogin, $iKey), + 'Some queries should be performed the first time FindUser is called' + ); - $oUser = $this->InvokeNonPublicStaticMethod(UserRights::class, "FindUser", [$sLogin]); - - $this->assertNotNull($oUser); - $this->assertEquals($iKey, $oUser->GetKey()); - $this->assertEquals(\UserExternal::class, get_class($oUser)); - - $this->assertDBQueryCount(0, function() use ($sLogin, $iKey){ - $oUser = $this->InvokeNonPublicStaticMethod(UserRights::class, "FindUser", [$sLogin]); - static::assertEquals($iKey, $oUser->GetKey()); - static::assertEquals(\UserExternal::class, get_class($oUser)); - }); + $this->assertDBQueryCount( + 0, + fn() => $this->FindUserAndAssertItHasBeenFound($sLogin, $iKey), + 'The cache should prevent additional queries on subsequent calls' + ); } - public function testFindUser_UnknownLogin_AvoidSameSqlQueryTwice() + public function testFindUser_UnknownLogin() { - $sLogin = 'UserRightsFindUser'.uniqid(); - $oUser = $this->InvokeNonPublicStaticMethod(UserRights::class, "FindUser", [$sLogin]); - $this->assertNull($oUser); + $sLogin = 'NobodyLogin'; - $this->assertDBQueryCount(0, function() use ($sLogin){ - $oUser = $this->InvokeNonPublicStaticMethod(UserRights::class, "FindUser", [$sLogin]); - $this->assertNull($oUser); - }); + $this->assertDBQueryCount( + 2, + fn() => $this->FindUserAndAssertItWasNotFound($sLogin), + 'Some queries should be performed the first time FindUser is called' + ); + + $this->assertDBQueryCount( + 0, + fn() => $this->FindUserAndAssertItWasNotFound($sLogin), + 'The cache should prevent additional queries on subsequent calls' + ); + } + + public function FindUserAndAssertItHasBeenFound($sLogin, $iExpectedKey) + { + $oUser = $this->InvokeNonPublicStaticMethod(UserRights::class, "FindUser", [$sLogin]); + static::assertIsDBObject(\User::class, $iExpectedKey, $oUser, 'FindUser should return the User object corresponding to the login'); + } + public function FindUserAndAssertItWasNotFound($sLogin) + { + $oUser = $this->InvokeNonPublicStaticMethod(UserRights::class, "FindUser", [$sLogin]); + static::assertNull($oUser, 'FindUser should return null when the login is unknown'); } }