from pathlib import Path from scripts.adapters.psscriptanalyzer import parse_psscriptanalyzer_output _FIXTURES = Path(__file__).parent / "fixtures" _REPO = "/repo" def _pssa(): payload = (_FIXTURES / "psscriptanalyzer_sample.json").read_text() return {f.rule_id: f for f in parse_psscriptanalyzer_output(payload, repo_root=_REPO)} def _injection(): payload = (_FIXTURES / "injectionhunter_sample.json").read_text() return { f.rule_id: f for f in parse_psscriptanalyzer_output(payload, repo_root=_REPO, tool="injectionhunter") } def test_paths_are_relative_to_repo_root(): f = _pssa()["PSAvoidUsingInvokeExpression"] assert f.file == "scripts/Deploy.ps1" assert f.tool == "psscriptanalyzer" def test_severity_mapping(): by_rule = _pssa() assert by_rule["PSAvoidUsingConvertToSecureStringWithPlainText"].severity == "high" assert by_rule["PSAvoidUsingInvokeExpression"].severity == "medium" assert by_rule["PSUseDeclaredVarsMoreThanAssignments"].severity == "low" assert by_rule["TypeNotFound"].severity == "critical" def test_line_range_from_extent(): f = _pssa()["PSAvoidUsingConvertToSecureStringWithPlainText"] assert f.line == 20 assert f.end_line == 22 def test_message_preserved(): assert "Invoke-Expression" in _pssa()["PSAvoidUsingInvokeExpression"].message def test_injectionhunter_findings_floor_at_high(): by_rule = _injection() assert by_rule["InjectionRisk.InvokeExpression"].severity == "high" assert by_rule["InjectionRisk.AddScriptBlock"].severity == "high" def test_injectionhunter_tool_name_and_location(): f = _injection()["InjectionRisk.AddScriptBlock"] assert f.tool == "injectionhunter" assert f.file == "scripts/Deploy.ps1" assert f.line == 33 assert f.end_line == 35 def test_single_object_not_array(): payload = '{"RuleName":"PSAvoidUsingWriteHost","Severity":"Warning","ScriptPath":"/repo/a.ps1","Line":3,"EndLine":3,"Message":"m"}' findings = parse_psscriptanalyzer_output(payload, repo_root=_REPO) assert len(findings) == 1 assert findings[0].file == "a.ps1" def test_handles_empty_array(): assert parse_psscriptanalyzer_output("[]", repo_root=_REPO) == [] def test_handles_invalid_json(): assert parse_psscriptanalyzer_output("not json", repo_root=_REPO) == [] def test_unknown_severity_defaults_to_medium(): payload = '[{"RuleName":"X","Severity":"Bogus","ScriptPath":"/repo/a.ps1","Line":1,"EndLine":1,"Message":"m"}]' assert parse_psscriptanalyzer_output(payload, repo_root=_REPO)[0].severity == "medium"