createObject('Person', array( 'first_name' => 'isaac', 'name' => 'asimov', 'email' => 'isaac.asimov@fundation.org', 'org_id' => $this->getTestOrgId(), )); $aData = array( array( $oPerson->Get("first_name"), $oPerson->Get("name"), $oPerson->Get("email"), "EN US", "iasimov", "harryseldon", "profileid->name:Administrator", ), ); $aAttributes = array("language" => 3, "login" => 4, "password" => 5, "profile_list" => 6); $aExtKeys = array( "contactid" => array("first_name" => 0, "name" => 1, "email" => 2), ); $oBulk = new \BulkChange( "UserLocal", $aData, $aAttributes, $aExtKeys, array("login"), null, null, "Y-m-d H:i:s", // date format true // localize ); $oChange = \CMDBObject::GetCurrentChange(); $aRes = $oBulk->Process($oChange); static::assertNotNull($aRes); foreach ($aRes as $aRow) { if (array_key_exists('__STATUS__', $aRow)) { $sStatus = $aRow['__STATUS__']; $this->assertFalse(strstr($sStatus->GetDescription(), "CoreCannotSaveObjectException"), "CSVimport/Datasynchro: Password validation failed with: ".$sStatus->GetDescription()); } } } /** * test $oBulk->Process with server 1 from demo datas * @dataProvider BulkChangeProvider * * @param $aData * @param $aAttributes * @param $aExtKeys * @param $aReconcilKeys */ public function testBulkChangeIssue($aData, $aAttributes, $aExtKeys, $aReconcilKeys, $aResult) { $this->debug("aReconcilKeys:".$aReconcilKeys[0]); $oBulk = new \BulkChange( "Server", $aData, $aAttributes, $aExtKeys, $aReconcilKeys, null, null, "Y-m-d H:i:s", // date format true // localize ); $oChange = \CMDBObject::GetCurrentChange(); $aRes = $oBulk->Process($oChange); static::assertNotNull($aRes); foreach ($aRes as $aRow) { if (array_key_exists('__STATUS__', $aRow)) { $sStatus = $aRow['__STATUS__']; //$this->debug("sStatus:".$sStatus->GetDescription()); $this->assertEquals($aResult["__STATUS__"], $sStatus->GetDescription()); foreach ($aRow as $i => $oCell) { if ($i != "finalclass" && $i != "__STATUS__" && $i != "__ERRORS__") { $this->debug("i:".$i); $this->debug('GetDisplayableValue:'.$oCell->GetDisplayableValue()); $this->debug("aResult:".$aResult[$i]); $this->assertEquals($aResult[$i], $oCell->GetDisplayableValue()); } } } } } public function BulkChangeProvider() { return [ "Case 3, 5 et 8 : unchanged" => [ [["Demo", "Server1", "1", "production", ""]], ["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4], ["org_id" => ["name" => 0]], ["id"], [0 => "Demo", "org_id" => "3", 1 => "Server1", 2 => "1", 3 => "production", 4 => "", "id" => 1, "__STATUS__" => "unchanged"], ], "Case 9 : wrong date format" => [ [["Demo", "Server1", "1", "production", "date"]], ["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4], ["org_id" => ["name" => 0]], ["id"], [ 0 => "Demo", "org_id" => "n/a", 1 => "Server1", 2 => "1", 3 => "production", 4 => "'date' is an invalid value", "id" => 1, "__STATUS__" => "Issue: wrong date format"], ], "Case 1 : no match" => [ [["Bad", "Server1", "1", "production", ""]], ["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4], ["org_id" => ["name" => 0]], ["id"], ["org_id" => "No match for value 'Bad'",1 => "Server1",2 => "1", 3 => "production", 4 => "", "id" => 1, "__STATUS__" => "Issue: Unexpected attribute value(s)"], ], "Case 10 : Missing mandatory value" => [ [["", "Server1", "1", "production", ""]], ["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4], ["org_id" => ["name" => 0]], ["id"], [ "org_id" => "invalid value for attribute", 1 => "Server1", 2 => "1", 3 => "production", 4 => "", "id" => 1, "__STATUS__" => "Issue: Unexpected attribute value(s)"], ], "Case 6 : Unexpected value" => [ [["Demo", "Server1", "1", "", ""]], ["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4], ["org_id" => ["name" => 0]], ["id"], [ 0 => "Demo", "org_id" => "3", 1 => "Server1", 2 => "1", 3 => "'<svg onclick"alert(1)">' is an invalid value", 4 => "", "id" => 1, "__STATUS__" => "Issue: Unexpected attribute value(s)", "__ERRORS__" => "Unexpected value for attribute 'status': no match found, check spelling"], ], ]; } /** * test $oBulk->Process with new server datas * @dataProvider CSVImportProvider * * @param $aInitData * @param $aCsvData * @param $aAttributes * @param $aExtKeys * @param $aReconcilKeys */ public function testCas1BulkChangeIssue($aInitData, $aCsvData, $aAttributes, $aExtKeys, $aReconcilKeys, $aResult) { CMDBSource::Query('START TRANSACTION'); //change value during the test $db_core_transactions_enabled=MetaModel::GetConfig()->Get('db_core_transactions_enabled'); MetaModel::GetConfig()->Set('db_core_transactions_enabled',false); if (is_array($aInitData) && sizeof($aInitData) != 0) { /** @var Server $oServer */ $oServer = $this->createObject('Server', array( 'name' => $aInitData[1], 'status' => $aInitData[2], 'org_id' => $aInitData[0], 'purchase_date' => $aInitData[3], )); $aCsvData[0][2]=$oServer->GetKey(); $aResult[2]=$oServer->GetKey(); $aResult["id"]=$oServer->GetKey(); $this->debug("oServer->GetKey():".$oServer->GetKey()); } $this->debug("aCsvData:".json_encode($aCsvData[0])); $this->debug("aReconcilKeys:".$aReconcilKeys[0]); $oBulk = new \BulkChange( "Server", $aCsvData, $aAttributes, $aExtKeys, $aReconcilKeys, null, null, "Y-m-d H:i:s", // date format true // localize ); $this->debug("BulkChange:"); $oChange = \CMDBObject::GetCurrentChange(); $this->debug("GetCurrentChange:"); $aRes = $oBulk->Process($oChange); $this->debug("Process:"); static::assertNotNull($aRes); $this->debug("assertNotNull:"); foreach ($aRes as $aRow) { if (array_key_exists('__STATUS__', $aRow)) { $sStatus = $aRow['__STATUS__']; $this->debug("sStatus:".$sStatus->GetDescription()); $this->assertEquals($aResult["__STATUS__"], $sStatus->GetDescription()); foreach ($aRow as $i => $oCell) { if ($i != "finalclass" && $i != "__STATUS__" && $i != "__ERRORS__") { $this->debug("i:".$i); $this->debug('GetDisplayableValue:'.$oCell->GetDisplayableValue()); $this->debug("aResult:".$aResult[$i]); $this->assertEquals( $aResult[$i], $oCell->GetDisplayableValue(), "failure on " . get_class($oCell) . ' cell type'); } else if ($i === "__ERRORS__") { $sErrors = array_key_exists("__ERRORS__", $aResult) ? $aResult["__ERRORS__"] : ""; $this->assertEquals( $sErrors, $oCell->GetDescription()); } } $this->assertEquals( $aResult[0], $aRow[0]->GetDisplayableValue()); } } CMDBSource::Query('ROLLBACK'); MetaModel::GetConfig()->Set('db_core_transactions_enabled',$db_core_transactions_enabled); } public function CSVImportProvider() { return [ "Case 6 - 1 : Unexpected value (update)" => [ ["1", "ServerTest", "production", ""], [["Demo", "ServerTest", "key", "BadValue", ""]], ["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4], ["org_id" => ["name" => 0]], ["id"], [ 0 => "Demo", "org_id" => "3", 1 => "ServerTest", 2 => "1", 3 => "'BadValue' is an invalid value", 4 => "", "id" => 1, "__STATUS__" => "Issue: Unexpected attribute value(s)", "__ERRORS__" => "Allowed 'status' value(s): implementation,obsolete,production,stock", ], ], "Case 6 - 2 : Unexpected value (update)" => [ ["1", "ServerTest", "production", ""], [["Demo", "ServerTest", "key", "", ""]], ["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4], ["org_id" => ["name" => 0]], ["id"], [ 0 => "Demo", "org_id" => "3", 1 => "ServerTest", 2 => "1", 3 => "'<svg onclick"alert(1)">' is an invalid value", 4 => "", "id" => 1, "__STATUS__" => "Issue: Unexpected attribute value(s)", "__ERRORS__" => "Allowed 'status' value(s): implementation,obsolete,production,stock", ], ], "Case 6 - 3 : Unexpected value (creation)" => [ [], [["Demo", "ServerTest", "", ""]], ["name" => 1, "status" => 2, "purchase_date" => 3], ["org_id" => ["name" => 0]], ["name"], [ 0 => "Demo", "org_id" => "3", 1 => "\"ServerTest\"", 2 => "'<svg onclick"alert(1)">' is an invalid value", 3 => "", "id" => 1, "__STATUS__" => "Issue: Unexpected attribute value(s)", "__ERRORS__" => "Allowed 'status' value(s): implementation,obsolete,production,stock", ], ], "Case 8 : unchanged name" => [ ["1", "", "production", ""], [["Demo", "", "key", "production", ""]], ["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4], ["org_id" => ["name" => 0]], ["id"], [0 => "Demo", "org_id" => "3", 1 => "<svg onclick"alert(1)">", 2 => "1", 3 => "production", 4 => "", "id" => 1, "__STATUS__" => "updated 1 cols"], ], "Case 3, 5 et 8 : unchanged 2" => [ ["1", "ServerTest", "production", ""], [["Demo", "ServerTest", "1", "production", ""]], ["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4], ["org_id" => ["name" => 0]], ["id"], [0 => "Demo", "org_id" => "3", 1 => "ServerTest", 2 => "1", 3 => "production", 4 => "", "id" => 1, "__STATUS__" => "updated 1 cols"], ], "Case 9 - 1: wrong date format" => [ ["1", "ServerTest", "production", ""], [["Demo", "ServerTest", "1", "production", "date"]], ["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4], ["org_id" => ["name" => 0]], ["id"], [ 0 => "Demo", "org_id" => "n/a", 1 => "ServerTest", 2 => "1", 3 => "production", 4 => "'date' is an invalid value", "id" => 1, "__STATUS__" => "Issue: wrong date format"], ], "Case 9 - 2: wrong date format" => [ ["1", "ServerTest", "production", ""], [["Demo", "ServerTest", "1", "production", ""]], ["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4], ["org_id" => ["name" => 0]], ["id"], [ 0 => "Demo", "org_id" => "n/a", 1 => "ServerTest", 2 => "1", 3 => "production", 4 => "'<svg onclick"alert(1)">' is an invalid value", "id" => 1, "__STATUS__" => "Issue: wrong date format"], ], "Case 1 - 1 : no match" => [ ["1", "ServerTest", "production", ""], [["Bad", "ServerTest", "1", "production", ""]], ["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4], ["org_id" => ["name" => 0]], ["id"], [ 0 => "Bad", "org_id" => "No match for value 'Bad'",1 => "ServerTest",2 => "1", 3 => "production", 4 => "", "id" => 1, "__STATUS__" => "Issue: Unexpected attribute value(s)", "__ERRORS__" => "Object not found", ], ], "Case 1 - 2 : no match" => [ ["1", "ServerTest", "production", ""], [["", "ServerTest", "1", "production", ""]], ["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4], ["org_id" => ["name" => 0]], ["id"], [ 0 => "<svg fonclick"alert(1)">", "org_id" => "No match for value ''",1 => "ServerTest",2 => "1", 3 => "production", 4 => "", "id" => 1, "__STATUS__" => "Issue: Unexpected attribute value(s)", "__ERRORS__" => "Object not found", ], ], "Case 10 : Missing mandatory value" => [ ["1", "ServerTest", "production", ""], [["", "ServerTest", "1", "production", ""]], ["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4], ["org_id" => ["name" => 0]], ["id"], [ 0 => "", "org_id" => "invalid value for attribute", 1 => "ServerTest", 2 => "1", 3 => "production", 4 => "", "id" => 1, "__STATUS__" => "Issue: Unexpected attribute value(s)", "__ERRORS__" => "Null not allowed", ], ], "Case 0 : Date format" => [ ["1", "ServerTest", "production", "2020-02-01"], [["Demo", "ServerTest", "1", "production", "2020-20-03"]], ["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4], ["org_id" => ["name" => 0]], ["id"], [ 0 => "Demo", "org_id" => "n/a", 1 => "ServerTest", 2 => "1", 3 => "production", 4 => "'2020-20-03' is an invalid value", "id" => 1, "__STATUS__" => "Issue: wrong date format"], ], ]; } /** * test $oBulk->Process with new server and new organization datas * @dataProvider CSVImportProvider2 * * @param $aInitData * @param $aCsvData * @param $aAttributes * @param $aExtKeys * @param $aReconcilKeys */ public function testCas2BulkChangeIssue($aInitData, $aCsvData, $aAttributes, $aExtKeys, $aReconcilKeys, $aResult) { CMDBSource::Query('START TRANSACTION'); //change value during the test $db_core_transactions_enabled=MetaModel::GetConfig()->Get('db_core_transactions_enabled'); MetaModel::GetConfig()->Set('db_core_transactions_enabled',false); if (is_array($aInitData) && sizeof($aInitData) != 0) { /** @var Server $oServer */ $oOrganisation = $this->createObject('Organization', array( 'name' => $aInitData[0] )); $aResult["org_id"] = $oOrganisation->GetKey(); $oServer = $this->createObject('Server', array( 'name' => $aInitData[1], 'status' => $aInitData[2], 'org_id' => $oOrganisation->GetKey(), 'purchase_date' => $aInitData[3], )); $aCsvData[0][2]=$oServer->GetKey(); $aResult[2]=$oServer->GetKey(); $aResult["id"]=$oServer->GetKey(); } $oBulk = new \BulkChange( "Server", $aCsvData, $aAttributes, $aExtKeys, $aReconcilKeys, null, null, "Y-m-d H:i:s", // date format true // localize ); $oChange = \CMDBObject::GetCurrentChange(); $aRes = $oBulk->Process($oChange); static::assertNotNull($aRes); foreach ($aRes as $aRow) { foreach ($aRow as $i => $oCell) { if ($i != "finalclass" && $i != "__STATUS__" && $i != "__ERRORS__") { $this->debug("i:".$i); $this->debug('GetDisplayableValue:'.$oCell->GetDisplayableValue()); $this->debug("aResult:".$aResult[$i]); $this->assertEquals($aResult[$i], $oCell->GetDisplayableValue()); } elseif ($i == "__STATUS__") { $sStatus = $aRow['__STATUS__']; $this->assertEquals($aResult["__STATUS__"], $sStatus->GetDescription()); } else if ($i === "__ERRORS__") { $sErrors = array_key_exists("__ERRORS__", $aResult) ? $aResult["__ERRORS__"] : ""; $this->assertEquals( $sErrors, $oCell->GetDescription()); } } $this->assertEquals($aResult[0], $aRow[0]->GetDisplayableValue()); } CMDBSource::Query('ROLLBACK'); MetaModel::GetConfig()->Set('db_core_transactions_enabled',$db_core_transactions_enabled); } public function CSVImportProvider2() { return [ "Case 3 : unchanged name" => [ ["dodo","ServerYO", "production", ""], [["dodo", "ServerYO", "key", "production", ""]], ["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4], ["org_id" => ["name" => 0]], ["id"], [0 => "dodo", "org_id" => "3", 1 => "ServerYO", 2 => "1", 3 => "production", 4 => "", "id" => 1, "__STATUS__" => "unchanged"], ], "Case 3 bis : unchanged name" => [ ["","ServerYO", "production", ""], [["", "ServerYO", "key", "production", ""]], ["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4], ["org_id" => ["name" => 0]], ["id"], [0 => "<svg >", "org_id" => "3", 1 => "ServerYO", 2 => "1", 3 => "production", 4 => "", "id" => 1, "__STATUS__" => "unchanged"], ], "Case 3 ter : unchanged name" => [ ["","ServerYO", "production", ""], [["", "ServerYO", "key", "production", ""]], ["name" => 1, "id" => 2, "status" => 3, "purchase_date" => 4], ["org_id" => ["name" => 0]], ["id"], [0 => "<svg onclick"alert(1)" >", "org_id" => "3", 1 => "ServerYO", 2 => "1", 3 => "production", 4 => "", "id" => 1, "__STATUS__" => "unchanged"], ], ]; } }