toBeArray() ->and($tables)->toHaveKeys([ 'poller_time', 'processes', 'grid_processes', 'automation_processes', 'plugin_hmib_processes', 'plugin_mikrotik_processes', 'plugin_webseer_processes', 'plugin_servcheck_processes', 'mac_track_processes', ]); foreach ($tables as $definition) { expect($definition['label'])->toBeString() ->and($definition['table'])->toBeString() ->and($definition['select'])->toBeString(); } }); test('a non-array hook result falls back to the built-in tables', function () { $GLOBALS['__test_process_hook'] = 'a plugin returned a string'; $tables = support_process_tables_probe(); expect($tables)->toBeArray() ->and($tables)->toHaveKey('poller_time'); }); test('malformed plugin definitions are discarded and valid ones kept', function () { $GLOBALS['__test_process_hook'] = [ 'good_plugin' => [ 'label' => 'Good Plugin', 'table' => 'plugin_good_processes', 'select' => 'SELECT 1', ], 'not_an_array' => 'nope', 'missing_select' => ['label' => 'x', 'table' => 'y'], 'array_label' => ['label' => ['x'], 'table' => 'y', 'select' => 'z'], 'array_table' => ['label' => 'x', 'table' => ['y'], 'select' => 'z'], 'array_select' => ['label' => 'x', 'table' => 'y', 'select' => ['z']], 'empty_label' => ['label' => '', 'table' => 'y', 'select' => 'z'], 'empty_table' => ['label' => 'x', 'table' => ' ', 'select' => 'z'], 'empty_select' => ['label' => 'x', 'table' => 'y', 'select' => "\t"], 'all' => ['label' => 'Reserved', 'table' => 'reserved_processes', 'select' => 'SELECT 1'], 'bad-key' => ['label' => 'Bad Key', 'table' => 'bad_key_processes', 'select' => 'SELECT 1'], 'bad_table' => ['label' => 'Bad Table', 'table' => 'bad-table', 'select' => 'SELECT 1'], 123 => ['label' => 'Integer Key', 'table' => 'int_key_processes', 'select' => 'SELECT 1'], ]; $tables = support_process_tables_probe(); expect(array_keys($tables))->toBe(['good_plugin']) ->and($tables['good_plugin']['table'])->toBe('plugin_good_processes'); }); test('the process query is skipped when no tables are available', function () { // A regression guard: when every process table is absent the UNION source is // empty, and show_cacti_processes() must render an empty result instead of a // broken "FROM ()" query. $src = file_get_contents(dirname(__DIR__, 3) . '/support.php'); expect($src)->toContain("if (\$sql_inner == '') {") ->and($src)->toContain('$processes = [];'); }); test('poller_time timeout stays string typed for the UNION', function () { $tables = support_process_tables_probe(); expect($tables['poller_time']['select'])->toContain(" AS taskid, '") ->and($tables['poller_time']['select'])->toContain("' AS timeout"); });