diff --git a/core/attributedef.class.inc.php b/core/attributedef.class.inc.php
index 57681870e..983c60b70 100644
--- a/core/attributedef.class.inc.php
+++ b/core/attributedef.class.inc.php
@@ -11315,6 +11315,10 @@ class AttributeEnumSet extends AttributeSet
}
return $aValues;
}
+ public function Equals($val1, $val2)
+ {
+ return $val1->Equals($val2);
+ }
}
diff --git a/core/ormset.class.inc.php b/core/ormset.class.inc.php
index 71d0f8914..139207c78 100644
--- a/core/ormset.class.inc.php
+++ b/core/ormset.class.inc.php
@@ -385,7 +385,7 @@ class ormSet
*/
public function Equals(ormSet $other)
{
- return implode(', ', $this->GetValue()) === implode(', ', $other->GetValue());
+ return implode(', ', $this->GetValues()) === implode(', ', $other->GetValues());
}
/**
diff --git a/tests/php-unit-tests/unitary-tests/core/querybuilderexpressions/Delta/all-attributes.xml b/tests/php-unit-tests/unitary-tests/core/querybuilderexpressions/Delta/all-attributes.xml
new file mode 100644
index 000000000..994618cfe
--- /dev/null
+++ b/tests/php-unit-tests/unitary-tests/core/querybuilderexpressions/Delta/all-attributes.xml
@@ -0,0 +1,608 @@
+
+
+
+
+ cmdbAbstractObject
+
+ bizmodel,searchable
+ true
+ testabstract
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ name
+
+ false
+
+ all
+
+
+
+ open
+ terminated
+
+ meta_enum
+ open
+ all
+
+
+ status
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ TestAbstract
+
+ bizmodel,searchable
+ false
+ testobject
+
+
+
+
+
+
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org_id
+
+
+ false
+ Organization
+ DEL_AUTO
+ all
+
+
+ parent_id
+
+
+ true
+ DEL_AUTO
+ all
+
+
+ caselog
+
+ true
+ all
+
+
+ date
+ 2010-05-26
+ true
+ all
+
+
+ date_time
+ 2000-01-01 00:00:00
+ true
+ all
+
+
+ deadline
+ 2028-05-26 00:00:00
+ true
+ all
+
+
+ decimal
+ 1.01
+ false
+ 8
+ 2
+ all
+
+
+ duration
+ 180
+ false
+ all
+
+
+ email
+ test@combodo.com
+ false
+
+ all
+
+
+ encrypted
+ 1234pwd
+ false
+
+ all
+
+
+ password
+
+ false
+
+
+
+ onewaypassword
+
+ false
+
+
+
+ enum
+
+ yes
+ no
+
+ no
+ false
+ radio_horizontal
+
+ all
+
+
+ enumset
+
+
+ low
+
+
+ high
+
+
+ large
+
+
+ tall
+
+
+ thin
+
+
+ long
+
+
+ short
+
+
+ small
+
+
+ big
+
+
+ true
+
+ all
+
+
+ file
+ true
+
+
+ html
+
+ true
+
+
+ 200
+ all
+
+
+
+ true
+ 128
+ 128
+ 128
+ 128
+ all
+
+
+ integer
+ 7
+ false
+ all
+
+
+ ip_address
+ 15.28.255.1
+ false
+
+ all
+
+
+ percentage
+ 50
+ false
+
+ all
+
+
+ phone
+ +33 666333000
+ false
+
+ all
+
+
+ status
+
+ new
+ investigation
+ cancel
+ done
+
+ new
+ false
+
+
+ all
+
+
+
+ investigation
+
+
+
+ true
+ all
+
+
+ stopwatch
+ started
+
+
+ tagset
+ true
+
+
+ all
+
+
+ text
+
+ true
+
+
+ 30
+ all
+
+
+ long_text
+
+ true
+
+
+ 50
+ all
+
+
+ url
+ http://www.combodo.com
+ false
+
+ _blank
+ all
+
+
+ oql
+
+ true
+
+
+ boolean
+
+ true
+
+
+
+
+
+
+ TestAbstract
+
+ bizmodel,searchable
+ false
+ subobject
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+ true
+
+
+
+
+
+ testobject_id
+
+
+ false
+ TestObject
+ DEL_AUTO
+ all
+
+
+
+ testobject_id
+ name
+
+
+ testobject_id
+ meta_enum
+
+
+ testobject_id
+ org_id
+
+
+ testobject_id
+ parent_id
+
+
+ testobject_id
+ caselog
+
+
+ testobject_id
+ date
+
+
+ testobject_id
+ date_time
+
+
+ testobject_id
+ deadline
+
+
+ testobject_id
+ decimal
+
+
+ testobject_id
+ duration
+
+
+ testobject_id
+ email
+
+
+ testobject_id
+ encrypted
+
+
+ testobject_id
+ password
+
+
+ testobject_id
+ onewaypassword
+
+
+ testobject_id
+ enum
+
+
+ testobject_id
+ enumset
+
+
+ testobject_id
+ file
+
+
+ testobject_id
+ html
+
+
+ testobject_id
+ image
+
+
+ testobject_id
+ integer
+
+
+ testobject_id
+ ip_address
+
+
+ testobject_id
+ percentage
+
+
+ testobject_id
+ phone
+
+
+ testobject_id
+ status
+
+
+ testobject_id
+ stopwatch
+
+
+ testobject_id
+ stopwatch_started
+
+
+ testobject_id
+ tagset
+
+
+ testobject_id
+ text
+
+
+ testobject_id
+ long_text
+
+
+ testobject_id
+ url
+
+
+ testobject_id
+ oql
+
+
+ testobject_id
+ boolean
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/php-unit-tests/unitary-tests/core/querybuilderexpressions/QueryBuilderExpressionsTest.php b/tests/php-unit-tests/unitary-tests/core/querybuilderexpressions/QueryBuilderExpressionsTest.php
new file mode 100644
index 000000000..3f3af0e0e
--- /dev/null
+++ b/tests/php-unit-tests/unitary-tests/core/querybuilderexpressions/QueryBuilderExpressionsTest.php
@@ -0,0 +1,197 @@
+ 'tagA',
+ 'label' => 'Tag A',
+ 'description' => 'Tag known as "A"'
+ ]);
+ $oTagA->DBInsert();
+
+ $sTargetClass = 'TestObject';
+ $aValues = [
+ 'name' => [
+ 'value' => 'Tadam!',
+ 'type' => 'php:integer',
+ ],
+ 'org_id' => [
+ 'value' => $this->getTestOrgId(),
+ 'type' => 'php:integer',
+ ],
+ 'parent_id' => [
+ 'value' => 0,
+ 'type' => 'php:integer',
+ ],
+ 'caselog' => [
+ 'value' => '{"items":[{"message":"Hi folks!"}]}',
+ 'type' => 'ormCaseLog',
+ ],
+ 'date' => [
+ 'value' => '2023-10-04',
+ 'type' => 'php:string',
+ ],
+ 'date_time' => [
+ 'value' => '2023-10-04 17:11:54',
+ 'type' => 'php:string',
+ ],
+ 'deadline' => [
+ 'value' => '2023-10-04 17:11:54',
+ 'type' => 'php:string',
+ ],
+ 'decimal' => [
+ 'value' => '123456.78',
+ 'type' => 'php:string',
+ ],
+ 'duration' => [
+ 'value' => 3660, // One hour and one minute
+ 'type' => 'php:integer',
+ ],
+ 'email' => [
+ 'value' => 'john.foo@company.com',
+ 'type' => 'php:string',
+ ],
+ 'encrypted' => [
+ 'value' => 'secret...inDB!',
+ 'type' => 'php:string',
+ ],
+ 'password' => [
+ 'value' => 'abc123',
+ 'type' => 'php:string',
+ ],
+ 'onewaypassword' => [
+ 'value' => 'az"e(t-yè',
+ 'type' => 'php:string',
+ ],
+ 'enum' => [
+ 'value' => 'yes',
+ 'type' => 'php:string',
+ ],
+ 'enumset' => [
+ 'value' => 'low|high',
+ 'type' => 'php:string',
+ ],
+ 'file' => [
+ 'value' => '{"data":"blahblah","mimetype":"text/plain","filename":"trash.txt", "downloads_count":0}',
+ 'type' => 'ormDocument',
+ ],
+ 'html' => [
+ 'value' => '
Hello world!
',
+ 'type' => 'php:string',
+ ],
+ 'image' => [
+ 'value' => '{"data":"notanimage-sowhat?","mimetype":"image/png","filename":"trash.png", "downloads_count":0}',
+ 'type' => 'ormDocument',
+ ],
+ 'integer' => [
+ 'value' => 123,
+ 'type' => 'php:integer',
+ ],
+ 'ip_address' => [
+ 'value' => '192.158.1.38',
+ 'type' => 'php:string',
+ ],
+ 'percentage' => [
+ 'value' => 49.3,
+ 'type' => 'php:double',
+ ],
+ 'phone' => [
+ 'value' => '+33476123456',
+ 'type' => 'php:string',
+ ],
+ 'status' => [
+ 'value' => 'investigation',
+ 'type' => 'php:string',
+ ],
+ 'stopwatch' => [
+ 'value' => null,
+ 'type' => 'ormStopWatch',
+ ],
+ 'tagset' => [
+ 'value' => 'tagA',
+ 'type' => 'php:string',
+ ],
+ 'text' => [
+ 'value' => 'Hello world!',
+ 'type' => 'php:string',
+ ],
+ 'long_text' => [
+ 'value' => 'Hello world!',
+ 'type' => 'php:string',
+ ],
+ 'url' => [
+ 'value' => 'http://www.combodo.com/void',
+ 'type' => 'php:string',
+ ],
+ 'oql' => [
+ 'value' => 'SELECT Organization',
+ 'type' => 'php:string',
+ ],
+ 'boolean' => [
+ 'value' => true,
+ 'type' => 'php:boolean',
+ ],
+ ];
+
+ $aValuesToSet = [];
+ foreach ($aValues as $sAttCode => $aValueData) {
+ if (substr($aValueData['type'], 0, 4) == 'php:') {
+ $aValuesToSet[$sAttCode] = $aValueData['value'];
+ } else {
+ $oAttDef = \MetaModel::GetAttributeDef($sTargetClass, $sAttCode);
+ $oJSONObject = is_null($aValueData['value']) ? null : json_decode($aValueData['value'], false);
+ $aValuesToSet[$sAttCode] = $oAttDef->FromJSONToValue($oJSONObject);
+ }
+ }
+
+
+ // Test that I can write without any error (such as malformed SQL query, that would throw an exception)
+ $oObject = \MetaModel::NewObject($sTargetClass, $aValuesToSet);
+ $oObject->DBInsert();
+
+ // Test that I can read without any error (such as malformed SQL query, that would throw an exception)
+ $iTestObject = $oObject->GetKey();
+ $oObjectFromDB = \MetaModel::GetObject($sTargetClass, $iTestObject);
+
+ // Test that each value matches the original value
+ foreach ($aValues as $sAttCode => $aValueData) {
+ $oAttDef = \MetaModel::GetAttributeDef($sTargetClass, $sAttCode);
+ static::assertTrue($oAttDef->Equals(
+ $oObject->Get($sAttCode),
+ $oObjectFromDB->Get($sAttCode)
+ ), "Value of attribute '$sAttCode' has been altered after DB write + read");
+ }
+
+ // Create an indirection
+ $oSubObject = \MetaModel::NewObject('SubObject', [
+ 'name' => 'subobject for '.$iTestObject,
+ 'testobject_id' => $iTestObject
+ ]);
+ $oSubObject->DBInsert();
+
+ // Test that it can be read from the DB
+ $iSubObject = $oSubObject->GetKey();
+ $oSubObjectFromDB = \MetaModel::GetObject('SubObject', $iSubObject);
+
+ // Test that each external field value matches the original value
+ foreach ($aValues as $sAttCode => $aValueData) {
+ $sExtFieldAttCode = '_'.$sAttCode;
+ $oAttDef = \MetaModel::GetAttributeDef($sTargetClass, $sAttCode);
+ static::assertTrue($oAttDef->Equals($oObject->Get($sAttCode), $oSubObjectFromDB->Get($sExtFieldAttCode)), "Value of attribute '$sAttCode' not correctly read as an external key");
+ }
+ }
+}
\ No newline at end of file