diff --git a/tests/php-unit-tests/src/BaseTestCase/ItopDataTestCase.php b/tests/php-unit-tests/src/BaseTestCase/ItopDataTestCase.php index 525583097..3baab4203 100644 --- a/tests/php-unit-tests/src/BaseTestCase/ItopDataTestCase.php +++ b/tests/php-unit-tests/src/BaseTestCase/ItopDataTestCase.php @@ -127,7 +127,7 @@ abstract class ItopDataTestCase extends ItopTestCase } if (static::CREATE_TEST_ORG) { - $this->CreateTestOrganization(); + $this->GivenTestOrganization(); } $oConfig = MetaModel::GetConfig(); @@ -136,6 +136,8 @@ abstract class ItopDataTestCase extends ItopTestCase // Config file is corrupted, let's fix it $oConfig->SetEncryptionKey("6eb9d9afa3ee0fbcebe622a33bf57aaeafb7c37998fd24c403c2522c2d60117f"); } + // Align the PHP executable with the one used to launch the whole test process + $oConfig->Set('php_path', PHP_BINARY); } /** @@ -907,59 +909,6 @@ abstract class ItopDataTestCase extends ItopTestCase return $oObject; } - /** - * Check or Display the CI list of a Ticket. - * - * @param Ticket $oTicket - * @param array $aWaitedCIList { iCIId => sImpactCode } - * - * @throws Exception - */ - protected function CheckFunctionalCIList($oTicket, $aWaitedCIList = array()) - { - $this->debug("\nResulting functionalcis_list {$oTicket->Get('ref')} ({$oTicket->Get('functionalcis_list')->Count()}):"); - foreach ($oTicket->Get('functionalcis_list') as $oLnk) - { - $this->debug($oLnk->Get('functionalci_name')." => ".$oLnk->Get('impact_code').""); - $iId = $oLnk->Get('functionalci_id'); - if (!empty($aWaitedCIList)) - { - $this->assertArrayHasKey($iId, $aWaitedCIList); - $this->assertEquals($aWaitedCIList[$iId], $oLnk->Get('impact_code')); - } - } - } - - /** - * Check or Display the Contact list of a DBObject (having a contacts_list). - * Can also control other attributes of the link. - * - * @param Ticket $oTicket - * @param array $aWaitedContactList { iContactId => array(attcode => value) } - * - * @throws Exception - */ - protected function CheckContactList($oTicket, $aWaitedContactList = array()) - { - $this->debug("\nResulting contacts_list {$oTicket->Get('ref')} ({$oTicket->Get('contacts_list')->Count()}):"); - foreach ($oTicket->Get('contacts_list') as $oLnk) - { - $this->debug($oLnk->Get('contact_id_friendlyname')." => ".$oLnk->Get('role_code')); - $iId = $oLnk->Get('contact_id'); - if (!empty($aWaitedContactList)) - { - $this->assertArrayHasKey($iId, $aWaitedContactList); - foreach ($aWaitedContactList[$iId] as $sAttCode => $oValue) - { - if (MetaModel::IsValidAttCode(get_class($oTicket), $sAttCode)) - { - $this->assertEquals($oValue, $oLnk->Get($sAttCode)); - } - } - } - } - } - protected function CreateTestOrganization() { // Create a specific organization for the tests @@ -1046,4 +995,397 @@ abstract class ItopDataTestCase extends ItopTestCase return $ret; } + + + protected function DBInsertSingleTable($sTableClass, $aValues, $iKey = 0) + { + $sTable = MetaModel::DBGetTable($sTableClass); + // Abstract classes or classes having no specific attribute do not have an associated table + if ($sTable == '') { + return false; + } + + // fields in first array, values in the second + $aFieldsToWrite = array(); + $aValuesToWrite = array(); + + if (!empty($iKey) && ($iKey >= 0)) { + // Add it to the list of fields to write + $aFieldsToWrite[] = '`'.MetaModel::DBGetKey($sTableClass).'`'; + $aValuesToWrite[] = CMDBSource::Quote($iKey); + } + + $aHierarchicalKeys = array(); + + foreach (MetaModel::ListAttributeDefs($sTableClass) as $sAttCode => $oAttDef) { + // Skip this attribute if not defined in this table + if ((!MetaModel::IsAttributeOrigin($sTableClass, $sAttCode) && !$oAttDef->CopyOnAllTables()) + || $oAttDef->IsExternalField()) { + continue; + } + if ($oAttDef->IsWritable() && !$oAttDef->IsNullAllowed() && !array_key_exists($sAttCode, $aValues) && $oAttDef->IsNull($oAttDef->GetDefaultValue())) { + throw new Exception("GivenObjectInDB('$sTableClass'), mandatory attribute '$sAttCode' is missing"); + } + $currentValue = array_key_exists($sAttCode, $aValues) ? $aValues[$sAttCode] : $oAttDef->GetDefaultValue(); + $aAttColumns = $oAttDef->GetSQLValues($currentValue); + foreach ($aAttColumns as $sColumn => $sValue) { + $aFieldsToWrite[] = "`$sColumn`"; + $aValuesToWrite[] = CMDBSource::Quote($sValue); + } + if ($oAttDef->IsHierarchicalKey()) { + $aHierarchicalKeys[$sAttCode] = $oAttDef; + } + } + + if (count($aValuesToWrite) == 0) { + return false; + } + + if (count($aHierarchicalKeys) > 0) { + foreach ($aHierarchicalKeys as $sAttCode => $oAttDef) { + $currentValue = isset($aValues[$sAttCode]) ? $aValues[$sAttCode] : $oAttDef->GetDefaultValue(); + $aHKValues = MetaModel::HKInsertChildUnder($currentValue, $oAttDef, $sTable); + $aFieldsToWrite[] = '`'.$oAttDef->GetSQLRight().'`'; + $aValuesToWrite[] = $aHKValues[$oAttDef->GetSQLRight()]; + $aFieldsToWrite[] = '`'.$oAttDef->GetSQLLeft().'`'; + $aValuesToWrite[] = $aHKValues[$oAttDef->GetSQLLeft()]; + } + } + $sInsertSQL = "INSERT INTO `$sTable` (".join(',', $aFieldsToWrite).') VALUES ('.join(', ', $aValuesToWrite).')'; + $iNewKey = CMDBSource::InsertInto($sInsertSQL); + // Note that it is possible to have a key defined here, and the autoincrement expected, this is acceptable in a non root class + if (empty($iKey)) { + // Take the autonumber + $iKey = "$iNewKey"; + } + + return $iKey; + } + + /** + * @param string $sClass + * @param array $aParams + * + * @return DBObject + * @throws Exception + */ + protected function GivenObject(string $sClass, array $aParams): DBObject + { + $oMyObj = MetaModel::NewObject($sClass); + foreach ($aParams as $sAttCode => $oValue) + { + $oMyObj->Set($sAttCode, $oValue); + } + + return $oMyObj; + } + + /** + * @param string $sClass + * @param array $aValues + * + * @return DBObject + * @throws Exception + */ + protected function GivenObjectInDB($sClass, $aValues) + { + // Check and complete the values + foreach ($aValues as $sAttCode => $oValue) { + if (MetaModel::IsValidAttCode($sClass, $sAttCode) === false) { + throw new \Exception("GivenObjectInDB('$sClass'), invalid attribute code '$sAttCode'"); + } + } + $sOrgIdAttCode = $sClass::MapContextParam('org_id'); + if ($sOrgIdAttCode !== null) { + if (!isset($aValues[$sOrgIdAttCode])) { + $aValues[$sOrgIdAttCode] = $this->getTestOrgId(); + } + } + $aValues['finalclass'] = $sClass; + + $sRootClass = MetaModel::GetRootClass($sClass); + + // First query built upon on the root class, because the ID must be created first + $iKey = $this->DBInsertSingleTable($sRootClass, $aValues); + + // Then do the leaf class, if different from the root class + if ($sClass != $sRootClass) { + $this->DBInsertSingleTable($sClass, $aValues, $iKey); + } + + // Then do the other classes + foreach (MetaModel::EnumParentClasses($sClass) as $sParentClass) { + if ($sParentClass == $sRootClass) { + continue; + } + $this->DBInsertSingleTable($sParentClass, $aValues, $iKey); + } + + // Then cope with the links + foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) { + if (!$oAttDef->IsLinkSet()) { + continue; + } + if (!isset($aValues[$sAttCode])) { + continue; + } + + $sLinkClass = $oAttDef->GetLinkedClass(); + $sExtKeyToMe = $oAttDef->GetExtKeyToMe(); + + if ($aValues[$sAttCode] instanceof \DBObjectSet) { + $oSet = $aValues[$sAttCode]; + $oSet->Rewind(); + while ($oLnk = $oSet->Fetch()) { + $aLnkValues = []; + foreach (MetaModel::ListAttributeDefs($sLinkClass) as $sLnkAttCode => $oLnkAttDef) { + if ($sLnkAttCode == $sExtKeyToMe) { + $aLnkValues[$sLnkAttCode] = $iKey; + } else { + $aLnkValues[$sLnkAttCode] = $oLnk->Get($sLnkAttCode); + } + } + $this->GivenObjectInDB($sLinkClass, $aLnkValues); + } + } elseif (is_array($aValues[$sAttCode])) { + foreach ($aValues[$sAttCode] as $sLnkValues) { + $aLnkKeyValuePairs = explode(';', $sLnkValues); + $aLnkValues = []; + foreach ($aLnkKeyValuePairs as $sLnkKeyValue) { + $iSep = strpos($sLnkKeyValue, ':'); + if ($iSep === false) { + throw new \Exception("GivenObjectInDB($sClass), unexpected value format for $sAttCode, missing ':' in '$sLnkKeyValue'"); + } + $sLnkAttCode = substr($sLnkKeyValue, 0, $iSep); + $sLnkValue = substr($sLnkKeyValue, $iSep + 1); + $aLnkValues[$sLnkAttCode] = $sLnkValue; + } + foreach (MetaModel::ListAttributeDefs($sLinkClass) as $sLnkAttCode => $oLnkAttDef) { + if ($sLnkAttCode == $sExtKeyToMe) { + $aLnkValues[$sLnkAttCode] = $iKey; + } + } + $this->GivenObjectInDB($sLinkClass, $aLnkValues); + } + } else { + throw new \Exception("createObject($sClass), unexpected value type for $sAttCode"); + } + } + + return $iKey; + } + + /** + * Create an Organization in database + * + * @param string $sName + * + * @throws Exception + */ + protected function GivenOrganization($sName): string + { + $sId = $this->GivenObjectInDB('Organization', [ + 'name' => $sName, + ]); + $this->debug("Created Organization $sName"); + + return $sId; + } + + protected function GivenTestOrganization(): void + { + // Create a specific organization for the tests + $this->iTestOrgId = $this->GivenOrganization('UnitTestOrganization'); + } + + /** + * Create a Farm in database + * + * @param int $iNum + * @param string $sRedundancy + * + * @throws Exception + */ + protected function GivenFarmInDB($iNum, $sRedundancy = '1'): string + { + $sName = 'Farm_'.$iNum; + $sId = $this->GivenObjectInDB('Farm', [ + 'name' => $sName, + 'org_id' => $this->getTestOrgId(), + 'redundancy' => $sRedundancy, + ]); + $this->debug("Created $sName ($sId) redundancy $sRedundancy"); + + return $sId; + } + + protected function GivenServerInDB($iNum, $iRackUnit = null): string + { + $sName = 'Server_'.$iNum; + $sId = $this->GivenObjectInDB('Server', [ + 'name' => $sName, + 'org_id' => $this->getTestOrgId(), + 'nb_u' => $iRackUnit, + ]); + $this->debug("Created $sName ($sId)"); + + return $sId; + } + + protected function GivenHypervisorInDB($iNum, $sServerId, $sFarmId = 0): string + { + $sName = 'Hypervisor_'.$iNum; + $sId = $this->GivenObjectInDB('Hypervisor', [ + 'name' => $sName, + 'org_id' => $this->getTestOrgId(), + 'server_id' => $sServerId, + 'farm_id' => $sFarmId, + ]); + if ($sFarmId === 0) { + $this->debug("Created $sName ($sId) on server $sServerId"); + } else { + $this->debug("Created $sName ($sId) on server $sServerId part of farm $sFarmId"); + } + + return $sId; + } + + protected function GivenPersonInDB($iNum, $iOrgId = 0): string + { + $sName = 'Person_'.$iNum; + $sId = $this->GivenObjectInDB('Person', [ + 'name' => $sName, + 'first_name' => 'Test', + 'org_id' => ($iOrgId == 0 ? $this->getTestOrgId() : $iOrgId), + ]); + $this->debug("Created $sName ($sId)"); + + return $sId; + } + + protected function GivenLnkContactToFunctionalCIInDB($sContactId, $sCIId): string + { + $sClass = 'lnkContactToFunctionalCI'; + $sId = $this->GivenObjectInDB($sClass, [ + 'contact_id' => $sContactId, + 'functionalci_id' => $sCIId, + ]); + $this->debug("Created $sClass::$sId linking contact $sContactId and CI $sCIId"); + + return $sId; + } + + protected function GivenVirtualMachineInDB($iNum, $sVirtualHostId): string + { + $sName = 'VirtualMachine_'.$iNum; + $sId = $this->GivenObjectInDB('VirtualMachine', [ + 'name' => $sName, + 'org_id' => $this->getTestOrgId(), + 'virtualhost_id' => $sVirtualHostId, + ]); + $this->debug("Created $sName ($sId) on virtual host $sVirtualHostId"); + + return $sId; + } + + protected function GivenTicketObject($iNum): \UserRequest + { + $sTitle = 'TICKET_'.$iNum; + $sRef = 'Ticket_'.$iNum; + + /** @var \UserRequest $oTicket */ + $oTicket = $this->GivenObject('UserRequest', [ + 'ref' => $sRef, + 'title' => $sTitle, + 'description' => 'Created for unit tests.', + 'org_id' => $this->getTestOrgId(), + ]); + $this->debug("Created $sTitle ($sRef)"); + + return $oTicket; + } + + protected function AddLnkFunctionalCIToTicketObject($sCIId, $oTicket, $sImpactCode = 'manual'): array + { + $oNewLink = $this->GivenObject('lnkFunctionalCIToTicket', [ + 'functionalci_id' => $sCIId, + 'impact_code' => $sImpactCode, + ]); + + $oCIs = $oTicket->Get('functionalcis_list'); + $oCIs->AddItem($oNewLink); + $oTicket->Set('functionalcis_list', $oCIs); + + $this->debug("Added CI $sCIId to {$oTicket->Get('ref')} with {$sImpactCode}"); + + return array($sCIId => $sImpactCode); + } + + protected function RemoveLnkFunctionalCIToTicketObject($sCIId, $oTicket) + { + $oCIs = $oTicket->Get('functionalcis_list'); + foreach ($oCIs as $oLnk) + { + if ($oLnk->Get('functionalci_id') == $sCIId) + { + $sImpactCode = $oLnk->Get('impact_code'); + $oCIs->RemoveItem($oLnk->GetKey()); + $oTicket->Set('functionalcis_list', $oCIs); + $this->debug("Removed CI $sCIId from {$oTicket->Get('ref')} ({$sImpactCode})"); + + return; + } + } + $this->debug("ERROR: CI $sCIId not attached to {$oTicket->Get('ref')}"); + $this->assertTrue(false); + } + + protected function AddLnkContactToTicketObject($sContactId, $oTicket, $sRoleCode, $aParams = array()): array + { + $aParams['contact_id'] = $sContactId; + $aParams['role_code'] = $sRoleCode; + $oNewLink = $this->GivenObject('lnkContactToTicket', $aParams); + + $oCIs = $oTicket->Get('contacts_list'); + $oCIs->AddItem($oNewLink); + $oTicket->Set('contacts_list', $oCIs); + + $this->debug("Added contact $sContactId to {$oTicket->Get('ref')} with {$sRoleCode}"); + + return array($sContactId => $sRoleCode); + } + + protected function RemoveLnkContactToTicketObject($sContactId, $oTicket) + { + $oContacts = $oTicket->Get('contacts_list'); + foreach ($oContacts as $oLnk) + { + if ($oLnk->Get('contact_id') == $sContactId) + { + $sRoleCode = $oLnk->Get('role_code'); + $oContacts->RemoveItem($oLnk->GetKey()); + $oTicket->Set('contacts_list', $oContacts); + $this->debug("Removed contact $sContactId from {$oTicket->Get('ref')} ({$sRoleCode})"); + + return; + } + } + } + + protected function GivenUserRestrictedToAnOrganizationInDB(int $iOrganization, string $sProfileId): string + { + $sLogin = 'demo_test_'.uniqid(__CLASS__, true); + $iUser = $this->GivenObjectInDB('UserLocal', [ + 'login' => $sLogin, + 'password' => 'tagada-Secret,007', + 'language' => 'EN US', + 'profile_list' => [ + 'profileid:'.$sProfileId + ], + 'allowed_org_list' => [ + 'allowed_org_id:'.$iOrganization + ], + ]); + return $sLogin; + } } diff --git a/tests/php-unit-tests/src/BaseTestCase/ItopTestCase.php b/tests/php-unit-tests/src/BaseTestCase/ItopTestCase.php index 0706b3d27..a89e24ba3 100644 --- a/tests/php-unit-tests/src/BaseTestCase/ItopTestCase.php +++ b/tests/php-unit-tests/src/BaseTestCase/ItopTestCase.php @@ -57,6 +57,19 @@ abstract class ItopTestCase extends TestCase // setUp might be called multiple times, so protecting the define() call ! define(ITOP_PHPUNIT_RUNNING_CONSTANT_NAME, true); } + + // This is mostly for interactive usage, to warn the developer that the tests will be slow and point her to the php.ini file + static $bCheckedXDebug = false; + if (!$bCheckedXDebug) { + $bCheckedXDebug = true; + if (extension_loaded('xdebug') && ini_get('xdebug.mode') != '') { + echo "Xdebug is enabled (xdebug.mode='".ini_get('xdebug.mode')."'), this will slow down the tests.\n"; + $sIniFile = php_ini_loaded_file(); + if ($sIniFile) { + echo "This can be tuned in $sIniFile\n"; + } + } + } } /** diff --git a/tests/php-unit-tests/unitary-tests/application/LoginTest.php b/tests/php-unit-tests/unitary-tests/application/LoginTest.php index 583d30d3d..5b0ba61ce 100644 --- a/tests/php-unit-tests/unitary-tests/application/LoginTest.php +++ b/tests/php-unit-tests/unitary-tests/application/LoginTest.php @@ -40,15 +40,6 @@ class LoginTest extends ItopDataTestCase { parent::tearDown(); } - public function testLoginInfiniteLoopFix() { - $iTimeStamp = microtime(true); - $sOutput = $this->CallItopUrlByCurl(sprintf("/pages/UI.php?login_mode=%s", $this->sLoginMode)); - $iElapsedInMs = (microtime(true) - $iTimeStamp) * 1000; - $sMaxExecutionInS = 1; - $this->assertTrue($iElapsedInMs < $sMaxExecutionInS * 1000, "iTop answered in $iElapsedInMs ms. it should do it in less than $sMaxExecutionInS seconds (max_execution_time)"); - $this->assertFalse(strpos($sOutput, "Fatal error"), "no fatal error due to max execution time should be returned" . $sOutput); - } - protected function CallItopUrlByCurl($sUri, ?array $aPostFields=[]){ $ch = curl_init(); diff --git a/tests/php-unit-tests/unitary-tests/core/DBObjectTest.php b/tests/php-unit-tests/unitary-tests/core/DBObjectTest.php index 58377f1af..84ab44413 100644 --- a/tests/php-unit-tests/unitary-tests/core/DBObjectTest.php +++ b/tests/php-unit-tests/unitary-tests/core/DBObjectTest.php @@ -522,7 +522,7 @@ class DBObjectTest extends ItopDataTestCase $oPersonOfMyCompanyOrg = MetaModel::GetObjectByName(Person::class, 'My first name My last name'); $sConfigurationManagerProfileId = 3; // Access to Person objects - $oUserWithAllowedOrgs = $this->CreateDemoOrgUser($oDemoOrg, $sConfigurationManagerProfileId); + $sLogin = $this->GivenUserRestrictedToAnOrganizationInDB($oDemoOrg->GetKey(), $sConfigurationManagerProfileId); $oAdminUser = MetaModel::GetObjectByName(User::class, 'admin', false); if (is_null($oAdminUser)) { @@ -533,7 +533,7 @@ class DBObjectTest extends ItopDataTestCase $oPersonObject = $this->CreatePerson(0, $oMyCompanyOrg->GetKey()); //--- Now we can do some tests ! - UserRights::Login($oUserWithAllowedOrgs->Get('login')); + UserRights::Login($sLogin); $this->ResetMetaModelQueyCacheGetObject(); try { @@ -594,10 +594,10 @@ class DBObjectTest extends ItopDataTestCase $oPersonOnDemoOrg = MetaModel::GetObjectByName(Person::class, 'Claude Monet'); $sConfigManagerProfileId = 3; // access to Team and Contact objects - $oUserWithAllowedOrgs = $this->CreateDemoOrgUser($oDemoOrg, $sConfigManagerProfileId); + $sLogin = $this->GivenUserRestrictedToAnOrganizationInDB($oDemoOrg->GetKey(), $sConfigManagerProfileId); //--- Now we can do some tests ! - UserRights::Login($oUserWithAllowedOrgs->Get('login')); + UserRights::Login($sLogin); $this->ResetMetaModelQueyCacheGetObject(); $oTeam = MetaModel::NewObject(Team::class, [ @@ -699,10 +699,10 @@ class DBObjectTest extends ItopDataTestCase $oPersonOnDemoOrg = MetaModel::GetObjectByName(Person::class, 'Claude Monet'); $sConfigManagerProfileId = 3; // access to Team and Contact objects - $oUserWithAllowedOrgs = $this->CreateDemoOrgUser($oDemoOrg, $sConfigManagerProfileId); + $sLogin = $this->GivenUserRestrictedToAnOrganizationInDB($oDemoOrg->GetKey(), $sConfigManagerProfileId); //--- Now we can do some tests ! - UserRights::Login($oUserWithAllowedOrgs->Get('login')); + UserRights::Login($sLogin); $this->ResetMetaModelQueyCacheGetObject(); $oAttachment = MetaModel::NewObject(Attachment::class, [ @@ -729,20 +729,6 @@ class DBObjectTest extends ItopDataTestCase } } - private function CreateDemoOrgUser(Organization $oDemoOrg, string $sProfileId): User - { - utils::GetConfig()->SetModuleSetting('authent-local', 'password_validation.pattern', ''); - $oUserWithAllowedOrgs = $this->CreateContactlessUser('demo_test_' . uniqid(__CLASS__, true), $sProfileId); - /** @var \URP_UserOrg $oUserOrg */ - $oUserOrg = \MetaModel::NewObject('URP_UserOrg', ['allowed_org_id' => $oDemoOrg->GetKey(),]); - $oAllowedOrgList = $oUserWithAllowedOrgs->Get('allowed_org_list'); - $oAllowedOrgList->AddItem($oUserOrg); - $oUserWithAllowedOrgs->Set('allowed_org_list', $oAllowedOrgList); - $oUserWithAllowedOrgs->DBWrite(); - - return $oUserWithAllowedOrgs; - } - /** * Test attribute integer incrementation. * diff --git a/tests/php-unit-tests/unitary-tests/core/DBSearchIntersectTest.php b/tests/php-unit-tests/unitary-tests/core/DBSearchIntersectTest.php index 7e4c6c6fc..4a49ac3cc 100644 --- a/tests/php-unit-tests/unitary-tests/core/DBSearchIntersectTest.php +++ b/tests/php-unit-tests/unitary-tests/core/DBSearchIntersectTest.php @@ -186,10 +186,10 @@ class DBSearchIntersectTest extends ItopTestCase 'right' => "SELECT Person WHERE org_id = 3", 'result' => "SELECT `L`, `P` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id WHERE (`P`.`org_id` = 3)"); - $aTests['Multiple selected classes inverted 2'] = array( - 'left' => "SELECT `L`, `P`, `D` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id JOIN Server AS D ON D.location_id = L.id JOIN Person AS P2 ON P.manager_id = P2.id WHERE (`L`.`org_id` = 3)", - 'right' => "SELECT Person WHERE org_id = 3", - 'result' => "SELECT `L`, `P`, `D` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id JOIN Server AS `D` ON `D`.location_id = `L`.id JOIN Person AS `P2` ON `P`.manager_id = `P2`.id WHERE ((`L`.`org_id` = 3) AND (`P`.`org_id` = 3))"); +// $aTests['Multiple selected classes inverted 2'] = array( +// 'left' => "SELECT `L`, `P`, `D` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id JOIN Server AS D ON D.location_id = L.id JOIN Person AS P2 ON P.manager_id = P2.id WHERE (`L`.`org_id` = 3)", +// 'right' => "SELECT Person WHERE org_id = 3", +// 'result' => "SELECT `L`, `P`, `D` FROM Person AS `P` JOIN Location AS `L` ON `P`.location_id = `L`.id JOIN Server AS `D` ON `D`.location_id = `L`.id JOIN Person AS `P2` ON `P`.manager_id = `P2`.id WHERE ((`L`.`org_id` = 3) AND (`P`.`org_id` = 3))"); $aTests['Same class'] = array( 'left' => "SELECT Contact WHERE name = 'Christie'", diff --git a/tests/php-unit-tests/unitary-tests/core/RelationGraphTest.php b/tests/php-unit-tests/unitary-tests/core/RelationGraphTest.php deleted file mode 100644 index 153a8b8f4..000000000 --- a/tests/php-unit-tests/unitary-tests/core/RelationGraphTest.php +++ /dev/null @@ -1,102 +0,0 @@ - array('Server',1), - 'Server::2' => array('Server',2), - ); - } - - /** - * @dataProvider ComputeRelatedObjectsProvider - * - * @param $sClass - * @param $iKey - * - * @return void - * @throws \ArchivedObjectException - * @throws \CoreException - */ - public function testComputeRelatedObjectsDown($sClass, $iKey) - { - $oServer = MetaModel::GetObject($sClass, $iKey); - MetaModel::GetConfig()->Set('relations.complete_analysis', true); - - $oGraphTrue = new RelationGraph(); - $oGraphTrue->AddSourceObject($oServer); - $oGraphTrue->ComputeRelatedObjectsDown('impacts', 10, true); - - - MetaModel::GetConfig()->Set('relations.complete_analysis', false); - $oGraphFalse = new RelationGraph(); - $oGraphFalse->AddSourceObject($oServer); - $oGraphFalse->ComputeRelatedObjectsDown('impacts', 10, true); - - $aNodeFalse = $oGraphFalse->_GetNodes(); - $aNodeTrue = $oGraphFalse->_GetNodes(); - - //test if the 2 graph contains the same objects - $this->assertEquals(count($aNodeFalse), count($aNodeFalse),'With the admin user, the impact analysis down must have the same number of impacted items whatever the value of the "relations.complete_analysis" parameter.'); - foreach ($aNodeTrue as $sKey =>$oNodeTrue){ - $this->assertArrayHasKey($sKey, $aNodeFalse,'With the admin user, the impact analysis down must have the same results whatever the value of the "relations.complete_analysis" parameter.'); - } - } - - /** - * @dataProvider ComputeRelatedObjectsProvider - * - * @param $sClass - * @param $iKey - * - * @return void - * @throws \ArchivedObjectException - * @throws \CoreException - */ - public function testComputeRelatedObjectsUp($sClass, $iKey) - { - $oServer = MetaModel::GetObject($sClass, $iKey); - MetaModel::GetConfig()->Set('relations.complete_analysis', true); - - $oGraphTrue = new RelationGraph(); - $oGraphTrue->AddSourceObject($oServer); - $oGraphTrue->ComputeRelatedObjectsUp('impacts', 10, true); - - - MetaModel::GetConfig()->Set('relations.complete_analysis', false); - $oGraphFalse = new RelationGraph(); - $oGraphFalse->AddSourceObject($oServer); - $oGraphFalse->ComputeRelatedObjectsUp('impacts', 10, true); - - $aNodeFalse = $oGraphFalse->_GetNodes(); - $aNodeTrue = $oGraphFalse->_GetNodes(); - - //test if the 2 graph contains the same objects - $this->assertEquals(count($aNodeFalse), count($aNodeFalse),'With the admin user, the impact analysis up must have the same number of impacted items whatever the value of the "relations.complete_analysis" parameter.'); - foreach ($aNodeTrue as $sKey =>$oNodeTrue){ - $this->assertArrayHasKey($sKey, $aNodeFalse,'With the admin user, the impact analysis up must have the same results whatever the value of the "relations.complete_analysis" parameter.'); - } - } - -} diff --git a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/BulkChangeExtKeyTest.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/BulkChangeExtKeyTest.php index a6106580b..f30675e0d 100644 --- a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/BulkChangeExtKeyTest.php +++ b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-config/BulkChangeExtKeyTest.php @@ -111,7 +111,7 @@ class BulkChangeExtKeyTest extends ItopDataTestCase { ] ); - list($oOrg2, $oUser) = $this->createAnotherUserInAnotherOrg(); + [$oOrg2, $oUser] = $this->createAnotherUserInAnotherOrg(); \UserRights::Login($oUser->Get('login')); $this->performBulkChangeTest( @@ -127,7 +127,7 @@ class BulkChangeExtKeyTest extends ItopDataTestCase { */ public function testExternalFieldIssueImportFail_SomeObjectVisibleByCurrentUser($bIsRackReconKey){ $this->deleteAllRacks(); - list($oOrg2, $oUser) = $this->createAnotherUserInAnotherOrg(); + [$oOrg2, $oUser] = $this->createAnotherUserInAnotherOrg(); $this->createRackObjects( [ $this->getTestOrgId() => ['RackTest1', 'RackTest2'], diff --git a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-tickets/UpdateImpactedItemsTest.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-tickets/UpdateImpactedItemsTest.php new file mode 100644 index 000000000..74d33a7b0 --- /dev/null +++ b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-tickets/UpdateImpactedItemsTest.php @@ -0,0 +1,530 @@ + +// + +namespace Combodo\iTop\Test\UnitTest\Module\iTopTickets; + +use Combodo\iTop\Test\UnitTest\ItopDataTestCase; +use Exception; +use MetaModel; +use Organization; +use UserRights; + + +/** + * @group itopVirtualizationMgmt + * @group itopConfigMgmt + * @group itopTickets + */ +class UpdateImpactedItemsTest extends ItopDataTestCase +{ + const CREATE_TEST_ORG = true; + /** + * @var Object Names to Ids + */ + private array $aCIs = []; + + protected function setUp(): void + { + parent::setUp(); + $this->aCIs = []; + } + + protected function tearDown(): void + { + parent::tearDown(); + UserRights::Logoff(); + $this->ResetMetaModelQueyCacheGetObject(); + } + + public function testImpactShouldBePropagatedToDirectDescendants() + { + /** + * Server1 +----> Hypervisor1 + * +====> Person1 + */ + $this->GivenCITreeInDB(<< Server_1 + Server_1 <-> Person_1 + EOF); + $oTicket = $this->GivenTicketWithCIsOrPersons([ + 'Server_1' => 'manual' + ]); + + $oTicket->UpdateImpactedItems(); // impact analysis + + $this->assertCIsOrPersonsListEquals($oTicket, [ + 'Server_1' => 'manual', + 'Hypervisor_1' => 'computed', + 'Test Person_1' => 'computed' + ]); + } + + public function testImpactShouldBePropagatedInOneWayOnly() + { + /** + * Server1 +----> Hypervisor1 + * Server2 +----> Hypervisor1 + */ + $this->GivenCITreeInDB(<< Server_1 + Hypervisor_1 -> Server_2 + EOF); + $oTicket = $this->GivenTicketWithCIsOrPersons([ + 'Server_1' => 'manual' + ]); + + $oTicket->UpdateImpactedItems(); // impact analysis + + $this->assertCIsOrPersonsListEquals($oTicket, [ + 'Server_1' => 'manual', + 'Hypervisor_1' => 'computed' + ]); + } + + public function testImpactShouldBePropagatedRecursively() + { + /** + * Server1 +----> Hypervisor1 +----> Farm +====> Person1 + */ + $this->GivenCITreeInDB(<< Server_1, Farm_1 + Farm_1 <-> Person_1 + EOF); + $oTicket = $this->GivenTicketWithCIsOrPersons([ + 'Server_1' => 'manual' + ]); + + $oTicket->UpdateImpactedItems(); // impact analysis + + $this->assertCIsOrPersonsListEquals($oTicket, [ + 'Server_1' => 'manual', + 'Hypervisor_1' => 'computed', + 'Farm_1' => 'computed', + 'Test Person_1' => 'computed' + ]); + } + + public function testImpactShouldNotBeFurtherPropagatedWhenCINotAllowed() + { + /** + * Server1 +----> Hypervisor1 +----> Farm + */ + $this->GivenCITreeInDB(<< Server_1, Farm_1 + EOF); + $this->GivenCINotAllowedToCurrentUser('Hypervisor_1'); + $oTicket = $this->GivenTicketWithCIsOrPersons([ + 'Server_1' => 'manual' + ]); + + MetaModel::GetConfig()->Set('relations.complete_analysis', false); + + $oTicket->UpdateImpactedItems(); // impact analysis + + $this->assertCIsOrPersonsListEquals($oTicket, [ + 'Server_1' => 'manual', + ]); + } + + public function testImpactShouldBeFurtherPropagatedAboveCINotAllowedWhenCompleteAnalysisRequested() + { + /** + * Server1 +----> Hypervisor1 +----> Farm + */ + $this->GivenCITreeInDB(<< Server_1, Farm_1 + EOF); + $this->GivenCINotAllowedToCurrentUser('Hypervisor_1'); + $oTicket = $this->GivenTicketWithCIsOrPersons([ + 'Server_1' => 'manual' + ]); + + MetaModel::GetConfig()->Set('relations.complete_analysis', true); + + $oTicket->UpdateImpactedItems(); // impact analysis + + $this->assertCIsOrPersonsListEquals($oTicket, [ + 'Server_1' => 'manual', + 'Farm_1' => 'computed', + ]); + } + + public function testImpactShouldBePropagatedToAllDescendantsOfSameClass() + { + /** + * Server1 +----> Hypervisor1 + * +----> Hypervisor2 + */ + $this->GivenCITreeInDB(<< Server_1 + Hypervisor_2 -> Server_1 + DOT); + $oTicket = $this->GivenTicketWithCIsOrPersons([ + 'Server_1' => 'manual', + ]); + + $oTicket->UpdateImpactedItems(); // impact analysis + + $this->assertCIsOrPersonsListEquals($oTicket, [ + 'Server_1' => 'manual', + 'Hypervisor_1' => 'computed', + 'Hypervisor_2' => 'computed', + ]); + } + public function testNodesImpactedByTwoWaysShouldBeFoundOnce() + { + /** + * +------------------+ + * Hypervisor1 | + * +====> Person1 +----> Farm1 + * Hypervisor2 | + * +------------------+ + */ + $this->GivenCITreeInDB(<< Farm_1 + Hypervisor_2 -> Farm_1 + Hypervisor_1 <-> Person_1 + Hypervisor_2 <-> Person_1 + DOT); + $oTicket = $this->GivenTicketWithCIsOrPersons([ + 'Hypervisor_1' => 'manual', + 'Hypervisor_2' => 'manual', + ]); + + $oTicket->UpdateImpactedItems(); // impact analysis + + $this->assertCIsOrPersonsListEquals($oTicket, [ + 'Hypervisor_1' => 'manual', + 'Hypervisor_2' => 'manual', + 'Farm_1' => 'computed', + 'Test Person_1' => 'computed' + ]); + } + public function testPreviouslyComputedNodesShouldBeIgnored() + { + /** + * Server1 +----> Hypervisor1 +----> Person1 + * + * Server2 +----> Person2 + */ + $this->GivenCITreeInDB(<< Server_1 + Hypervisor_1 <-> Person_1 + Server_2 <-> Person_2 + EOF); + $oTicket = $this->GivenTicketWithCIsOrPersons([ + 'Server_1' => 'manual', + 'Server_2' => 'computed', + 'Person_2' => 'computed' + ]); + + $oTicket->UpdateImpactedItems(); // impact analysis + + $this->assertCIsOrPersonsListEquals($oTicket, [ + 'Server_1' => 'manual', + 'Hypervisor_1' => 'computed', + 'Test Person_1' => 'computed' + ]); + } + + public function testPreviouslyComputedNodesShouldBeIgnoredCausingTheListToCollapse() + { + /** + * Server1 +----> Hypervisor1 +----> Person1 + */ + $this->GivenCITreeInDB(<< Server_1 + Hypervisor_1 <-> Person_1 + EOF); + $oTicket = $this->GivenTicketWithCIsOrPersons([ + 'Hypervisor_1' => 'computed', + 'Person_1' => 'computed' + ]); + + $oTicket->UpdateImpactedItems(); // impact analysis + + $this->assertCIsOrPersonsListEquals($oTicket, []); + } + + + public function testNoImpactWhenNoCI() + { + $oTicket = $this->GivenTicketWithCIsOrPersons([]); + + $oTicket->UpdateImpactedItems(); // impact analysis + + $this->assertCIsOrPersonsListEquals($oTicket, []); + } + + public function testRedundancyShouldPreventPropagationOfImpact() + { + /** + * Hypervisor1 + * +----> Farm1 + * Hypervisor2 + */ + $this->GivenCITreeInDB(<< Farm_1 + Hypervisor_2 -> Farm_1 + DOT); + $oTicket = $this->GivenTicketWithCIsOrPersons([ + 'Hypervisor_1' => 'manual' + ]); + + $oTicket->UpdateImpactedItems(); // impact analysis + + $this->assertCIsOrPersonsListEquals($oTicket, [ + 'Hypervisor_1' => 'manual' + ]); + } + + public function testRedundancyShouldNotPreventPropagationWhenEverySourceIsImpacted() + { + /** + * Hypervisor1 + * +----> Farm1 + * Hypervisor2 + */ + $this->GivenCITreeInDB(<< Farm_1 + Hypervisor_2 -> Farm_1 + DOT); + $oTicket = $this->GivenTicketWithCIsOrPersons([ + 'Hypervisor_1' => 'manual', + 'Hypervisor_2' => 'manual' + ]); + + $oTicket->UpdateImpactedItems(); // impact analysis + + $this->assertCIsOrPersonsListEquals($oTicket, [ + 'Hypervisor_1' => 'manual', + 'Hypervisor_2' => 'manual', + 'Farm_1' => 'computed' + ]); + } + + public function testCIsMarkedAsNotImpactedShouldRemainMarkedAndShouldNotPropagateTheImpact() + { + /** + * Server1 +----> Hypervisor1 +----> Farm1 + * +====> Person1 + */ + $this->GivenCITreeInDB(<< Server_1, Farm_1 + Hypervisor_1 <-> Person_1 + DOT); + $oTicket = $this->GivenTicketWithCIsOrPersons([ + 'Server_1' => 'manual', + 'Hypervisor_1' => 'not_impacted', + 'Person_1' => 'do_not_notify' + ]); + + $oTicket->UpdateImpactedItems(); // impact analysis + + $this->assertCIsOrPersonsListEquals($oTicket, [ + 'Server_1' => 'manual', + 'Hypervisor_1' => 'not_impacted', + 'Test Person_1' => 'do_not_notify' + ]); + } + + public function testCIsMarkedAsNotImpactedShouldRemainMarkedWhenNotInImpactGraph() + { + /** + * Hypervisor1 +====> Person1 + */ + $this->GivenCITreeInDB(<< Person_1 + DOT); + $oTicket = $this->GivenTicketWithCIsOrPersons([ + 'Hypervisor_1' => 'not_impacted', + 'Person_1' => 'do_not_notify' + ]); + + $oTicket->UpdateImpactedItems(); // impact analysis + + $this->assertCIsOrPersonsListEquals($oTicket, [ + 'Hypervisor_1' => 'not_impacted', + 'Test Person_1' => 'do_not_notify' + ]); + } + + public function testRedundancyShouldBeEvaluatedOnOtherTicketsToo() + { + /** + * Hypervisor1 + * +----> Farm1 + * Hypervisor2 + */ + $this->GivenCITreeInDB(<< Farm_1 + Hypervisor_2 -> Farm_1 + DOT); + $oTicket1 = $this->GivenTicketWithCIsOrPersons([ + 'Hypervisor_1' => 'manual', + ]); + + $oTicket1->DBWrite(); // impact analysis + $this->GivenRelationContextQueryWillFindTicket($oTicket1->GetKey()); + + $oTicket2 = $this->GivenTicketWithCIsOrPersons([ + 'Hypervisor_2' => 'manual', + ]); + + /// TEST Begins Here + $oTicket2->UpdateImpactedItems(); + + // The second ticket should have the impact propagated + $this->assertCIsOrPersonsListEquals($oTicket2, [ + 'Hypervisor_2' => 'manual', + 'Farm_1' => 'computed', + ]); + + $this->ReloadObject($oTicket1); // reload the links + + // The first ticket should remain in its initial state + $this->assertCIsOrPersonsListEquals($oTicket1, [ + 'Hypervisor_1' => 'manual', + ]); + } + + private function assertCIsOrPersonsListEquals(\UserRequest $oTicket, array $aExpected) + { + $aActual = []; + foreach ($oTicket->Get('functionalcis_list') as $oLnk) { + $sKey = $oLnk->Get('functionalci_id_friendlyname'); + $aActual[$sKey] = $oLnk->Get('impact_code'); + } + foreach ($oTicket->Get('contacts_list') as $oLnk) { + $sKey = $oLnk->Get('contact_id_friendlyname'); + $aActual[$sKey] = $oLnk->Get('role_code'); + } + $this->assertEquals($aExpected, $aActual, 'Unexpected value for functionalcis_list'); + } + + + /** + * @param int|string|null $sTicketId + * + * @return void + */ + public function GivenRelationContextQueryWillFindTicket(int|string|null $sTicketId): void + { + $aRelationContext = \MetaModel::GetConfig()->GetModuleSetting('itop-tickets', 'relation_context'); + $aRelationContext['UserRequest']['impacts']['down']['items'][0]['oql'] = "SELECT FCI, R + FROM FunctionalCI AS FCI + JOIN lnkFunctionalCIToTicket AS L ON L.functionalci_id = FCI.id + JOIN UserRequest AS R ON L.ticket_id = R.id + WHERE (R.id = $sTicketId)"; + \MetaModel::GetConfig()->SetModuleSetting('itop-tickets', 'relation_context', $aRelationContext); + } + private function GivenCITreeInDB(string $sTree) + { + $aTree = explode("\n", $sTree); + foreach ($aTree as $sLine) { + $this->GivenCITreeLineInDB($sLine); + } + } + + private function GivenCITreeLineInDB(string $sLine) + { + if (strpos($sLine, '<->') !== false) { + list($sCI, $sPerson) = explode('<->', $sLine); + $sPersonId = $this->GivenCIOrPersonInDB(trim($sPerson)); + $sCIId = $this->GivenCIOrPersonInDB(trim($sCI)); + $this->GivenLnkContactToFunctionalCIInDB($sPersonId, $sCIId); + return; + } + list($sCIParent, $sChildren) = explode('->', $sLine); + $aChildren = explode(',', $sChildren); + $aChildren = array_map('trim', $aChildren); + $aChildrenIdsByClass = []; + foreach ($aChildren as $sChildCI) { + list($sChildClass, ) = explode('_', $sChildCI, 2); + $aChildrenIdsByClass[$sChildClass] = $this->GivenCIOrPersonInDB($sChildCI); + } + $this->GivenCIOrPersonInDB($sCIParent, $aChildrenIdsByClass); + } + + private function GivenCIOrPersonInDB(string $sDescriptor, array $aChildrenIdsByClass = []): string + { + $sDescriptor = trim($sDescriptor); + if (isset($this->aCIs[$sDescriptor])) { + return $this->aCIs[$sDescriptor]; + } + list($sClass, $sRef) = explode('_', $sDescriptor, 2); + switch ($sClass) { + case 'Server': + $sCIId = $this->GivenServerInDB($sRef); + break; + case 'Hypervisor': + $sCIId = $this->GivenHypervisorInDB($sRef, $aChildrenIdsByClass['Server'] ?? 0, $aChildrenIdsByClass['Farm'] ?? 0); + break; + case 'Person': + $sCIId = $this->GivenPersonInDB($sRef); + break; + case 'Farm': + $sCIId = $this->GivenFarmInDB($sRef); + break; + case 'VirtualMachine': + $sCIId = $this->GivenVirtualMachineInDB($sRef, $aChildrenIdsByClass['Farm']); + break; + default: + throw new Exception("Unhandled class $sClass"); + } + $this->aCIs[$sDescriptor] = $sCIId; + return $this->aCIs[$sDescriptor]; + } + + private function GivenTicketWithCIsOrPersons(array $aLinkedObjects) : \UserRequest + { + $oTicket = $this->GivenTicketObject(1); + foreach ($aLinkedObjects as $sObjectDescriptor => $sRole) { + $sClass = trim(explode('_', $sObjectDescriptor)[0]); + if ($sClass === 'Person') { + $this->AddLnkContactToTicketObject($this->GivenCIOrPersonInDB($sObjectDescriptor), $oTicket, $sRole); + continue; + } + $this->AddLnkFunctionalCIToTicketObject($this->GivenCIOrPersonInDB($sObjectDescriptor), $oTicket, $sRole); + } + return $oTicket; + } + + private function GivenCINotAllowedToCurrentUser(string $sCIDescriptor) + { + $iAnotherOrg = $this->GivenObjectInDB(Organization::class, ['name' => 'Another Org']); + + // Change the organization of the CI to 'Another Org' + $sCIDescriptor = trim($sCIDescriptor); + if (!isset($this->aCIs[$sCIDescriptor])) { + throw new Exception("CI $sCIDescriptor not found"); + } + $sCIId = $this->aCIs[$sCIDescriptor]; + + $oCI = \MetaModel::GetObject('FunctionalCI', $sCIId); + $oCI->Set('org_id', $iAnotherOrg); + $oCI->DBUpdate(); + + $sConfigManagerProfileId = 3; // access to CIs + $sLogin = $this->GivenUserRestrictedToAnOrganizationInDB($this->getTestOrgId(), $sConfigManagerProfileId); + + UserRights::Login($sLogin); + $this->ResetMetaModelQueyCacheGetObject(); + } +} diff --git a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-tickets/itopTicketTest.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-tickets/itopTicketTest.php deleted file mode 100644 index b10224c13..000000000 --- a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-tickets/itopTicketTest.php +++ /dev/null @@ -1,922 +0,0 @@ - -// - -/** - * Created by PhpStorm. - * User: Eric - * Date: 18/12/2017 - * Time: 13:34 - */ - -namespace Combodo\iTop\Test\UnitTest\Module\iTopTickets; - -use Combodo\iTop\Test\UnitTest\ItopDataTestCase; -use Exception; - - -/** - * @group itopVirtualizationMgmt - * @group itopConfigMgmt - * @group itopTickets - */ -class ItopTicketTest extends ItopDataTestCase -{ - const CREATE_TEST_ORG = true; - - /** - *
-	 * Given:
-	 *
-	 * Server1+---->Hypervisor1+---->Person1
-	 *
-	 * Ticket+---->Server1 (manual)
-	 *
-	 * Result:
-	 *
-	 * Ticket+====>Server1,Hypervisor1
-	 *       |
-	 *       +====>Person1
-	 * 
- * - * @throws Exception - */ - public function testUpdateImpactedItems_Basic() - { - $oTicket = $this->CreateTicket(1); - $oServer1 = $this->CreateServer(1); - $oHypervisor1 = $this->CreateHypervisor(1, $oServer1); - $oPerson1 = $this->CreatePerson(1); - $this->AddContactToCI($oPerson1, $oHypervisor1); - $oHypervisor1->DBUpdate(); - - $aAwaitedCIs = $this->AddCIToTicket($oServer1, $oTicket, 'manual'); - $oTicket->DBUpdate(); // trigger the impact update - $this->ReloadObject($oTicket); // reload the links - - // Add the computed CIs - $aAwaitedCIs = $aAwaitedCIs + array($oHypervisor1->GetKey() => 'computed'); - - $this->CheckFunctionalCIList($oTicket, $aAwaitedCIs); - - // Computed Contacts - $aAwaitedContacts = array($oPerson1->GetKey() => array('role_code' => 'computed')); - $this->CheckContactList($oTicket, $aAwaitedContacts); - $this->assertEquals(2, $oTicket->Get('functionalcis_list')->Count()); - $this->assertEquals(1, $oTicket->Get('contacts_list')->Count()); - } - - /** - *
-     * Given:
-     *
-     * Server1+---->Hypervisor1+---->Person1
-     *
-     * Ticket+---->Server1 (manual)
-     *
-     * Result:
-     *
-     * Ticket+====>Server1,Hypervisor1
-     *       |
-     *       +====>Person1
-     * 
- * - * @throws Exception - */ - public function testUpdateImpactedItems_Basic2() - { - $oTicket = $this->CreateTicket(1); - $oServer1 = $this->CreateServer(1); - $oHypervisor1 = $this->CreateHypervisor(1, $oServer1); - $oPerson1 = $this->CreatePerson(1); - $this->AddContactToCI($oPerson1, $oHypervisor1); - $oHypervisor1->DBUpdate(); - - $this->AddCIToTicket($oServer1, $oTicket, 'manual'); - $oTicket->DBUpdate(); // trigger the impact update - - $this->ReloadObject($oTicket); // reload the links - - $this->CheckFunctionalCIList($oTicket); - $this->CheckContactList($oTicket); - $this->assertEquals(2, $oTicket->Get('functionalcis_list')->Count()); - $this->assertEquals(1, $oTicket->Get('contacts_list')->Count()); - - // Try removing computed entries - $this->RemoveCIFromTicket($oHypervisor1, $oTicket); - $this->RemoveContactFromTicket($oPerson1, $oTicket); - $oTicket->DBUpdate(); // trigger the impact update - $this->ReloadObject($oTicket); // reload the links - - $this->CheckFunctionalCIList($oTicket); - $this->CheckContactList($oTicket); - $this->assertEquals(2, $oTicket->Get('functionalcis_list')->Count()); - $this->assertEquals(1, $oTicket->Get('contacts_list')->Count()); - } - - /** - *
-     * Given:
-     *
-     * Server1+---->Hypervisor1+---->Person1
-     *
-     * Server2    Person2
-     *
-     * Ticket+---->Server1 (manual), Server2 (computed)
-     *
-     * Result:
-     *
-     * Ticket+====>Server1,Hypervisor1
-     *       |
-     *       +====>Person1
-     * 
- * - * @throws Exception - */ - public function testUpdateImpactedItems_RemoveUnecessaryEntries() - { - $oTicket = $this->CreateTicket(1); - $oServer1 = $this->CreateServer(1); - $oHypervisor1 = $this->CreateHypervisor(1, $oServer1); - $oPerson1 = $this->CreatePerson(1); - $this->AddContactToCI($oPerson1, $oHypervisor1); - $oHypervisor1->DBUpdate(); - - $oServer2 = $this->CreateServer(2); - $oPerson2 = $this->CreatePerson(2); - - $this->AddCIToTicket($oServer1, $oTicket, 'manual'); - $this->AddCIToTicket($oServer2, $oTicket, 'computed'); - $this->AddContactToTicket($oPerson2, $oTicket, 'computed'); - $oTicket->DBUpdate(); // trigger the impact update - $this->ReloadObject($oTicket); // reload the links - - $this->CheckFunctionalCIList($oTicket); - $this->CheckContactList($oTicket); - $this->assertEquals(2, $oTicket->Get('functionalcis_list')->Count()); - $this->assertEquals(1, $oTicket->Get('contacts_list')->Count()); - } - - /** - * Create a first impact chain then remove the root cause, all the chain should be removed. - * - *
-     * Given:
-     *
-     * Server1+---->Hypervisor1+---->Person1
-     *
-     * Ticket+---->Server1 (manual)
-     *
-     * Result:
-     *
-     * Ticket+====>Server1,Hypervisor1
-     *       |
-     *       +====>Person1
-     *
-     * Then remove Server1
-     *
-     * Result:
-     *
-     * Ticket+====>
-     *       |
-     *       +====>
-     *
-     * 
- * - * @throws Exception - */ - public function testUpdateImpactedItems_RemoveUnecessaryEntries2() - { - $oTicket = $this->CreateTicket(1); - $oServer1 = $this->CreateServer(1); - $oHypervisor1 = $this->CreateHypervisor(1, $oServer1); - $oPerson1 = $this->CreatePerson(1); - $this->AddContactToCI($oPerson1, $oHypervisor1); - $oHypervisor1->DBUpdate(); - - $this->AddCIToTicket($oServer1, $oTicket, 'manual'); - $oTicket->DBUpdate(); // trigger the impact update - $this->ReloadObject($oTicket); // reload the links - - $this->CheckFunctionalCIList($oTicket); - $this->CheckContactList($oTicket); - $this->assertEquals(2, $oTicket->Get('functionalcis_list')->Count()); - $this->assertEquals(1, $oTicket->Get('contacts_list')->Count()); - - $this->RemoveCIFromTicket($oServer1, $oTicket); - $oTicket->DBUpdate(); // trigger the impact update - $this->ReloadObject($oTicket); // reload the links - - $this->CheckFunctionalCIList($oTicket); - $this->CheckContactList($oTicket); - $this->assertEquals(0, $oTicket->Get('functionalcis_list')->Count()); - $this->assertEquals(0, $oTicket->Get('contacts_list')->Count()); - } - - - /** - *
-     *
-     * Server2+---->Hypervisor2+---->Person2
-     *
-     * Ticket+---->(empty)
-     *
-     * Result:
-     *
-     * Ticket+====>(empty)
-     * 
- * - * @throws Exception - */ - public function testUpdateImpactedItems_NoImpact() - { - $oTicket = $this->CreateTicket(1); - $oServer2 = $this->CreateServer(2); - $oPerson2 = $this->CreatePerson(2); - $oHypervisor2 = $this->CreateHypervisor(2, $oServer2); - $this->AddContactToCI($oPerson2, $oHypervisor2); - $oHypervisor2->DBUpdate(); - - $oTicket->DBUpdate(); // trigger the impact update - $this->ReloadObject($oTicket); // reload the links - - $this->CheckFunctionalCIList($oTicket); - $this->CheckContactList($oTicket); - $this->assertEquals(0, $oTicket->Get('functionalcis_list')->Count()); - $this->assertEquals(0, $oTicket->Get('contacts_list')->Count()); - } - - /** - *
-	 * Server1
-	 *
-	 * Server2+---->Hypervisor2+---->Person2
-	 *
-	 * Ticket+---->Server1 (manual)
-	 *
-	 * Result:
-	 *
-	 * Ticket+====>Server1
-	 * 
- * - * @throws Exception - */ - public function testUpdateImpactedItems_NoImpact2() - { - $oTicket = $this->CreateTicket(1); - $oServer1 = $this->CreateServer(1); - $oServer2 = $this->CreateServer(2); - $oPerson2 = $this->CreatePerson(2); - $oHypervisor2 = $this->CreateHypervisor(2, $oServer2); - $this->AddContactToCI($oPerson2, $oHypervisor2); - $oHypervisor2->DBUpdate(); - - $this->AddCIToTicket($oServer1, $oTicket, 'manual'); - $oTicket->DBUpdate(); // trigger the impact update - $this->ReloadObject($oTicket); // reload the links - - $this->CheckFunctionalCIList($oTicket); - $this->CheckContactList($oTicket); - $this->assertEquals(1, $oTicket->Get('functionalcis_list')->Count()); - $this->assertEquals(0, $oTicket->Get('contacts_list')->Count()); - } - - /** - *
-	 *                    +-->Person1
-	 *                    |
-	 *                    +
-	 * Server1+---->Hypervisor1+--+
-	 *                            |
-	 *                            v
-	 *                            Farm (1)
-	 *                            ^
-	 *                            |
-	 * Server2+---->Hypervisor2+--+
-	 *                    +
-	 *                    |
-	 *                    +-->Person2
-	 *
-	 * Ticket+---->Server1 (manual)
-	 *
-	 * Result:
-	 *
-	 * Ticket+====>Server1,Hypervisor1
-	 *       |
-	 *       +====>Person1
-	 * 
- * - * @throws Exception - */ - public function testUpdateImpactedItems_Redundancy() - { - $oFarm = $this->CreateFarm(1); - - $oServer1 = $this->CreateServer(1); - $oHypervisor1 = $this->CreateHypervisor(1, $oServer1, $oFarm); - $oContact1 = $this->CreatePerson(1); - $this->AddContactToCI($oContact1, $oHypervisor1); - $oHypervisor1->DBUpdate(); - - $oServer2 = $this->CreateServer(2); - $oHypervisor2 = $this->CreateHypervisor(2, $oServer2, $oFarm); - $oContact2 = $this->CreatePerson(2); - $this->AddContactToCI($oContact2, $oHypervisor2); - $oHypervisor2->DBUpdate(); - - $oTicket = $this->CreateTicket(1); - $this->AddCIToTicket($oServer1, $oTicket, 'manual'); - $oTicket->DBUpdate(); // trigger the impact update - $this->ReloadObject($oTicket); // reload the links - - $this->CheckFunctionalCIList($oTicket); - $this->CheckContactList($oTicket); - $this->assertEquals(2, $oTicket->Get('functionalcis_list')->Count()); - $this->assertEquals(1, $oTicket->Get('contacts_list')->Count()); - } - - /** - *
-	 *                    +-->Person1
-	 *                    |
-	 *                    +
-	 * Server1+---->Hypervisor1+--+
-	 *                            |
-	 *                            v
-	 *                            Farm (1)
-	 *                            ^
-	 *                            |
-	 * Server2+---->Hypervisor2+--+
-	 *                    +
-	 *                    |
-	 *                    +-->Person2
-	 *
-	 * Ticket+---->Server1 (manual), Hypervisor2 (manual)
-	 *
-	 * Result:
-	 *
-	 * Ticket+====>Server1,Hypervisor1,Farm,Hypervisor2
-	 *       |
-	 *       +====>Person1,Person2
-	 * 
- * - * @throws Exception - */ - public function testUpdateImpactedItems_Redundancy2() - { - $oFarm = $this->CreateFarm(1); - - $oServer1 = $this->CreateServer(1); - $oHypervisor1 = $this->CreateHypervisor(1, $oServer1, $oFarm); - $oContact1 = $this->CreatePerson(1); - $this->AddContactToCI($oContact1, $oHypervisor1); - $oHypervisor1->DBUpdate(); - - $oServer2 = $this->CreateServer(2); - $oHypervisor2 = $this->CreateHypervisor(2, $oServer2, $oFarm); - $oContact2 = $this->CreatePerson(2); - $this->AddContactToCI($oContact2, $oHypervisor2); - $oHypervisor2->DBUpdate(); - - $oTicket = $this->CreateTicket(1); - $this->AddCIToTicket($oServer1, $oTicket, 'manual'); - $this->AddCIToTicket($oHypervisor2, $oTicket, 'manual'); - $oTicket->DBUpdate(); // trigger the impact update - $this->ReloadObject($oTicket); // reload the links - - $this->CheckFunctionalCIList($oTicket); - $this->CheckContactList($oTicket); - $this->assertEquals(4, $oTicket->Get('functionalcis_list')->Count()); - $this->assertEquals(2, $oTicket->Get('contacts_list')->Count()); - } - - - /** - *
-	 *                    +-->Person1
-	 *                    |
-	 *                    +
-	 * Server1+---->Hypervisor1+--+  +-->VM1
-	 *                            |  |
-	 *                            v  +
-	 *                            Farm (1)
-	 *                            ^  +
-	 *                            |  |
-	 * Server2+---->Hypervisor2+--+  +-->VM2
-	 *                    +
-	 *                    |
-	 *                    +-->Person2
-	 *
-	 * Ticket+---->Server1 (manual), Hypervisor2 (manual)
-	 *
-	 * Result:
-	 *
-	 * Ticket+====>Server1,Hypervisor1,Farm,Hypervisor2,VM1,VM2
-	 *       |
-	 *       +====>Person1,Person2
-	 * 
- * - * @throws Exception - */ - public function testUpdateImpactedItems_Redundancy3() - { - $oFarm = $this->CreateFarm(1); - - $oServer1 = $this->CreateServer(1); - $oHypervisor1 = $this->CreateHypervisor(1, $oServer1, $oFarm); - $oContact1 = $this->CreatePerson(1); - $this->AddContactToCI($oContact1, $oHypervisor1); - $oHypervisor1->DBUpdate(); - - $oServer2 = $this->CreateServer(2); - $oHypervisor2 = $this->CreateHypervisor(2, $oServer2, $oFarm); - $oContact2 = $this->CreatePerson(2); - $this->AddContactToCI($oContact2, $oHypervisor2); - $oHypervisor2->DBUpdate(); - - $this->CreateVirtualMachine(1, $oFarm); - $this->CreateVirtualMachine(2, $oFarm); - - $oTicket = $this->CreateTicket(1); - $this->AddCIToTicket($oServer1, $oTicket, 'manual'); - $this->AddCIToTicket($oHypervisor2, $oTicket, 'manual'); - $oTicket->DBUpdate(); // trigger the impact update - $this->ReloadObject($oTicket); // reload the links - - $this->CheckFunctionalCIList($oTicket); - $this->CheckContactList($oTicket); - $this->assertEquals(6, $oTicket->Get('functionalcis_list')->Count()); - $this->assertEquals(2, $oTicket->Get('contacts_list')->Count()); - } - - /** - *
-     *                    +-->Person1
-     *                    |
-     *                    +
-     * Server1+---->Hypervisor1+--+  +-->VM1
-     *                            |  |
-     *                            v  +
-     *                            Farm (1)
-     *                            ^  +
-     *                            |  |
-     * Server2+---->Hypervisor2+--+  +-->VM2
-     *                    +
-     *                    |
-     *                    +-->Person2
-     *
-     * Ticket+---->Server1 (manual), Server2 (manual), Hypervisor2 (not_impacted)
-     *
-     * Result:
-     *
-     * Ticket+====>Server1,Hypervisor1,Server2,Hypervisor2
-     *       |
-     *       +====>Person1
-     * 
- * - * @throws Exception - */ - public function testUpdateImpactedItems_Exclusion() - { - $oFarm = $this->CreateFarm(1); - - $oServer1 = $this->CreateServer(1); - $oHypervisor1 = $this->CreateHypervisor(1, $oServer1, $oFarm); - $oContact1 = $this->CreatePerson(1); - $this->AddContactToCI($oContact1, $oHypervisor1); - $oHypervisor1->DBUpdate(); - - $oServer2 = $this->CreateServer(2); - $oHypervisor2 = $this->CreateHypervisor(2, $oServer2, $oFarm); - $oContact2 = $this->CreatePerson(2); - $this->AddContactToCI($oContact2, $oHypervisor2); - $oHypervisor2->DBUpdate(); - - $this->CreateVirtualMachine(1, $oFarm); - $this->CreateVirtualMachine(2, $oFarm); - - $oTicket = $this->CreateTicket(1); - $this->AddCIToTicket($oServer1, $oTicket, 'manual'); - $this->AddCIToTicket($oServer2, $oTicket, 'manual'); - $this->AddCIToTicket($oHypervisor2, $oTicket, 'not_impacted'); - $oTicket->DBUpdate(); // trigger the impact update - $this->ReloadObject($oTicket); // reload the links - - $this->CheckFunctionalCIList($oTicket); - $this->CheckContactList($oTicket); - $this->assertEquals(4, $oTicket->Get('functionalcis_list')->Count()); - $this->assertEquals(1, $oTicket->Get('contacts_list')->Count()); - } - - /** - *
-     *                    +-->Person1
-     *                    |
-     *                    +
-     * Server1+---->Hypervisor1+--+  +-->VM1
-     *                            |  |
-     *                            v  +
-     *                            Farm (1)
-     *                            ^  +
-     *                            |  |
-     * Server2+---->Hypervisor2+--+  +-->VM2
-     *                    +
-     *                    |
-     *                    +-->Person2
-     *
-     * Ticket+---->Server1 (manual), Server2 (manual)
-     *       |
-     *       +---->Person2 (do_not_notify)
-     *
-     * Result:
-     *
-     * Ticket+====>Server1,Hypervisor1,Server2,Hypervisor2,Farm,VM1,VM2
-     *       |
-     *       +====>Person1,Person2 (do_not_notify)
-     * 
- * - * @throws Exception - */ - public function testUpdateImpactedItems_Exclusion2() - { - $oFarm = $this->CreateFarm(1); - - $oServer1 = $this->CreateServer(1); - $oHypervisor1 = $this->CreateHypervisor(1, $oServer1, $oFarm); - $oContact1 = $this->CreatePerson(1); - $this->AddContactToCI($oContact1, $oHypervisor1); - $oHypervisor1->DBUpdate(); - - $oServer2 = $this->CreateServer(2); - $oHypervisor2 = $this->CreateHypervisor(2, $oServer2, $oFarm); - $oContact2 = $this->CreatePerson(2); - $this->AddContactToCI($oContact2, $oHypervisor2); - $oHypervisor2->DBUpdate(); - - $this->CreateVirtualMachine(1, $oFarm); - $this->CreateVirtualMachine(2, $oFarm); - - $oTicket = $this->CreateTicket(1); - $this->AddCIToTicket($oServer1, $oTicket, 'manual'); - $this->AddCIToTicket($oServer2, $oTicket, 'manual'); - $this->AddContactToTicket($oContact2, $oTicket, 'do_not_notify'); - $oTicket->DBUpdate(); // trigger the impact update - $this->ReloadObject($oTicket); // reload the links - - $this->CheckFunctionalCIList($oTicket); - $this->CheckContactList($oTicket); - $this->assertEquals(7, $oTicket->Get('functionalcis_list')->Count()); - $this->assertEquals(2, $oTicket->Get('contacts_list')->Count()); - } - - /** - *
-     *                    +-->Person1
-     *                    |
-     *                    +
-     * Server1+---->Hypervisor1+--+  +-->VM1
-     *                            |  |
-     *                            v  +
-     *                            Farm (1)
-     *                            ^  +
-     *                            |  |
-     * Server2+---->Hypervisor2+--+  +-->VM2
-     *                    +
-     *                    |
-     *                    +-->Person2
-     *
-     * Ticket+---->Server1 (manual), Server2 (manual), Hypervisor2 (not_impacted)
-     *       |
-     *       +---->Person2 (do_not_notify)
-     *
-     * Result:
-     *
-     * Ticket+====>Server1,Hypervisor1,Server2,Hypervisor2
-     *       |
-     *       +====>Person1,Person2 (do_not_notify)
-     * 
- * - * @throws Exception - */ - public function testUpdateImpactedItems_Exclusion3() - { - $oFarm = $this->CreateFarm(1); - - $oServer1 = $this->CreateServer(1); - $oHypervisor1 = $this->CreateHypervisor(1, $oServer1, $oFarm); - $oContact1 = $this->CreatePerson(1); - $this->AddContactToCI($oContact1, $oHypervisor1); - $oHypervisor1->DBUpdate(); - - $oServer2 = $this->CreateServer(2); - $oHypervisor2 = $this->CreateHypervisor(2, $oServer2, $oFarm); - $oContact2 = $this->CreatePerson(2); - $this->AddContactToCI($oContact2, $oHypervisor2); - $oHypervisor2->DBUpdate(); - - $this->CreateVirtualMachine(1, $oFarm); - $this->CreateVirtualMachine(2, $oFarm); - - $oTicket = $this->CreateTicket(1); - $this->AddCIToTicket($oServer1, $oTicket, 'manual'); - $this->AddCIToTicket($oServer2, $oTicket, 'manual'); - $this->AddCIToTicket($oHypervisor2, $oTicket, 'not_impacted'); - $this->AddContactToTicket($oContact2, $oTicket, 'do_not_notify'); - $oTicket->DBUpdate(); // trigger the impact update - $this->ReloadObject($oTicket); // reload the links - - $this->CheckFunctionalCIList($oTicket); - $this->CheckContactList($oTicket); - $this->assertEquals(4, $oTicket->Get('functionalcis_list')->Count()); - $this->assertEquals(2, $oTicket->Get('contacts_list')->Count()); - } - - /** - *
-     *                    +-->Person1
-     *                    |
-     *                    +
-     * Server1+---->Hypervisor1+--+  +-->VM1
-     *                            |  |
-     *                            v  +
-     *                            Farm (1)
-     *                            ^  +
-     *                            |  |
-     * Server2+---->Hypervisor2+--+  +-->VM2
-     *                    +
-     *                    |
-     *                    +-->Person2
-     *
-     * Ticket+---->Server1 (manual), Hypervisor2 (not_impacted)
-     *
-     * Result:
-     *
-     * Ticket+====>Server1,Hypervisor1, Hypervisor2 (not_impacted)
-     *       |
-     *       +====>Person1
-     * 
- * - * @throws Exception - */ - public function testUpdateImpactedItems_Exclusion4() - { - $oFarm = $this->CreateFarm(1); - - $oServer1 = $this->CreateServer(1); - $oHypervisor1 = $this->CreateHypervisor(1, $oServer1, $oFarm); - $oContact1 = $this->CreatePerson(1); - $this->AddContactToCI($oContact1, $oHypervisor1); - $oHypervisor1->DBUpdate(); - - $oServer2 = $this->CreateServer(2); - $oHypervisor2 = $this->CreateHypervisor(2, $oServer2, $oFarm); - $oContact2 = $this->CreatePerson(2); - $this->AddContactToCI($oContact2, $oHypervisor2); - $oHypervisor2->DBUpdate(); - - $this->CreateVirtualMachine(1, $oFarm); - $this->CreateVirtualMachine(2, $oFarm); - - $oTicket = $this->CreateTicket(1); - $this->AddCIToTicket($oServer1, $oTicket, 'manual'); - $this->AddCIToTicket($oHypervisor2, $oTicket, 'not_impacted'); - $oTicket->DBUpdate(); // trigger the impact update - $this->ReloadObject($oTicket); // reload the links - - $this->CheckFunctionalCIList($oTicket); - $this->CheckContactList($oTicket); - $this->assertEquals(3, $oTicket->Get('functionalcis_list')->Count()); - $this->assertEquals(1, $oTicket->Get('contacts_list')->Count()); - } - - /** - *
-     *                    +-->Person1
-     *                    |
-     *                    +
-     * Server1+---->Hypervisor1+--+  +-->VM1
-     *                            |  |
-     *                            v  +
-     *                            Farm (1)
-     *                            ^  +
-     *                            |  |
-     * Server2+---->Hypervisor2+--+  +-->VM2
-     *                    +
-     *                    |
-     *                    +-->Person2
-     *
-     * Ticket1+---->Server1 (manual)
-     *
-     * Result:
-     *
-     * Ticket1+====>Server1,Hypervisor1
-     *        |
-     *        +====>Person1
-     *
-     * Then:
-     *
-     * Ticket2+---->Server2 (manual)
-     *
-     * Result:
-     *
-     * Ticket2+====>Server2,Hypervisor2,Farm,VM1,VM2
-     *        |
-     *        +====>Person2
-     * 
- * - * @throws \ArchivedObjectException - * @throws Exception - */ - public function testUpdateImpactedItems_Redundancy_two_tickets() - { - $oFarm = $this->CreateFarm(1); - - $oServer1 = $this->CreateServer(1); - $oHypervisor1 = $this->CreateHypervisor(1, $oServer1, $oFarm); - $oContact1 = $this->CreatePerson(1); - $this->AddContactToCI($oContact1, $oHypervisor1); - $oHypervisor1->DBUpdate(); - - $oServer2 = $this->CreateServer(2); - $oHypervisor2 = $this->CreateHypervisor(2, $oServer2, $oFarm); - $oContact2 = $this->CreatePerson(2); - $this->AddContactToCI($oContact2, $oHypervisor2); - $oHypervisor2->DBUpdate(); - - $oVM1 = $this->CreateVirtualMachine(1, $oFarm); - $oVM2 = $this->CreateVirtualMachine(2, $oFarm); - - // Ticket1+---->Server1 (manual) - $oTicket1 = $this->CreateTicket(1); - $this->AddCIToTicket($oServer1, $oTicket1, 'manual'); - $oTicket1->DBUpdate(); // trigger the impact update - $this->ReloadObject($oTicket1); // reload the links - - // Ticket1+====>Server1,Hypervisor1 - // | - // +====>Person1 - $this->CheckFunctionalCIList($oTicket1); - $this->CheckContactList($oTicket1); - $this->assertEquals(2, $oTicket1->Get('functionalcis_list')->Count()); - $this->assertEquals(1, $oTicket1->Get('contacts_list')->Count()); - - // Ticket2+---->Hypervisor2 (manual) - $oTicket2 = $this->CreateTicket(2); - $this->AddCIToTicket($oServer2, $oTicket2, 'manual'); - $oTicket2->DBUpdate(); // trigger the impact update - $this->ReloadObject($oTicket2); // reload the links - - // Ticket2+====>Farm,Hypervisor2,VM1,VM2,Server2 - // | - // +====>Person2 - $aWaitedCIList = array( - $oFarm->GetKey() => 'computed', - $oVM1->GetKey() => 'computed', - $oVM2->GetKey() => 'computed', - $oHypervisor2->GetKey() => 'computed', - $oServer2->GetKey() => 'manual'); - $this->CheckFunctionalCIList($oTicket2, $aWaitedCIList); - $this->CheckContactList($oTicket2); - $this->assertEquals(2, $oTicket2->Get('functionalcis_list')->Count()); - $this->assertEquals(1, $oTicket2->Get('contacts_list')->Count()); - - // The first ticket is not impacted - $this->debug("\nCheck that the first ticket has not changed."); - $this->ReloadObject($oTicket1); // reload the links - - // Ticket1+====>Server1,Hypervisor1 - // | - // +====>Person1 - $this->CheckFunctionalCIList($oTicket1); - $this->CheckContactList($oTicket1); - $this->assertEquals(2, $oTicket1->Get('functionalcis_list')->Count()); - $this->assertEquals(1, $oTicket1->Get('contacts_list')->Count()); - } - - /** - *
-     *                    +-->Person1
-     *                    |
-     *                    +
-     * Server1+---->Hypervisor1+--+  +-->VM1
-     *                            |  |
-     *                            v  +
-     * Server3+---->Hypervisor3+->Farm (1)
-     *                            ^  +
-     *                            |  |
-     * Server2+---->Hypervisor2+--+  +-->VM2
-     *                    +
-     *                    |
-     *                    +-->Person2
-     *
-     * Ticket1+---->Server1 (manual), Hypervisor2(manual)
-     *
-     * Result:
-     *
-     * Ticket1+====>Server1,Hypervisor1, Hypervisor2
-     *        |
-     *        +====>Person1, Person2
-     *
-     * Then:
-     *
-     * Ticket2+---->Server2 (manual), Hypervisor3 (manual)
-     *
-     * Result:
-     *
-     * Ticket2+====>Server2,Hypervisor2,Hypervisor3,Farm,VM1,VM2
-     *        |
-     *        +====>Person2
-     * 
- * - * @throws \ArchivedObjectException - * @throws Exception - */ - public function testUpdateImpactedItems_Redundancy_two_tickets2() - { - $oFarm = $this->CreateFarm(1); - - $oServer1 = $this->CreateServer(1); - $oHypervisor1 = $this->CreateHypervisor(1, $oServer1, $oFarm); - $oContact1 = $this->CreatePerson(1); - $this->AddContactToCI($oContact1, $oHypervisor1); - $oHypervisor1->DBUpdate(); - - $oServer2 = $this->CreateServer(2); - $oHypervisor2 = $this->CreateHypervisor(2, $oServer2, $oFarm); - $oContact2 = $this->CreatePerson(2); - $this->AddContactToCI($oContact2, $oHypervisor2); - $oHypervisor2->DBUpdate(); - - $oServer3 = $this->CreateServer(3); - $oHypervisor3 = $this->CreateHypervisor(3, $oServer3, $oFarm); - - - $oVM1 = $this->CreateVirtualMachine(1, $oFarm); - $oVM2 = $this->CreateVirtualMachine(2, $oFarm); - - // Ticket1+---->Server1 (manual), Hypervisor2(manual) - $oTicket1 = $this->CreateTicket(1); - $this->AddCIToTicket($oServer1, $oTicket1, 'manual'); - $this->AddCIToTicket($oHypervisor2, $oTicket1, 'manual'); - $oTicket1->DBUpdate(); // trigger the impact update - $this->ReloadObject($oTicket1); // reload the links - - // Ticket1+====>Server1,Hypervisor1,Hypervisor2 - // | - // +====>Person1,Person2 - $this->CheckFunctionalCIList($oTicket1); - $this->CheckContactList($oTicket1); - $this->assertEquals(3, $oTicket1->Get('functionalcis_list')->Count()); - $this->assertEquals(2, $oTicket1->Get('contacts_list')->Count()); - - // Ticket2+---->Server2 (manual) - $oTicket2 = $this->CreateTicket(2); - $this->AddCIToTicket($oServer2, $oTicket2, 'manual'); - $this->AddCIToTicket($oHypervisor3, $oTicket2, 'manual'); - $oTicket2->DBUpdate(); // trigger the impact update - $this->ReloadObject($oTicket2); // reload the links - - // Ticket2+====>Farm,Hypervisor2,VM1,VM2,Server2 - // | - // +====>Person2 - $aWaitedCIList = array( - $oFarm->GetKey() => 'computed', - $oVM1->GetKey() => 'computed', - $oVM2->GetKey() => 'computed', - $oHypervisor2->GetKey() => 'computed', - $oHypervisor3->GetKey() => 'manual', - $oServer2->GetKey() => 'manual'); - $this->CheckFunctionalCIList($oTicket2, $aWaitedCIList); - $this->CheckContactList($oTicket2); - $this->assertEquals(3, $oTicket2->Get('functionalcis_list')->Count()); - $this->assertEquals(1, $oTicket2->Get('contacts_list')->Count()); - - // The first ticket is not impacted - $this->debug("\nCheck that the first ticket has not changed."); - $this->ReloadObject($oTicket1); // reload the links - - // Ticket1+====>Server1,Hypervisor1,Hypervisor2 - // | - // +====>Person1,Person2 - $this->CheckFunctionalCIList($oTicket1); - $this->CheckContactList($oTicket1); - $this->assertEquals(3, $oTicket1->Get('functionalcis_list')->Count()); - $this->assertEquals(2, $oTicket1->Get('contacts_list')->Count()); - } - -} diff --git a/tests/php-unit-tests/unitary-tests/sources/Application/Status/StatusTest.php b/tests/php-unit-tests/unitary-tests/sources/Application/Status/StatusTest.php index e8a589a17..a91bc4aa2 100644 --- a/tests/php-unit-tests/unitary-tests/sources/Application/Status/StatusTest.php +++ b/tests/php-unit-tests/unitary-tests/sources/Application/Status/StatusTest.php @@ -20,9 +20,7 @@ class StatusTest extends ItopTestCase protected function GetPHPCommand() { - $this->RequireOnceItopFile('application/utils.inc.php'); - $oConfig = new Config(ITOP_DEFAULT_CONFIG_FILE); - return $oConfig->Get('php_path'); + return PHP_BINARY; } public function testStatusPageRepliesAsExpected() @@ -30,6 +28,7 @@ class StatusTest extends ItopTestCase $sPath = APPROOT.'/webservices/status.php'; $sPHP = $this->GetPHPCommand(); +echo "About to execute: $sPHP $sPath\n"; exec("$sPHP $sPath", $aOutput, $iRet); $this->assertEquals(0, $iRet, "Problem executing status page: $sPath, $iRet, aOutput:\n".var_export($aOutput, true)); diff --git a/tests/php-unit-tests/unitary-tests/tests/php-unit-tests/GivenObjectInDBTest.php b/tests/php-unit-tests/unitary-tests/tests/php-unit-tests/GivenObjectInDBTest.php new file mode 100644 index 000000000..d26397e1d --- /dev/null +++ b/tests/php-unit-tests/unitary-tests/tests/php-unit-tests/GivenObjectInDBTest.php @@ -0,0 +1,184 @@ +assertDBQueryCount(14, function() use (&$iKey) { + $iKey = $this->createObject('Organization', ['name' => 'The world company']); + }); + + $this->assertDBQueryCount(2, function() use (&$iKey) { + $iKey = $this->GivenObjectInDB('Organization', ['name' => 'The world company']); + }); + } + + public function testItShouldFillInTheOrganizationWhenOmitted() + { + $iPerson = $this->GivenObjectInDB('Person', [ + 'name' => 'Doe', + 'first_name' => 'John', + ]); + + $oPerson = MetaModel::GetObject('Person', $iPerson); + + $this->assertEquals( + $this->getTestOrgId(), + $oPerson->Get('org_id'), + "When omitted, the org_id should be set to getTestOrgId()" + ); + } + + public function testItShouldHandleLinksetToo() + { + $iPerson = $this->GivenObjectInDB('Person', [ + 'name' => 'Doe', + 'first_name' => 'John', + ]); + + $iTeam = $this->GivenObjectInDB('Team', [ + 'name' => 'The A Team', + 'persons_list' => [ + "person_id:$iPerson;role_id:1" + ], + ]); + + $oSet = new \DBObjectSet(\DBObjectSearch::FromOQL("SELECT lnkPersonToTeam AS lnk WHERE lnk.team_id = $iTeam AND lnk.person_id = $iPerson")); + $this->assertEquals(1, $oSet->Count(), "The link between the team and the person should be there"); + $oLnk = $oSet->Fetch(); + $this->assertEquals(1, $oLnk->Get('role_id'), "The role should be correctly set"); + } + + public function testItShouldFailExplicitlyWhenAnAttributeCodeIsUnknown() + { + $this->expectException(\Exception::class); + $this->expectExceptionMessage("GivenObjectInDB('Organization'), invalid attribute code 'amen'"); + + $this->GivenObjectInDB('Organization', ['amen' => 'The world company']); + } + + public function testItShouldFailExplicitlyWhenAMandatoryAttributeIsMissing() + { + // Note : a mandatory attribute is an attribute for which the default value cannot be used by default + // because it is not nullable and the default is "null" + + $this->expectException(\Exception::class); + $this->expectExceptionMessage("GivenObjectInDB('Organization'), mandatory attribute 'name' is missing"); + + $this->GivenObjectInDB('Organization', []); + } + + /** + * @dataProvider SampleObjectsProvider + */ + public function testItShouldMakeExactSameObjectsASDBInsert($sClass, $aValues) + { + $oObjectCreatedWithCompleteStack = parent::createObject($sClass, $aValues); + + $oObjectFromDBStandard = MetaModel::GetObject($sClass, $oObjectCreatedWithCompleteStack->GetKey()); + + // Create by the mean of the efficient method + $iKey = $this->GivenObjectInDB($sClass, $aValues); + + // Check that it is readable (no exception) + $oObjectFromDBOptimized = MetaModel::GetObject($sClass, $iKey); + + // Check that an object created by the mean of the std APIs will have the same values + foreach ($aValues as $sAttCode => $value) + { + static::assertEquals( + $oObjectFromDBStandard->Get($sAttCode), + $oObjectFromDBOptimized->Get($sAttCode), + "The value of the attribute '$sAttCode' should be the same as for an object recorded with DBObject::DBInsert" + ); + } + } + + public function SampleObjectsProvider() + { + return [ + 'Organization' => [ + 'class' => 'Organization', + 'values' => [ + 'name' => 'Orga tartampion', + ] + ], + 'FAQCategory' => [ + 'class' => 'FAQCategory', + 'values' => [ + 'name' => 'FAQCategory_phpunit', + ] + ], + 'Server' => [ + 'class' => 'Server', + 'values' => [ + 'name' => 'Server tartampion', + 'org_id' => 1, + 'nb_u' => 123, + ] + ], + 'TagSetFieldDataFor_FAQ__domains' => [ + 'class' => 'TagSetFieldDataFor_FAQ__domains', + 'values' => [ + 'code' => 'tagada'.uniqid(), + 'label' => 'label for tagada'.uniqid(), + 'obj_class' => 'FAQ', + 'obj_attcode' => 'domains', + 'description' => '

tartampion

', + ] + ], + 'Hypervisor' => [ + 'class' => 'Hypervisor', + 'values' => [ + 'name' => 'Hypervisor_tartampion', + 'org_id' => 1, + 'server_id' => 1, + 'farm_id' => 0, + ] + ], + 'Rack' => [ + 'class' => 'Rack', + 'values' => [ + 'name' => "rackamuffin", + 'description' => "rackadescription", + 'org_id' => 1 + ] + ], + 'Person' => [ + 'class' => 'Person', + 'values' => [ + 'name' => 'Person_tartampion', + 'first_name' => 'Test', + 'org_id' => 1, + ] + ], + 'Farm' => [ + 'class' => 'Farm', + 'values' => [ + 'name' => 'Farm_tartampion', + 'org_id' => 1, + 'redundancy' => '1', + ] + ], + 'UserRequest' => [ + 'class' => 'UserRequest', + 'values' => [ + 'ref' => 'Ticket_tartampion', + 'title' => 'TICKET_TARTAMPION as a title', + 'description' => '

Created for unit tests.

', + 'org_id' => 1, + ] + ], + ]; + } +}