import os import tempfile import pandas as pd import app as app_mod def noop_progress(*args, **kwargs): return None def test_run_scan_empty_target(): df, msg, log, report_html, report_path = app_mod.run_scan( " ", "", False, False, False, 10, True, True, True, True, progress=noop_progress ) assert isinstance(df, pd.DataFrame) assert df.empty assert "No target provided" in msg def test_run_scan_list_user_spaces_no_targets(monkeypatch): def fake_list_user_spaces(target, hf_token=None): return [], "no spaces found" monkeypatch.setattr(app_mod, "list_user_spaces", fake_list_user_spaces) df, msg, log, report_html, report_path = app_mod.run_scan( "someuser", "", False, True, False, 5, True, True, True, True, progress=noop_progress ) assert isinstance(df, pd.DataFrame) assert df.empty assert msg.startswith("❌") assert report_html is None assert report_path is None def test_run_scan_success_generates_reports(monkeypatch, tmp_path): findings = [ { "category": "security", "severity": "ERROR", "confidence": "confirmed", "tool": "bandit", "rule": "B602", "file": "src/runner.py", "line": 42, "message": "subprocess with shell=True", "owasp": ["A03"], "remediation": "Use list args", } ] def fake_scan_repo(t, hf_token=None, deep_history=False, run_security=True, run_performance=True, run_llm=True, run_supply_chain=True, progress_cb=None): return findings, ["scan ok"] monkeypatch.setattr(app_mod, "scan_repo", fake_scan_repo) monkeypatch.setattr(app_mod, "generate_html_report", lambda f, m: "ok") monkeypatch.setattr(app_mod, "generate_sarif", lambda f, m: {"sarif": True}) df, summary, log, report_html, report_path = app_mod.run_scan( "https://example.com/repo", "", False, False, False, 1, True, True, True, True, progress=noop_progress ) assert not df.empty assert report_html == "ok" assert isinstance(report_path, str) and report_path.endswith(".html") assert os.path.exists(report_path) def test_run_scan_comment_calls_comment_on_space(monkeypatch): findings = [ { "category": "security", "severity": "ERROR", "confidence": "confirmed", "tool": "bandit", "rule": "B602", "file": "src/runner.py", "line": 42, "message": "subprocess with shell=True", "owasp": ["A03"], "remediation": "Use list args", } ] def fake_scan_repo(t, hf_token=None, deep_history=False, run_security=True, run_performance=True, run_llm=True, run_supply_chain=True, progress_cb=None): return findings, ["scan ok"] called = {} def fake_comment_on_space(t, hf_token, findings_): called['args'] = (t, hf_token, findings_) return "commented" monkeypatch.setattr(app_mod, "scan_repo", fake_scan_repo) monkeypatch.setattr(app_mod, "generate_html_report", lambda f, m: "ok") monkeypatch.setattr(app_mod, "generate_sarif", lambda f, m: {"sarif": True}) monkeypatch.setattr(app_mod, "comment_on_space", fake_comment_on_space) df, summary, log, report_html, report_path = app_mod.run_scan( "https://huggingface.co/spaces/user/space", "token", True, False, False, 1, True, True, True, True, progress=noop_progress ) assert 'args' in called assert called['args'][0].startswith("https://huggingface.co/spaces/")