toContain("json_encode((string) grv('tab'))"); expect($contents)->toContain("gfrv('tab', FILTER_VALIDATE_REGEXP"); expect($contents)->toContain('rawurlencode($currentTab)'); }); test('plugins page normalizes state and encodes sort column in JavaScript', function () use ($pluginsPath) { $contents = file_get_contents($pluginsPath); expect($contents)->toContain("json_encode((string) grv('sort_column'))"); expect($contents)->toContain("var tableState = ;"); expect($contents)->not->toContain("var tableState = "); }); test('graph list view uses JSON and sanitized CSV for graph list', function () use ($htmlGraphPath) { $contents = file_get_contents($htmlGraphPath); expect($contents)->toContain('$graph_list_js = []'); expect($contents)->toContain('ctype_digit($item)'); expect($contents)->toContain('json_encode($graph_list_js)'); expect($contents)->toContain("graph_list="); expect($contents)->not->toContain("new Array()"); }); test('graph pages encode JS-bound PHP strings safely', function () use ($htmlGraphPath) { $contents = file_get_contents($htmlGraphPath); expect($contents)->toContain('var pageAction = '); expect($contents)->toContain('var graphPage = '); expect($contents)->toContain("json_encode((string) \$suffix)"); }); test('data debug escapes tooltip title values before rendering', function () use ($dataDebugPath) { $contents = file_get_contents($dataDebugPath); expect($contents)->toContain('$value_title = htmle((string) $value);'); }); test('auth reset password encodes return location in onclick handlers', function () use ($authResetpasswordPath) { $contents = file_get_contents($authResetpasswordPath); expect($contents)->toContain("document.location="); expect($contents)->not->toContain("document.location=\"\""); }); test('auth change password encodes return location in onclick handler', function () use ($authChangepasswordPath) { $contents = file_get_contents($authChangepasswordPath); expect($contents)->toContain("document.location="); expect($contents)->not->toContain("onClick='document.location=\\\"\$return\\\"'"); });