mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
@@ -4538,6 +4538,8 @@ abstract class DBObject implements iDisplay
|
||||
} else {
|
||||
$aBackupValues[$sAttCode] = $value;
|
||||
}
|
||||
} else {
|
||||
$aBackupValues[$sAttCode] = $oAttDef->GetNullValue();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Core\DBObject;
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopCustomDatamodelTestCase;
|
||||
use IssueLog;
|
||||
use LogChannels;
|
||||
use MetaModel;
|
||||
use utils;
|
||||
use const EVENT_DB_LINKS_CHANGED;
|
||||
|
||||
class DBObjectWithModifiedDataModelTest extends ItopCustomDatamodelTestCase
|
||||
{
|
||||
public function GetDatamodelDeltaAbsPath(): string
|
||||
{
|
||||
return __DIR__.'/Delta/dbobjecttest.xml';
|
||||
}
|
||||
|
||||
const USE_TRANSACTION = true;
|
||||
const CREATE_TEST_ORG = false;
|
||||
|
||||
|
||||
private static string $sLogFile = 'log/test_error_CRUDEventTest.log';
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
static::$DEBUG_UNIT_TEST = false;
|
||||
|
||||
if (static::$DEBUG_UNIT_TEST) {
|
||||
echo '--- logging in '.APPROOT.static::$sLogFile."\n\n";
|
||||
@unlink(APPROOT.static::$sLogFile);
|
||||
IssueLog::Enable(APPROOT.static::$sLogFile);
|
||||
$oConfig = utils::GetConfig();
|
||||
$oConfig->Set('log_level_min', [LogChannels::DM_CRUD => 'Debug', LogChannels::EVENT_SERVICE => 'Trace']);
|
||||
}
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
if (is_file(APPROOT.static::$sLogFile)) {
|
||||
$sLog = file_get_contents(APPROOT.static::$sLogFile);
|
||||
echo "--- error.log\n$sLog\n\n";
|
||||
@unlink(APPROOT.static::$sLogFile);
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function testStimulusStoppingActionPreventObjectModification()
|
||||
{
|
||||
// Given
|
||||
$sObjectKey = $this->GivenObjectInDB('TestDBObject', ['name' => 'parent', 'status' => 'new']);
|
||||
$oParent = MetaModel::GetObject('TestDBObject', $sObjectKey);
|
||||
|
||||
// When actions ApplyStimulus then next action fails
|
||||
$oParent->ApplyStimulus('ev_assign');
|
||||
$oParent->Reload();
|
||||
|
||||
// Then
|
||||
// Check status...
|
||||
$this->assertEquals('new', $oParent->Get('status'), 'The status should have remained unmodified due to action failure');
|
||||
}
|
||||
|
||||
public function testCallingApplyStimulusWithinActionsWorks()
|
||||
{
|
||||
// Given
|
||||
$sObjectKey = $this->GivenObjectInDB('TestDBObject', ['name' => 'parent', 'status' => 'assigned']);
|
||||
$oParent = MetaModel::GetObject('TestDBObject', $sObjectKey);
|
||||
|
||||
// When action ApplyStimulus
|
||||
$oParent->ApplyStimulus('ev_reassign');
|
||||
$oParent->Reload();
|
||||
|
||||
// Then
|
||||
// Check that status has changed to the final status
|
||||
$this->assertEquals('resolved', $oParent->Get('status'), 'The status should have been modified to resolved (the final state after a nested stimulus)');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0">
|
||||
<classes>
|
||||
<class id="TestDBObject" _delta="define">
|
||||
<parent>cmdbAbstractObject</parent>
|
||||
@@ -12,7 +12,77 @@
|
||||
<attribute id="name"/>
|
||||
</attributes>
|
||||
</reconciliation>
|
||||
<fields_semantic>
|
||||
<state_attribute>status</state_attribute>
|
||||
</fields_semantic>
|
||||
</properties>
|
||||
<lifecycle>
|
||||
<highlight_scale>
|
||||
<item id="closed">
|
||||
<rank>3</rank>
|
||||
<color>HIGHLIGHT_CLASS_NONE</color>
|
||||
<icon>images/user-request-closed.svg</icon>
|
||||
</item>
|
||||
</highlight_scale>
|
||||
<stimuli>
|
||||
<stimulus id="ev_assign" xsi:type="StimulusUserAction"/>
|
||||
<stimulus id="ev_reassign" xsi:type="StimulusUserAction"/>
|
||||
<stimulus id="ev_resolve" xsi:type="StimulusUserAction"/>
|
||||
</stimuli>
|
||||
<states>
|
||||
<state id="new">
|
||||
<flags/>
|
||||
<transitions>
|
||||
<transition id="ev_assign">
|
||||
<target>assigned</target>
|
||||
<actions>
|
||||
<action>
|
||||
<verb>Assign</verb>
|
||||
<params/>
|
||||
</action>
|
||||
<action>
|
||||
<verb>Assign2</verb>
|
||||
<params/>
|
||||
</action>
|
||||
</actions>
|
||||
</transition>
|
||||
</transitions>
|
||||
</state>
|
||||
<state id="assigned">
|
||||
<inherit_flags_from>new</inherit_flags_from>
|
||||
<flags/>
|
||||
<transitions>
|
||||
<transition id="ev_resolve">
|
||||
<target>resolved</target>
|
||||
<actions>
|
||||
<action>
|
||||
<verb>Resolve</verb>
|
||||
<params/>
|
||||
</action>
|
||||
</actions>
|
||||
</transition>
|
||||
<transition id="ev_reassign">
|
||||
<target>assigned</target>
|
||||
<actions>
|
||||
<action>
|
||||
<verb>Reassign</verb>
|
||||
<params/>
|
||||
</action>
|
||||
</actions>
|
||||
<flags/>
|
||||
</transition>
|
||||
</transitions>
|
||||
</state>
|
||||
<state id="resolved">
|
||||
<highlight>
|
||||
<code>closed</code>
|
||||
</highlight>
|
||||
<inherit_flags_from>assigned</inherit_flags_from>
|
||||
<flags/>
|
||||
<transitions/>
|
||||
</state>
|
||||
</states>
|
||||
</lifecycle>
|
||||
<fields>
|
||||
<field id="name" xsi:type="AttributeString">
|
||||
<sql>name</sql>
|
||||
@@ -38,9 +108,90 @@
|
||||
<count_max>0</count_max>
|
||||
<with_php_computation>true</with_php_computation>
|
||||
</field>
|
||||
<field id="status" xsi:type="AttributeEnum">
|
||||
<always_load_in_tables>true</always_load_in_tables>
|
||||
<sort_type>rank</sort_type>
|
||||
<values>
|
||||
<value id="new">
|
||||
<code>new</code>
|
||||
<rank>10</rank>
|
||||
</value>
|
||||
<value id="assigned">
|
||||
<code>assigned</code>
|
||||
<rank>60</rank>
|
||||
</value>
|
||||
<value id="resolved">
|
||||
<code>resolved</code>
|
||||
<rank>100</rank>
|
||||
</value>
|
||||
</values>
|
||||
<sql>status</sql>
|
||||
<default_value>new</default_value>
|
||||
<is_null_allowed>false</is_null_allowed>
|
||||
</field>
|
||||
</fields>
|
||||
<presentation/>
|
||||
<methods/>
|
||||
<methods>
|
||||
<method id="Assign">
|
||||
<comment><![CDATA[/**
|
||||
* @return true (returning false would stop the ongoing transition)
|
||||
*/]]></comment>
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<type>LifecycleAction</type>
|
||||
<arguments>
|
||||
</arguments>
|
||||
<code><![CDATA[ public function Assign()
|
||||
{
|
||||
$this->ApplyStimulus('ev_assign');
|
||||
return true;
|
||||
}]]></code>
|
||||
</method>
|
||||
<method id="Assign2">
|
||||
<comment><![CDATA[/**
|
||||
* @return true (returning false would stop the ongoing transition)
|
||||
*/]]></comment>
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<type>LifecycleAction</type>
|
||||
<arguments>
|
||||
</arguments>
|
||||
<code><![CDATA[ public function Assign2()
|
||||
{
|
||||
return false;
|
||||
}]]></code>
|
||||
</method>
|
||||
<method id="Resolve">
|
||||
<comment><![CDATA[/**
|
||||
* @return true (returning false would stop the ongoing transition)
|
||||
*/]]></comment>
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<type>LifecycleAction</type>
|
||||
<arguments>
|
||||
</arguments>
|
||||
<code><![CDATA[ public function Resolve()
|
||||
{
|
||||
$this->ApplyStimulus('ev_resolve');
|
||||
return true;
|
||||
}]]></code>
|
||||
</method>
|
||||
<method id="Reassign">
|
||||
<comment><![CDATA[/**
|
||||
* @return true (returning false would stop the ongoing transition)
|
||||
*/]]></comment>
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<type>LifecycleAction</type>
|
||||
<arguments>
|
||||
</arguments>
|
||||
<code><![CDATA[ public function Reassign()
|
||||
{
|
||||
$this->ApplyStimulus('ev_resolve');
|
||||
return true;
|
||||
}]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
</class>
|
||||
</classes>
|
||||
</itop_design>
|
||||
Reference in New Issue
Block a user