<?php
use PHPUnit\Framework\TestCase;
use SHServ\Models\Scripts;
use SHServ\Middleware\ControlScripts;
class ScriptsModelStateTest extends TestCase {
private $tb;
private $scriptsModel;
private $originalScopes;
protected function setUp(): void {
$this -> tb = app() -> thin_builder;
$this -> create_scripts_table();
$this -> scriptsModel = new Scripts();
$this -> originalScopes = app() -> control_scripts_instances;
app() -> control_scripts_instances = [];
}
protected function tearDown(): void {
$this -> tb -> query("DROP TABLE IF EXISTS scripts");
app() -> control_scripts_instances = $this -> originalScopes;
// Reset static script registries to avoid leakage between tests
$refRegular = new \ReflectionProperty(ControlScripts::class, 'regular_scripts');
$refRegular -> setAccessible(true);
$refRegular -> setValue(null, []);
$refActions = new \ReflectionProperty(ControlScripts::class, 'actions_scripts');
$refActions -> setAccessible(true);
$refActions -> setValue(null, []);
}
private function create_scripts_table(): void {
$this -> tb -> query("CREATE TABLE scripts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
area_id INTEGER DEFAULT 0,
uniq_name TEXT,
type TEXT,
state TEXT,
create_at TEXT,
update_at TEXT
)");
}
private function makeFakeScope(string $name): object {
return new class($name) extends ControlScripts {
private string $name;
public function __construct(string $name) {
$this -> name = $name;
// bypass parent constructor to avoid DB checks
}
public function register_sync_map(): void {}
protected function register_events_handlers(): void {}
protected function register_regular_scripts(): void {}
protected function register_actions_scripts(): void {}
};
}
private function registerActionScript(string $alias): void {
$scope = $this -> makeFakeScope('FakeScope');
$ref = new \ReflectionMethod(ControlScripts::class, 'add_action_script');
$ref -> setAccessible(true);
$ref -> invoke($scope, ['alias' => $alias, 'name' => 'Test Action'], function($params) {
return true;
});
}
private function registerRegularScript(string $alias): void {
$scope = $this -> makeFakeScope('FakeScope');
$ref = new \ReflectionMethod(ControlScripts::class, 'add_regular_script');
$ref -> setAccessible(true);
$ref -> invoke($scope, ['alias' => $alias, 'name' => 'Test Regular'], function() {
return true;
});
}
public function test_get_scopes_list_returns_metadata(): void {
app() -> control_scripts_instances = [
'FakeScope' => $this -> makeFakeScope('FakeScope'),
];
$list = $this -> scriptsModel -> get_scopes_list();
$this -> assertCount(1, $list);
$this -> assertSame('FakeScope', $list[0]['name']);
$this -> assertNotEmpty($list[0]['filename']);
$this -> assertNotEmpty($list[0]['path']);
$this -> assertSame('disabled', $list[0]['state']);
}
public function test_script_state_returns_false_for_missing(): void {
$this -> assertFalse($this -> scriptsModel -> script_state('action', 'nonexistent'));
}
public function test_script_state_returns_true_for_enabled(): void {
$this -> tb -> insert('scripts', [
'uniq_name' => 'test_script',
'type' => 'action',
'state' => 'enabled',
'create_at' => date('Y-m-d H:i:s'),
]);
$this -> assertTrue($this -> scriptsModel -> script_state('action', 'test_script'));
}
public function test_enable_script_inserts_row(): void {
$this -> registerActionScript('enable_me');
$result = $this -> scriptsModel -> enable_script('action', 'enable_me');
$this -> assertTrue($result);
$rows = $this -> tb -> select('scripts', ['state'], [
['uniq_name', '=', 'enable_me'],
'AND',
['type', '=', 'action'],
]);
$this -> assertCount(1, $rows);
$this -> assertSame('enabled', $rows[0]['state']);
}
public function test_disable_script_updates_row(): void {
$this -> registerActionScript('disable_me');
$this -> tb -> insert('scripts', [
'uniq_name' => 'disable_me',
'type' => 'action',
'state' => 'enabled',
'create_at' => date('Y-m-d H:i:s'),
]);
$result = $this -> scriptsModel -> disable_script('action', 'disable_me');
$this -> assertTrue($result);
$rows = $this -> tb -> select('scripts', ['state'], [
['uniq_name', '=', 'disable_me'],
'AND',
['type', '=', 'action'],
]);
$this -> assertSame('disabled', $rows[0]['state']);
}
public function test_set_script_state_returns_scope_not_found(): void {
app() -> control_scripts_instances = ['RealScope' => $this -> makeFakeScope('RealScope')];
$result = $this -> scriptsModel -> set_script_state('scope', 'missing_scope', true);
$this -> assertSame('scope_not_found', $result);
}
public function test_set_script_state_returns_invalid_type(): void {
$result = $this -> scriptsModel -> set_script_state('invalid_type', 'something', true);
$this -> assertSame('invalid_type', $result);
}
public function test_set_script_state_updates_existing_row(): void {
$this -> registerRegularScript('regular_one');
$this -> tb -> insert('scripts', [
'uniq_name' => 'regular_one',
'type' => 'regular',
'state' => 'disabled',
'create_at' => date('Y-m-d H:i:s'),
]);
$result = $this -> scriptsModel -> set_script_state('regular', 'regular_one', true);
$this -> assertTrue($result);
$rows = $this -> tb -> select('scripts', ['state'], [
['uniq_name', '=', 'regular_one'],
'AND',
['type', '=', 'regular'],
]);
$this -> assertSame('enabled', $rows[0]['state']);
}
public function test_select_scripts_by_aliases_types_returns_empty_for_empty_array(): void {
$result = $this -> scriptsModel -> select_scripts_by_aliases_types('action', []);
$this -> assertIsArray($result);
$this -> assertCount(0, $result);
}
}