356 lines
11 KiB
PHP
356 lines
11 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace Tests\Unit\Rules;
|
||
|
|
|
||
|
|
use App\Services\RuleEngineService;
|
||
|
|
use CodeIgniter\Test\CIUnitTestCase;
|
||
|
|
use CodeIgniter\Test\DatabaseTestTrait;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Integration tests for Rule Engine with multi-action support
|
||
|
|
*/
|
||
|
|
class RuleEngineMultiActionTest extends CIUnitTestCase
|
||
|
|
{
|
||
|
|
use DatabaseTestTrait;
|
||
|
|
|
||
|
|
protected RuleEngineService $engine;
|
||
|
|
protected $seed = [];
|
||
|
|
|
||
|
|
public function setUp(): void
|
||
|
|
{
|
||
|
|
parent::setUp();
|
||
|
|
$this->engine = new RuleEngineService();
|
||
|
|
|
||
|
|
// Seed test data
|
||
|
|
$this->seedTestData();
|
||
|
|
}
|
||
|
|
|
||
|
|
private function seedTestData(): void
|
||
|
|
{
|
||
|
|
$db = \Config\Database::connect();
|
||
|
|
|
||
|
|
// Insert test testdefsite
|
||
|
|
$db->table('testdefsite')->insert([
|
||
|
|
'TestSiteCode' => 'GLU',
|
||
|
|
'TestSiteName' => 'Glucose',
|
||
|
|
'CreateDate' => date('Y-m-d H:i:s'),
|
||
|
|
]);
|
||
|
|
|
||
|
|
$db->table('testdefsite')->insert([
|
||
|
|
'TestSiteCode' => 'HBA1C',
|
||
|
|
'TestSiteName' => 'HbA1c',
|
||
|
|
'CreateDate' => date('Y-m-d H:i:s'),
|
||
|
|
]);
|
||
|
|
|
||
|
|
// Insert test order
|
||
|
|
$db->table('orders')->insert([
|
||
|
|
'OrderID' => 'ORD001',
|
||
|
|
'Sex' => 'M',
|
||
|
|
'Age' => 45,
|
||
|
|
'Priority' => 'R',
|
||
|
|
'CreateDate' => date('Y-m-d H:i:s'),
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testExecuteSetResult()
|
||
|
|
{
|
||
|
|
$db = \Config\Database::connect();
|
||
|
|
|
||
|
|
// Get order ID
|
||
|
|
$order = $db->table('orders')->where('OrderID', 'ORD001')->get()->getRowArray();
|
||
|
|
$internalOID = $order['InternalOID'] ?? null;
|
||
|
|
|
||
|
|
// Get test site ID
|
||
|
|
$testSite = $db->table('testdefsite')->where('TestSiteCode', 'GLU')->get()->getRowArray();
|
||
|
|
$testSiteID = $testSite['TestSiteID'] ?? null;
|
||
|
|
|
||
|
|
$this->assertNotNull($internalOID);
|
||
|
|
$this->assertNotNull($testSiteID);
|
||
|
|
|
||
|
|
// Insert initial patres row
|
||
|
|
$db->table('patres')->insert([
|
||
|
|
'OrderID' => $internalOID,
|
||
|
|
'TestSiteID' => $testSiteID,
|
||
|
|
'CreateDate' => date('Y-m-d H:i:s'),
|
||
|
|
]);
|
||
|
|
|
||
|
|
// Execute RESULT_SET action
|
||
|
|
$action = [
|
||
|
|
'type' => 'RESULT_SET',
|
||
|
|
'value' => 5.5,
|
||
|
|
];
|
||
|
|
|
||
|
|
$context = [
|
||
|
|
'order' => [
|
||
|
|
'InternalOID' => $internalOID,
|
||
|
|
'Sex' => 'M',
|
||
|
|
'Age' => 45,
|
||
|
|
],
|
||
|
|
'testSiteID' => $testSiteID,
|
||
|
|
];
|
||
|
|
|
||
|
|
$this->invokeMethod($this->engine, 'executeAction', [$action, $context]);
|
||
|
|
|
||
|
|
// Verify result was set
|
||
|
|
$patres = $db->table('patres')
|
||
|
|
->where('OrderID', $internalOID)
|
||
|
|
->where('TestSiteID', $testSiteID)
|
||
|
|
->where('DelDate', null)
|
||
|
|
->get()->getRowArray();
|
||
|
|
|
||
|
|
$this->assertNotNull($patres);
|
||
|
|
$this->assertEquals(5.5, $patres['Result']);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testExecuteInsertTest()
|
||
|
|
{
|
||
|
|
$db = \Config\Database::connect();
|
||
|
|
|
||
|
|
// Get order ID
|
||
|
|
$order = $db->table('orders')->where('OrderID', 'ORD001')->get()->getRowArray();
|
||
|
|
$internalOID = $order['InternalOID'] ?? null;
|
||
|
|
|
||
|
|
$this->assertNotNull($internalOID);
|
||
|
|
|
||
|
|
// Execute TEST_INSERT action
|
||
|
|
$action = [
|
||
|
|
'type' => 'TEST_INSERT',
|
||
|
|
'testCode' => 'HBA1C',
|
||
|
|
];
|
||
|
|
|
||
|
|
$context = [
|
||
|
|
'order' => [
|
||
|
|
'InternalOID' => $internalOID,
|
||
|
|
],
|
||
|
|
];
|
||
|
|
|
||
|
|
$this->invokeMethod($this->engine, 'executeAction', [$action, $context]);
|
||
|
|
|
||
|
|
// Verify test was inserted
|
||
|
|
$testSite = $db->table('testdefsite')->where('TestSiteCode', 'HBA1C')->get()->getRowArray();
|
||
|
|
$testSiteID = $testSite['TestSiteID'] ?? null;
|
||
|
|
|
||
|
|
$patres = $db->table('patres')
|
||
|
|
->where('OrderID', $internalOID)
|
||
|
|
->where('TestSiteID', $testSiteID)
|
||
|
|
->where('DelDate', null)
|
||
|
|
->get()->getRowArray();
|
||
|
|
|
||
|
|
$this->assertNotNull($patres);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testExecuteAddComment()
|
||
|
|
{
|
||
|
|
$db = \Config\Database::connect();
|
||
|
|
|
||
|
|
// Get order ID
|
||
|
|
$order = $db->table('orders')->where('OrderID', 'ORD001')->get()->getRowArray();
|
||
|
|
$internalOID = $order['InternalOID'] ?? null;
|
||
|
|
|
||
|
|
$this->assertNotNull($internalOID);
|
||
|
|
|
||
|
|
// Execute COMMENT_INSERT action
|
||
|
|
$action = [
|
||
|
|
'type' => 'COMMENT_INSERT',
|
||
|
|
'comment' => 'Test comment from rule engine',
|
||
|
|
];
|
||
|
|
|
||
|
|
$context = [
|
||
|
|
'order' => [
|
||
|
|
'InternalOID' => $internalOID,
|
||
|
|
],
|
||
|
|
];
|
||
|
|
|
||
|
|
$this->invokeMethod($this->engine, 'executeAction', [$action, $context]);
|
||
|
|
|
||
|
|
// Verify comment was added
|
||
|
|
$comment = $db->table('ordercom')
|
||
|
|
->where('InternalOID', $internalOID)
|
||
|
|
->where('Comment', 'Test comment from rule engine')
|
||
|
|
->get()->getRowArray();
|
||
|
|
|
||
|
|
$this->assertNotNull($comment);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testExecuteNoOp()
|
||
|
|
{
|
||
|
|
// Execute NO_OP action - should not throw or do anything
|
||
|
|
$action = [
|
||
|
|
'type' => 'NO_OP',
|
||
|
|
];
|
||
|
|
|
||
|
|
$context = [
|
||
|
|
'order' => [
|
||
|
|
'InternalOID' => 1,
|
||
|
|
],
|
||
|
|
];
|
||
|
|
|
||
|
|
// Should not throw exception
|
||
|
|
$this->invokeMethod($this->engine, 'executeAction', [$action, $context]);
|
||
|
|
|
||
|
|
// Test passes if no exception is thrown
|
||
|
|
$this->assertTrue(true);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testMultiActionExecution()
|
||
|
|
{
|
||
|
|
$db = \Config\Database::connect();
|
||
|
|
|
||
|
|
// Get order ID
|
||
|
|
$order = $db->table('orders')->where('OrderID', 'ORD001')->get()->getRowArray();
|
||
|
|
$internalOID = $order['InternalOID'] ?? null;
|
||
|
|
|
||
|
|
// Get test site ID
|
||
|
|
$testSite = $db->table('testdefsite')->where('TestSiteCode', 'GLU')->get()->getRowArray();
|
||
|
|
$testSiteID = $testSite['TestSiteID'] ?? null;
|
||
|
|
|
||
|
|
$this->assertNotNull($internalOID);
|
||
|
|
$this->assertNotNull($testSiteID);
|
||
|
|
|
||
|
|
// Insert initial patres row
|
||
|
|
$db->table('patres')->insert([
|
||
|
|
'OrderID' => $internalOID,
|
||
|
|
'TestSiteID' => $testSiteID,
|
||
|
|
'CreateDate' => date('Y-m-d H:i:s'),
|
||
|
|
]);
|
||
|
|
|
||
|
|
// Execute multiple actions
|
||
|
|
$actions = [
|
||
|
|
[
|
||
|
|
'type' => 'RESULT_SET',
|
||
|
|
'value' => 7.2,
|
||
|
|
],
|
||
|
|
[
|
||
|
|
'type' => 'COMMENT_INSERT',
|
||
|
|
'comment' => 'Multi-action test',
|
||
|
|
],
|
||
|
|
[
|
||
|
|
'type' => 'TEST_INSERT',
|
||
|
|
'testCode' => 'HBA1C',
|
||
|
|
],
|
||
|
|
];
|
||
|
|
|
||
|
|
$context = [
|
||
|
|
'order' => [
|
||
|
|
'InternalOID' => $internalOID,
|
||
|
|
],
|
||
|
|
'testSiteID' => $testSiteID,
|
||
|
|
];
|
||
|
|
|
||
|
|
foreach ($actions as $action) {
|
||
|
|
$this->invokeMethod($this->engine, 'executeAction', [$action, $context]);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Verify SET_RESULT
|
||
|
|
$patres = $db->table('patres')
|
||
|
|
->where('OrderID', $internalOID)
|
||
|
|
->where('TestSiteID', $testSiteID)
|
||
|
|
->where('DelDate', null)
|
||
|
|
->get()->getRowArray();
|
||
|
|
$this->assertEquals(7.2, $patres['Result']);
|
||
|
|
|
||
|
|
// Verify ADD_COMMENT
|
||
|
|
$comment = $db->table('ordercom')
|
||
|
|
->where('InternalOID', $internalOID)
|
||
|
|
->where('Comment', 'Multi-action test')
|
||
|
|
->get()->getRowArray();
|
||
|
|
$this->assertNotNull($comment);
|
||
|
|
|
||
|
|
// Verify INSERT_TEST
|
||
|
|
$hba1cSite = $db->table('testdefsite')->where('TestSiteCode', 'HBA1C')->get()->getRowArray();
|
||
|
|
$hba1cPatres = $db->table('patres')
|
||
|
|
->where('OrderID', $internalOID)
|
||
|
|
->where('TestSiteID', $hba1cSite['TestSiteID'])
|
||
|
|
->where('DelDate', null)
|
||
|
|
->get()->getRowArray();
|
||
|
|
$this->assertNotNull($hba1cPatres);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testIsTestRequested()
|
||
|
|
{
|
||
|
|
$db = \Config\Database::connect();
|
||
|
|
|
||
|
|
// Get order ID
|
||
|
|
$order = $db->table('orders')->where('OrderID', 'ORD001')->get()->getRowArray();
|
||
|
|
$internalOID = $order['InternalOID'] ?? null;
|
||
|
|
|
||
|
|
// Get test site ID
|
||
|
|
$testSite = $db->table('testdefsite')->where('TestSiteCode', 'GLU')->get()->getRowArray();
|
||
|
|
$testSiteID = $testSite['TestSiteID'] ?? null;
|
||
|
|
|
||
|
|
// Insert patres row for GLU test
|
||
|
|
$db->table('patres')->insert([
|
||
|
|
'OrderID' => $internalOID,
|
||
|
|
'TestSiteID' => $testSiteID,
|
||
|
|
'CreateDate' => date('Y-m-d H:i:s'),
|
||
|
|
]);
|
||
|
|
|
||
|
|
// Test isTestRequested method
|
||
|
|
$result = $this->invokeMethod($this->engine, 'isTestRequested', ['GLU', [
|
||
|
|
'order' => ['InternalOID' => $internalOID],
|
||
|
|
]]);
|
||
|
|
|
||
|
|
$this->assertTrue($result);
|
||
|
|
|
||
|
|
// Test for non-existent test
|
||
|
|
$result = $this->invokeMethod($this->engine, 'isTestRequested', ['NONEXISTENT', [
|
||
|
|
'order' => ['InternalOID' => $internalOID],
|
||
|
|
]]);
|
||
|
|
|
||
|
|
$this->assertFalse($result);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function testExecuteDeleteTest(): void
|
||
|
|
{
|
||
|
|
$db = \Config\Database::connect();
|
||
|
|
|
||
|
|
$order = $db->table('orders')->where('OrderID', 'ORD001')->get()->getRowArray();
|
||
|
|
$internalOID = $order['InternalOID'] ?? null;
|
||
|
|
$this->assertNotNull($internalOID);
|
||
|
|
|
||
|
|
$testSite = $db->table('testdefsite')->where('TestSiteCode', 'HBA1C')->get()->getRowArray();
|
||
|
|
$testSiteID = $testSite['TestSiteID'] ?? null;
|
||
|
|
$this->assertNotNull($testSiteID);
|
||
|
|
|
||
|
|
// Insert a patres row to delete
|
||
|
|
$db->table('patres')->insert([
|
||
|
|
'OrderID' => $internalOID,
|
||
|
|
'TestSiteID' => $testSiteID,
|
||
|
|
'CreateDate' => date('Y-m-d H:i:s'),
|
||
|
|
]);
|
||
|
|
|
||
|
|
$action = [
|
||
|
|
'type' => 'TEST_DELETE',
|
||
|
|
'testCode' => 'HBA1C',
|
||
|
|
];
|
||
|
|
|
||
|
|
$context = [
|
||
|
|
'order' => [
|
||
|
|
'InternalOID' => $internalOID,
|
||
|
|
],
|
||
|
|
];
|
||
|
|
|
||
|
|
$this->invokeMethod($this->engine, 'executeAction', [$action, $context]);
|
||
|
|
|
||
|
|
$deleted = $db->table('patres')
|
||
|
|
->where('OrderID', $internalOID)
|
||
|
|
->where('TestSiteID', $testSiteID)
|
||
|
|
->get()
|
||
|
|
->getRowArray();
|
||
|
|
|
||
|
|
$this->assertNotNull($deleted);
|
||
|
|
$this->assertNotEmpty($deleted['DelDate'] ?? null);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Helper to invoke protected/private methods
|
||
|
|
*/
|
||
|
|
private function invokeMethod($object, $methodName, array $parameters = [])
|
||
|
|
{
|
||
|
|
$reflection = new \ReflectionClass(get_class($object));
|
||
|
|
$method = $reflection->getMethod($methodName);
|
||
|
|
$method->setAccessible(true);
|
||
|
|
return $method->invokeArgs($object, $parameters);
|
||
|
|
}
|
||
|
|
}
|