clqms-be/tests/unit/Rules/RuleEngineMultiActionTest.php

356 lines
11 KiB
PHP
Raw Normal View History

<?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);
}
}