mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-24 19:18:44 +02:00
N°7385 - Trigger on mention executed even if it's not a mention with @ (#638)
This commit is contained in:
@@ -521,7 +521,7 @@ class utils
|
|||||||
|
|
||||||
// For URL
|
// For URL
|
||||||
case static::ENUM_SANITIZATION_FILTER_URL:
|
case static::ENUM_SANITIZATION_FILTER_URL:
|
||||||
// N°6350 - returns only valid URLs
|
// N°6350 - returns only valid URLs
|
||||||
$retValue = filter_var($value, FILTER_VALIDATE_URL);
|
$retValue = filter_var($value, FILTER_VALIDATE_URL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -554,44 +554,44 @@ class utils
|
|||||||
switch($sError)
|
switch($sError)
|
||||||
{
|
{
|
||||||
case UPLOAD_ERR_OK:
|
case UPLOAD_ERR_OK:
|
||||||
$sTmpName = is_null($sIndex) ? $aFileInfo['tmp_name'] : $aFileInfo['tmp_name'][$sIndex];
|
$sTmpName = is_null($sIndex) ? $aFileInfo['tmp_name'] : $aFileInfo['tmp_name'][$sIndex];
|
||||||
$sMimeType = is_null($sIndex) ? $aFileInfo['type'] : $aFileInfo['type'][$sIndex];
|
$sMimeType = is_null($sIndex) ? $aFileInfo['type'] : $aFileInfo['type'][$sIndex];
|
||||||
$sName = is_null($sIndex) ? $aFileInfo['name'] : $aFileInfo['name'][$sIndex];
|
$sName = is_null($sIndex) ? $aFileInfo['name'] : $aFileInfo['name'][$sIndex];
|
||||||
|
|
||||||
$doc_content = file_get_contents($sTmpName);
|
$doc_content = file_get_contents($sTmpName);
|
||||||
$sMimeType = self::GetFileMimeType($sTmpName);
|
$sMimeType = self::GetFileMimeType($sTmpName);
|
||||||
$oDocument = new ormDocument($doc_content, $sMimeType, $sName);
|
$oDocument = new ormDocument($doc_content, $sMimeType, $sName);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UPLOAD_ERR_NO_FILE:
|
case UPLOAD_ERR_NO_FILE:
|
||||||
// no file to load, it's a normal case, just return an empty document
|
// no file to load, it's a normal case, just return an empty document
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UPLOAD_ERR_FORM_SIZE:
|
case UPLOAD_ERR_FORM_SIZE:
|
||||||
case UPLOAD_ERR_INI_SIZE:
|
case UPLOAD_ERR_INI_SIZE:
|
||||||
throw new FileUploadException(Dict::Format('UI:Error:UploadedFileTooBig', ini_get('upload_max_filesize')));
|
throw new FileUploadException(Dict::Format('UI:Error:UploadedFileTooBig', ini_get('upload_max_filesize')));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UPLOAD_ERR_PARTIAL:
|
case UPLOAD_ERR_PARTIAL:
|
||||||
throw new FileUploadException(Dict::S('UI:Error:UploadedFileTruncated.'));
|
throw new FileUploadException(Dict::S('UI:Error:UploadedFileTruncated.'));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UPLOAD_ERR_NO_TMP_DIR:
|
case UPLOAD_ERR_NO_TMP_DIR:
|
||||||
throw new FileUploadException(Dict::S('UI:Error:NoTmpDir'));
|
throw new FileUploadException(Dict::S('UI:Error:NoTmpDir'));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UPLOAD_ERR_CANT_WRITE:
|
case UPLOAD_ERR_CANT_WRITE:
|
||||||
throw new FileUploadException(Dict::Format('UI:Error:CannotWriteToTmp_Dir', ini_get('upload_tmp_dir')));
|
throw new FileUploadException(Dict::Format('UI:Error:CannotWriteToTmp_Dir', ini_get('upload_tmp_dir')));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UPLOAD_ERR_EXTENSION:
|
case UPLOAD_ERR_EXTENSION:
|
||||||
$sName = is_null($sIndex) ? $aFileInfo['name'] : $aFileInfo['name'][$sIndex];
|
$sName = is_null($sIndex) ? $aFileInfo['name'] : $aFileInfo['name'][$sIndex];
|
||||||
throw new FileUploadException(Dict::Format('UI:Error:UploadStoppedByExtension_FileName', $sName));
|
throw new FileUploadException(Dict::Format('UI:Error:UploadStoppedByExtension_FileName', $sName));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new FileUploadException(Dict::Format('UI:Error:UploadFailedUnknownCause_Code', $sError));
|
throw new FileUploadException(Dict::Format('UI:Error:UploadFailedUnknownCause_Code', $sError));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -889,10 +889,10 @@ class utils
|
|||||||
$aDateRegexps = array_values($aSpec);
|
$aDateRegexps = array_values($aSpec);
|
||||||
}
|
}
|
||||||
|
|
||||||
$sDateRegexp = str_replace($aDateTokens, $aDateRegexps, $sFormat);
|
$sDateRegexp = str_replace($aDateTokens, $aDateRegexps, $sFormat);
|
||||||
|
|
||||||
if (preg_match('!^(?<head>)'.$sDateRegexp.'(?<tail>)$!', $sDate, $aMatches))
|
if (preg_match('!^(?<head>)'.$sDateRegexp.'(?<tail>)$!', $sDate, $aMatches))
|
||||||
{
|
{
|
||||||
$sYear = isset($aMatches['year']) ? $aMatches['year'] : 0;
|
$sYear = isset($aMatches['year']) ? $aMatches['year'] : 0;
|
||||||
$sMonth = isset($aMatches['month']) ? $aMatches['month'] : 1;
|
$sMonth = isset($aMatches['month']) ? $aMatches['month'] : 1;
|
||||||
$sDay = isset($aMatches['day']) ? $aMatches['day'] : 1;
|
$sDay = isset($aMatches['day']) ? $aMatches['day'] : 1;
|
||||||
@@ -901,11 +901,11 @@ class utils
|
|||||||
$sSecond = isset($aMatches['second']) ? $aMatches['second'] : 0;
|
$sSecond = isset($aMatches['second']) ? $aMatches['second'] : 0;
|
||||||
return strtotime("$sYear-$sMonth-$sDay $sHour:$sMinute:$sSecond");
|
return strtotime("$sYear-$sMonth-$sDay $sHour:$sMinute:$sSecond");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// http://www.spaweditor.com/scripts/regex/index.php
|
// http://www.spaweditor.com/scripts/regex/index.php
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1334,8 +1334,8 @@ class utils
|
|||||||
return Session::GetLog();
|
return Session::GetLog();
|
||||||
}
|
}
|
||||||
|
|
||||||
static function DebugBacktrace($iLimit = 5)
|
static function DebugBacktrace($iLimit = 5)
|
||||||
{
|
{
|
||||||
$aFullTrace = debug_backtrace();
|
$aFullTrace = debug_backtrace();
|
||||||
$aLightTrace = array();
|
$aLightTrace = array();
|
||||||
for($i=1; ($i<=$iLimit && $i < count($aFullTrace)); $i++) // Skip the last function call... which is the call to this function !
|
for($i=1; ($i<=$iLimit && $i < count($aFullTrace)); $i++) // Skip the last function call... which is the call to this function !
|
||||||
@@ -1343,7 +1343,7 @@ class utils
|
|||||||
$aLightTrace[$i] = $aFullTrace[$i]['function'].'(), called from line '.$aFullTrace[$i]['line'].' in '.$aFullTrace[$i]['file'];
|
$aLightTrace[$i] = $aFullTrace[$i]['function'].'(), called from line '.$aFullTrace[$i]['line'].' in '.$aFullTrace[$i]['file'];
|
||||||
}
|
}
|
||||||
echo "<p><pre>".print_r($aLightTrace, true)."</pre></p>\n";
|
echo "<p><pre>".print_r($aLightTrace, true)."</pre></p>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the given iTop PHP script, passing it the current credentials
|
* Execute the given iTop PHP script, passing it the current credentials
|
||||||
@@ -1539,7 +1539,7 @@ class utils
|
|||||||
if (strlen($sUrl) < SERVER_MAX_URL_LENGTH) {
|
if (strlen($sUrl) < SERVER_MAX_URL_LENGTH) {
|
||||||
// Static menus: Email this page, CSV Export & Add to Dashboard
|
// Static menus: Email this page, CSV Export & Add to Dashboard
|
||||||
$aResult[] = new URLPopupMenuItem('UI:Menu:EMail', Dict::S('UI:Menu:EMail'),
|
$aResult[] = new URLPopupMenuItem('UI:Menu:EMail', Dict::S('UI:Menu:EMail'),
|
||||||
"mailto:?body=".urlencode($sUrl).' ' // Add an extra space to make it work in Outlook
|
"mailto:?body=".urlencode($sUrl).' ' // Add an extra space to make it work in Outlook
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1961,7 +1961,7 @@ SQL;
|
|||||||
CURLOPT_HTTPHEADER => $aHTTPHeaders,
|
CURLOPT_HTTPHEADER => $aHTTPHeaders,
|
||||||
);
|
);
|
||||||
|
|
||||||
$aAllOptions = $aCurlOptions + $aOptions;
|
$aAllOptions = $aCurlOptions + $aOptions;
|
||||||
$ch = curl_init($sUrl);
|
$ch = curl_init($sUrl);
|
||||||
curl_setopt_array($ch, $aAllOptions);
|
curl_setopt_array($ch, $aAllOptions);
|
||||||
$response = curl_exec($ch);
|
$response = curl_exec($ch);
|
||||||
@@ -1986,7 +1986,7 @@ SQL;
|
|||||||
/**
|
/**
|
||||||
* Get a standard list of character sets
|
* Get a standard list of character sets
|
||||||
*
|
*
|
||||||
* @param array $aAdditionalEncodings Additional values
|
* @param array $aAdditionalEncodings Additional values
|
||||||
* @return array of iconv code => english label, sorted by label
|
* @return array of iconv code => english label, sorted by label
|
||||||
*/
|
*/
|
||||||
public static function GetPossibleEncodings($aAdditionalEncodings = array())
|
public static function GetPossibleEncodings($aAdditionalEncodings = array())
|
||||||
@@ -2221,13 +2221,13 @@ SQL;
|
|||||||
case 'image/gif':
|
case 'image/gif':
|
||||||
case 'image/jpeg':
|
case 'image/jpeg':
|
||||||
case 'image/png':
|
case 'image/png':
|
||||||
$img = @imagecreatefromstring($oImage->GetData());
|
$img = @imagecreatefromstring($oImage->GetData());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Unsupported image type, return the image as-is
|
// Unsupported image type, return the image as-is
|
||||||
//throw new Exception("Unsupported image type: '".$oImage->GetMimeType()."'. Cannot resize the image, original image will be used.");
|
//throw new Exception("Unsupported image type: '".$oImage->GetMimeType()."'. Cannot resize the image, original image will be used.");
|
||||||
return $oImage;
|
return $oImage;
|
||||||
}
|
}
|
||||||
if ($img === false)
|
if ($img === false)
|
||||||
{
|
{
|
||||||
@@ -2259,16 +2259,16 @@ SQL;
|
|||||||
switch ($oImage->GetMimeType())
|
switch ($oImage->GetMimeType())
|
||||||
{
|
{
|
||||||
case 'image/gif':
|
case 'image/gif':
|
||||||
imagegif($new); // send image to output buffer
|
imagegif($new); // send image to output buffer
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'image/jpeg':
|
case 'image/jpeg':
|
||||||
imagejpeg($new, null, 80); // null = send image to output buffer, 80 = good quality
|
imagejpeg($new, null, 80); // null = send image to output buffer, 80 = good quality
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'image/png':
|
case 'image/png':
|
||||||
imagepng($new, null, 5); // null = send image to output buffer, 5 = medium compression
|
imagepng($new, null, 5); // null = send image to output buffer, 5 = medium compression
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
$oResampledImage = new ormDocument(ob_get_contents(), $oImage->GetMimeType(), $oImage->GetFileName());
|
$oResampledImage = new ormDocument(ob_get_contents(), $oImage->GetMimeType(), $oImage->GetFileName());
|
||||||
@ob_end_clean();
|
@ob_end_clean();
|
||||||
@@ -2298,16 +2298,16 @@ SQL;
|
|||||||
$data .= mt_rand();
|
$data .= mt_rand();
|
||||||
$hash = strtoupper(hash('ripemd128', $uid . md5($data)));
|
$hash = strtoupper(hash('ripemd128', $uid . md5($data)));
|
||||||
$sUUID = '{' .
|
$sUUID = '{' .
|
||||||
substr($hash, 0, 8) .
|
substr($hash, 0, 8) .
|
||||||
'-' .
|
'-' .
|
||||||
substr($hash, 8, 4) .
|
substr($hash, 8, 4) .
|
||||||
'-' .
|
'-' .
|
||||||
substr($hash, 12, 4) .
|
substr($hash, 12, 4) .
|
||||||
'-' .
|
'-' .
|
||||||
substr($hash, 16, 4) .
|
substr($hash, 16, 4) .
|
||||||
'-' .
|
'-' .
|
||||||
substr($hash, 20, 12) .
|
substr($hash, 20, 12) .
|
||||||
'}';
|
'}';
|
||||||
return $sUUID;
|
return $sUUID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2319,7 +2319,7 @@ SQL;
|
|||||||
*/
|
*/
|
||||||
public static function GetCurrentModuleName($iCallDepth = 0)
|
public static function GetCurrentModuleName($iCallDepth = 0)
|
||||||
{
|
{
|
||||||
return ModuleService::GetInstance()->GetCurrentModuleName($iCallDepth + 1);
|
return ModuleService::GetInstance()->GetCurrentModuleName($iCallDepth + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2366,7 +2366,7 @@ SQL;
|
|||||||
*/
|
*/
|
||||||
public static function GetCurrentModuleSetting($sProperty, $defaultvalue = null)
|
public static function GetCurrentModuleSetting($sProperty, $defaultvalue = null)
|
||||||
{
|
{
|
||||||
return ModuleService::GetInstance()->GetCurrentModuleSetting($sProperty, $defaultvalue);
|
return ModuleService::GetInstance()->GetCurrentModuleSetting($sProperty, $defaultvalue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2375,7 +2375,7 @@ SQL;
|
|||||||
*/
|
*/
|
||||||
public static function GetCompiledModuleVersion($sModuleName)
|
public static function GetCompiledModuleVersion($sModuleName)
|
||||||
{
|
{
|
||||||
return ModuleService::GetInstance()->GetCompiledModuleVersion($sModuleName);
|
return ModuleService::GetInstance()->GetCompiledModuleVersion($sModuleName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -3109,19 +3109,29 @@ TXT
|
|||||||
$aMentionMatches = [];
|
$aMentionMatches = [];
|
||||||
$sText = html_entity_decode($sText);
|
$sText = html_entity_decode($sText);
|
||||||
|
|
||||||
preg_match_all('/<a\s*([^>]*)data-object-class="([^"]*)"\s.*data-object-key="([^"]*)"/Ui', $sText, $aMentionMatches);
|
$aMentionAllowedClasses = MetaModel::GetConfig()->Get('mentions.allowed_classes');
|
||||||
|
preg_match_all('/<a\s*([^>]*)data-object-class="([^"]*)"\s.*data-object-key="([^"]*)"\s*([^>]*)>(.*)<\/a>/Ui', $sText, $aMentionMatches);
|
||||||
foreach ($aMentionMatches[0] as $iMatchIdx => $sCompleteMatch) {
|
foreach ($aMentionMatches[0] as $iMatchIdx => $sCompleteMatch) {
|
||||||
$sMatchedClass = $aMentionMatches[2][$iMatchIdx];
|
$sMatchedClass = $aMentionMatches[2][$iMatchIdx];
|
||||||
$sMatchedId = $aMentionMatches[3][$iMatchIdx];
|
$sMatchedId = $aMentionMatches[3][$iMatchIdx];
|
||||||
|
$sMatchedName = $aMentionMatches[5][$iMatchIdx];
|
||||||
|
|
||||||
// Prepare array for matched class if not already present
|
$sMentionPrefix = array_search($sMatchedClass, $aMentionAllowedClasses);
|
||||||
if (!array_key_exists($sMatchedClass, $aMentionedObjects)) {
|
if ($sMentionPrefix === false) {
|
||||||
$aMentionedObjects[$sMatchedClass] = array();
|
continue;
|
||||||
}
|
}
|
||||||
// Add matched ID if not already there
|
//tests if the name starts with $sMentionPrefix (e.g. '@' for 'Contact' class)
|
||||||
if (!in_array($sMatchedId, $aMentionedObjects[$sMatchedClass])) {
|
if (str_starts_with($sMatchedName, $sMentionPrefix) === false) {
|
||||||
$aMentionedObjects[$sMatchedClass][] = $sMatchedId;
|
continue;
|
||||||
}
|
}
|
||||||
|
// Prepare array for matched class if not already present
|
||||||
|
if (!array_key_exists($sMatchedClass, $aMentionedObjects)) {
|
||||||
|
$aMentionedObjects[$sMatchedClass] = array();
|
||||||
|
}
|
||||||
|
// Add matched ID if not already there
|
||||||
|
if (!in_array($sMatchedId, $aMentionedObjects[$sMatchedClass])) {
|
||||||
|
$aMentionedObjects[$sMatchedClass][] = $sMatchedId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $aMentionedObjects;
|
return $aMentionedObjects;
|
||||||
|
|||||||
@@ -521,14 +521,13 @@ abstract class ItopTestCase extends KernelTestCase
|
|||||||
sort($aActual);
|
sort($aActual);
|
||||||
sort($aExpected);
|
sort($aExpected);
|
||||||
|
|
||||||
$sExpected = implode("\n", $aExpected);
|
$sExpected = var_export($aExpected, true);
|
||||||
$sActual = implode("\n", $aActual);
|
$sActual = var_export($aActual, true);
|
||||||
if ($sExpected === $sActual) {
|
if ($sExpected === $sActual) {
|
||||||
$this->assertTrue(true);
|
$this->assertTrue(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$sMessage .= "\nExpected:\n$sExpected\nActual:\n$sActual";
|
$sMessage .= "\nExpected:\n$sExpected\nActual:\n$sActual";
|
||||||
var_export($aActual);
|
|
||||||
|
|
||||||
$this->fail($sMessage);
|
$this->fail($sMessage);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -645,66 +645,6 @@ class utilsTest extends ItopTestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @dataProvider GetMentionedObjectsFromTextProvider
|
|
||||||
* @covers utils::GetMentionedObjectsFromText
|
|
||||||
*
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
public function testGetMentionedObjectsFromText($sInput, $aExceptedMentionedObjects)
|
|
||||||
{
|
|
||||||
// Emulate the "Case provider mechanism" (reason: the data provider requires utils constants not available before the application startup)
|
|
||||||
echo "testGetMentionedObjectsFromText: input = $sInput\n";
|
|
||||||
$aTestedMentionedObjects = utils::GetMentionedObjectsFromText($sInput);
|
|
||||||
|
|
||||||
$sExpectedAsString = print_r($aExceptedMentionedObjects, true);
|
|
||||||
$sTestedAsString = print_r($aTestedMentionedObjects, true);
|
|
||||||
|
|
||||||
$this->assertEquals($sExpectedAsString, $sTestedAsString, "Found mentioned objects don't match. Got: $sTestedAsString, expected $sExpectedAsString");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @since 3.0.0
|
|
||||||
*/
|
|
||||||
public function GetMentionedObjectsFromTextProvider(): array
|
|
||||||
{
|
|
||||||
$sAbsUrlAppRoot = utils::GetAbsoluteUrlAppRoot();
|
|
||||||
|
|
||||||
return [
|
|
||||||
'No object' => [
|
|
||||||
"Begining
|
|
||||||
Second line
|
|
||||||
End",
|
|
||||||
[],
|
|
||||||
],
|
|
||||||
'1 UserRequest' => [
|
|
||||||
<<<HTML
|
|
||||||
<p>Beginning</p><p>Before link <a data-role="object-mention" data-object-class="UserRequest" data-object-key="12345" data-object-id="#Test Ticket" href="$sAbsUrlAppRoot/pages/UI.php?operation=details&class=UserRequest&id=12345">#Test Ticket</a>After link</p><p>End</p>
|
|
||||||
HTML,
|
|
||||||
[
|
|
||||||
'UserRequest' => ['12345'],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
'2 UserRequests' => [
|
|
||||||
<<<HTML
|
|
||||||
<div class="ibo-activity-entry--main-information-content"><p>Beginning</p><p>Before link <a data-role="object-mention" data-object-class="UserRequest" data-object-key="12345" data-object-id="#Test Ticket 1" href="$sAbsUrlAppRoot/pages/UI.php?operation=details&class=UserRequest&id=12345">#Test Ticket</a> After link</p><p>And <a data-role="object-mention" data-object-class="UserRequest" data-object-key="987654" data-object-id="#Test Ticket 2" href="$sAbsUrlAppRoot/pages/UI.php?operation=details&class=UserRequest&id=987654">#Test Ticket</a></p><p>End</p></div>
|
|
||||||
HTML,
|
|
||||||
[
|
|
||||||
'UserRequest' => ['12345', '987654'],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
'1 UserRequest, 1 Person' => [
|
|
||||||
<<<HTML
|
|
||||||
<div class="ibo-activity-entry--main-information-content"><div class="ibo-activity-entry--main-information-content"><p>Beginning</p><p>Before link <a data-role="object-mention" data-object-class="UserRequest" data-object-key="12345" data-object-id="#Test Ticket" href="$sAbsUrlAppRoot/pages/UI.php?operation=details&class=UserRequest&id=12345">#Test Ticket</a> After link</p><p>And <a data-role="object-mention" data-object-class="Person" data-object-id="@Agatha Christie" data-object-key="3" data-object-id="@Agatha Christie" href="$sAbsUrlAppRoot/pages/UI.php?operation=details&class=Person&id=3">@Agatha Christie</a></p><p>End</p></div></div>
|
|
||||||
HTML,
|
|
||||||
[
|
|
||||||
'UserRequest' => ['12345'],
|
|
||||||
'Person' => ['3'],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider FormatInitialsForMedallionProvider
|
* @dataProvider FormatInitialsForMedallionProvider
|
||||||
* @covers utils::FormatInitialsForMedallion
|
* @covers utils::FormatInitialsForMedallion
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* @copyright Copyright (C) 2010-2025 Combodo SAS
|
||||||
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Combodo\iTop\Test\UnitTest\Application;
|
||||||
|
|
||||||
|
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||||
|
use MetaModel;
|
||||||
|
use utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers utils
|
||||||
|
*/
|
||||||
|
class utilsTestWithDataModel extends ItopDataTestCase
|
||||||
|
{
|
||||||
|
const USE_TRANSACTION = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider GetMentionedObjectsFromTextProvider
|
||||||
|
* @covers utils::GetMentionedObjectsFromText
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function testGetMentionedObjectsFromText($sInput, $aExceptedMentionedObjects)
|
||||||
|
{
|
||||||
|
MetaModel::GetConfig()->Set('mentions.allowed_classes', ['@' => 'Person', '😊#' => 'Team']);
|
||||||
|
// Emulate the "Case provider mechanism" (reason: the data provider requires utils constants not available before the application startup)
|
||||||
|
$aTestedMentionedObjects = utils::GetMentionedObjectsFromText($sInput);
|
||||||
|
|
||||||
|
$this->AssertArraysHaveSameItems($aExceptedMentionedObjects, $aTestedMentionedObjects);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public function GetMentionedObjectsFromTextProvider(): array
|
||||||
|
{
|
||||||
|
$sAbsUrlAppRoot = 'https://myitop.com/itop/';
|
||||||
|
|
||||||
|
return [
|
||||||
|
'No object' => [
|
||||||
|
"Begining
|
||||||
|
Second line
|
||||||
|
End",
|
||||||
|
[],
|
||||||
|
],
|
||||||
|
'1 Object' => [
|
||||||
|
<<<HTML
|
||||||
|
<p>Beginning</p><p>Before link <a data-role="object-mention" data-object-class="Person" data-object-key="12345" data-object-id="#Test Person" href="$sAbsUrlAppRoot/pages/UI.php?operation=details&class=Person&id=12345">@Test Person</a>After link</p><p>End</p>
|
||||||
|
HTML,
|
||||||
|
[
|
||||||
|
'Person' => ['12345'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'Should not match 1 Object if the mention prefix is missing' => [
|
||||||
|
<<<HTML
|
||||||
|
<div class="ibo-activity-entry--main-information-content"><p>Beginning</p><p>Before link <a data-role="object-mention" data-object-class="Person" data-object-key="12345" data-object-id="#Test Person 1" href="$sAbsUrlAppRoot/pages/UI.php?operation=details&class=Person&id=12345">#Test Ticket</a> After link</p></div>
|
||||||
|
HTML,
|
||||||
|
[],
|
||||||
|
],
|
||||||
|
'Should return 2 Objects' => [
|
||||||
|
<<<HTML
|
||||||
|
<div class="ibo-activity-entry--main-information-content"><div class="ibo-activity-entry--main-information-content"><p>Beginning</p><p>Before link <a data-role="object-mention" data-object-class="Person" data-object-key="12345" data-object-id="#Test Person" href="$sAbsUrlAppRoot/pages/UI.php?operation=details&class=UserRequest&id=12345">@Test Person</a> After link</p><p>And <a data-role="object-mention" data-object-class="Person" data-object-id="@Agatha Christie" data-object-key="3" data-object-id="@Agatha Christie" href="$sAbsUrlAppRoot/pages/UI.php?operation=details&class=Person&id=3">@Agatha Christie</a></p><p>End</p></div></div>
|
||||||
|
HTML,
|
||||||
|
[
|
||||||
|
'Person' => ['12345', '3'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'Should process objects of different classes' => [
|
||||||
|
<<<HTML
|
||||||
|
Begining
|
||||||
|
Before link <a data-object-class="Team" data-object-key="12345" href=\"$sAbsUrlAppRoot/pages/UI.php&operation=details&class=Team&id=12345&foo=bar\">😊#R-012345</a> After link
|
||||||
|
And <a data-object-class="Person" data-object-key="3" href=\"$sAbsUrlAppRoot/pages/UI.php&operation=details&class=Person&id=3&foo=bar\">@Claude Monet</a>
|
||||||
|
End
|
||||||
|
HTML,
|
||||||
|
[
|
||||||
|
'Team' => ['12345'],
|
||||||
|
'Person' => ['3'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user