CreateTestOrganization();
$oRestProfile = MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", ['name' => 'REST Services User'], true);
$oAdminProfile = MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", ['name' => 'Administrator'], true);
if (is_object($oRestProfile) && is_object($oAdminProfile)) {
$oUser = $this->CreateUser(static::$sLogin, $oRestProfile->GetKey(), static::$sPassword);
$this->AddProfileToUser($oUser, $oAdminProfile->GetKey());
}
}
public function testListOperationsAndJSONPCallback()
{
$sCallbackName = 'fooCallback';
$sJsonData = '{"operation": "list_operations"}';
// Test regular JSON result
$sJSONResult = $this->CallRestApi_HTTP($sJsonData);
// - Try to decode JSON to array to check if it is well-formed
$aJSONResultAsArray = json_decode($sJSONResult, true);
$this->assertArrayHasKey('version', $aJSONResultAsArray);
$this->assertArrayHasKey('operations', $aJSONResultAsArray);
$this->assertArrayHasKey('code', $aJSONResultAsArray);
$this->assertArrayHasKey('message', $aJSONResultAsArray);
$this->assertEquals(0, $aJSONResultAsArray['code']);
$this->assertTrue(count($aJSONResultAsArray['operations']) >= 7, 'Expecting at least 7 operations from Core Services');
foreach ($aJSONResultAsArray['operations'] as $aOperationData) {
$this->assertCount(3, $aOperationData);
$this->assertArrayHasKey('verb', $aOperationData);
$this->assertArrayHasKey('description', $aOperationData);
$this->assertArrayHasKey('extension', $aOperationData);
$this->assertNotEmpty($aOperationData['verb']);
}
// Test JSONP with callback by checking that it is the same as the regular JSON but within the JS callback
$sJSONPResult = $this->CallRestApi_HTTP($sJsonData, $sCallbackName);
$this->assertEquals($sCallbackName.'('.$sJSONResult.');', $sJSONPResult, 'JSONP response callback does not match expected result');
}
public function testMissingJSONData()
{
$sOutputJson = $this->CallRestApi_HTTP();
$aJson = json_decode($sOutputJson, true);
$this->assertEquals(3, $aJson['code'], $sOutputJson);
$this->assertEquals("Error: Missing parameter 'json_data'", $aJson['message'], $sOutputJson);
}
public function testPostJSONDataAsCurlFile()
{
$sJsonData = '{"operation": "list_operations"}';
// Test regular JSON result
$sJSONResult = $this->CallRestApi_HTTP($sJsonData, null, true);
$aJSONResultAsArray = json_decode($sJSONResult, true);
$this->assertEquals(0, $aJSONResultAsArray['code'], $sJSONResult);
}
public function testCoreApiGet()
{
// Create ticket
$description = date('dmY H:i:s');
$oTicket = $this->CreateSampleTicket($description);
$iId = $oTicket->GetKey();
$sJSONOutput = $this->CallCoreRestApi_Internally(<<$description
",
"id": "$iId"
},
"key": "$iId",
"message": ""
}
}
}
JSON;
$this->assertJsonStringEqualsJsonString($sExpectedJsonOuput, $sJSONOutput);
}
public function testCoreApiCreate()
{
// Create ticket
$description = date('dmY H:i:s');
$sOutputJson = $this->CallCoreRestApi_Internally(<<debug("Output: '$sOutputJson'");
$aJson = json_decode($sOutputJson, true);
$this->assertNotNull($aJson, "Cannot decode returned JSON : $sOutputJson");
$this->assertStringContainsString("0", "".$aJson['code'], $sOutputJson);
$sUserRequestKey = $this->array_key_first($aJson['objects']);
$this->assertStringContainsString('UserRequest::', $sUserRequestKey);
$iId = $aJson['objects'][$sUserRequestKey]['key'];
$sExpectedJsonOuput = <<assertJsonStringEqualsJsonString($sExpectedJsonOuput, $sOutputJson);
$oObject = MetaModel::GetObject('UserRequest', $iId, false, true);
$this->assertIsObject($oObject, "Object UserRequest::$iId not present in the database");
$this->assertSame("$description
", $oObject->Get('description'));
$this->assertDBChangeOpCount('UserRequest', $iId, 1);
// Delete ticket
$oObject->DBDelete();
}
/**
* array_key_first comes with PHP7.3
* itop should also work with previous PHP versions
*/
private function array_key_first($aTab)
{
if (!is_array($aTab) || empty($aTab)) {
return false;
}
foreach ($aTab as $sKey => $sVal) {
return $sKey;
}
}
public function testCoreApiUpdate()
{
//create ticket
$description = date('dmY H:i:s');
$oTicket = $this->CreateSampleTicket($description);
$iId = $oTicket->GetKey();
// Update ticket
$description = 'Update to '.date('Ymd H:i:s');
$sJSONOutput = $this->CallCoreRestApi_Internally(<<$description<\/p>"}}},"code":0,"message":null}
JSON;
$this->assertJsonStringEqualsJsonString($sExpectedJsonOuput, $sJSONOutput);
$this->assertDBChangeOpCount('UserRequest', $iId, 2);
}
public function testCoreApiDelete()
{
// Create ticket
$description = date('dmY H:i:s');
$oTicket = $this->CreateSampleTicket($description);
$iId = $oTicket->GetKey();
// Delete ticket
$sJSONOutput = $this->CallCoreRestApi_Internally(<<assertStringContainsString($sExpectedJsonOuput, $sJSONOutput);
$oObject = MetaModel::GetObject('UserRequest', $iId, false, true);
$this->assertSame(null, $oObject, "Object UserRequest::$iId still present in the database");
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Helpers
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private function CreateSampleTicket($description)
{
$oTicket = $this->createObject('UserRequest', [
'org_id' => $this->getTestOrgId(),
"title" => "Houston, got a problem",
"description" => $description,
]);
return $oTicket;
}
/**
* @param string|null $sJsonDataContent If null, then no data is posted and the service should reply with an error
* @param string|null $sCallbackName JSONP callback
* @param bool $bJSONDataAsFile Set to true to test with the data provided to curl as a file
*
* @return bool|string
*/
private function CallRestApi_HTTP(string $sJsonDataContent = null, string $sCallbackName = null, bool $bJSONDataAsFile = false)
{
$ch = curl_init();
$aPostFields = [
'version' => '1.3',
'auth_user' => static::$sLogin,
'auth_pwd' => static::$sPassword,
];
$sTmpFile = null;
if (!is_null($sJsonDataContent)) {
if ($bJSONDataAsFile) {
$sTmpFile = tempnam(sys_get_temp_dir(), 'jsondata_');
file_put_contents($sTmpFile, $sJsonDataContent);
$oCurlFile = curl_file_create($sTmpFile);
$aPostFields['json_data'] = $oCurlFile;
} else {
$aPostFields['json_data'] = $sJsonDataContent;
}
}
if (utils::IsNotNullOrEmptyString($sCallbackName)) {
$aPostFields['callback'] = $sCallbackName;
}
$sJson = $this->CallItopUri('webservices/rest.php', $aPostFields);
if (!is_null($sTmpFile)) {
unlink($sTmpFile);
}
return $sJson;
}
private function CallCoreRestApi_Internally(string $sJsonDataContent)
{
$oJsonData = json_decode($sJsonDataContent);
$sOperation = $oJsonData->operation;
//\UserRights::Login(static::$sLogin);
\CMDBObject::SetTrackOrigin('webservice-rest');
\CMDBObject::SetTrackInfo('test');
$oRestSP = new \CoreServices();
$oResult = $oRestSP->ExecOperation('1.3', $sOperation, $oJsonData);
//\UserRights::Logoff();
return json_encode($oResult);
}
}