from scripts.scanners import ( _normalize_tflint_findings, _run_tflint, ) def test_normalize_tflint_findings_parses_issues(): payload = { "issues": [ { "rule": { "name": "terraform_unused_declarations", "severity": "warning", "link": "https://example.com/rule", }, "message": "variable \"foo\" is declared but not used", "range": { "filename": "variables.tf", "start": {"line": 12}, "end": {"line": 12}, }, } ], "errors": [], } findings = _normalize_tflint_findings(payload, scanned_dir="modules/vpc") assert len(findings) == 1 f = findings[0] assert f.rule == "terraform_unused_declarations" assert f.file == "modules/vpc/variables.tf" assert f.start_line == 12 assert f.severity == "warning" assert f.source == "tflint" def test_normalize_tflint_findings_preserves_absolute_filename(): payload = { "issues": [ { "rule": {"name": "r", "severity": "warning"}, "message": "m", "range": {"filename": "modules/vpc/variables.tf", "start": {"line": 1}, "end": {"line": 1}}, } ] } findings = _normalize_tflint_findings(payload, scanned_dir="modules/vpc") assert findings[0].file == "modules/vpc/variables.tf" def test_normalize_tflint_findings_empty(): assert _normalize_tflint_findings({"issues": []}, scanned_dir=".") == [] def test_run_tflint_handles_missing_binary(tmp_path, monkeypatch): monkeypatch.setenv("PATH", "/nonexistent") payload, findings, err = _run_tflint(tmp_path, ["main.tf"]) assert findings == [] assert payload == {} assert err is None def test_run_tflint_skips_when_no_terraform_files(tmp_path): payload, findings, err = _run_tflint(tmp_path, ["README.md", "Makefile"]) assert findings == [] assert err is None def test_normalize_tflint_findings_collapses_dot_scanned_dir(): payload = { "issues": [ { "rule": {"name": "r", "severity": "warning"}, "message": "m", "range": {"filename": "main.tf", "start": {"line": 1}, "end": {"line": 1}}, } ] } findings = _normalize_tflint_findings(payload, scanned_dir=".") assert findings[0].file == "main.tf" def test_run_tflint_aggregates_errors_from_multiple_dirs(tmp_path, monkeypatch): (tmp_path / "modules" / "a").mkdir(parents=True) (tmp_path / "modules" / "b").mkdir(parents=True) (tmp_path / "modules" / "a" / "main.tf").write_text("") (tmp_path / "modules" / "b" / "main.tf").write_text("") from scripts import scanners def fake_run(cmd, **_): class R: returncode = 1 stdout = "" stderr = "boom" return R() monkeypatch.setattr(scanners.subprocess, "run", fake_run) monkeypatch.setattr(scanners.shutil, "which", lambda _: "/usr/bin/tflint") payload, findings, err = scanners._run_tflint( tmp_path, ["modules/a/main.tf", "modules/b/main.tf"] ) assert findings == [] assert err is not None assert "modules/a" in err assert "modules/b" in err