Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions scripts/ci/opencode_review_normalize_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ def iter_json_objects(text: str) -> list[Any]:
return values


def project_root() -> Path:
return Path(__file__).resolve().parents[2]


def main(argv: list[str]) -> int:
if len(argv) != 5:
print(
Expand All @@ -132,9 +136,9 @@ def main(argv: list[str]) -> int:

expected_head_sha, expected_run_id, expected_run_attempt, output_file_arg = argv[1:]
output_file = Path(output_file_arg)
project_root = Path.cwd().resolve()
root = project_root()

if not output_file.resolve().is_relative_to(project_root):
if not output_file.resolve().is_relative_to(root):
print(f"error: output file path {output_file_arg!r} is outside the project root", file=sys.stderr)
return 65

Expand Down
13 changes: 12 additions & 1 deletion tests/scripts/ci/test_opencode_review_normalize_output.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import pytest

from scripts.ci.opencode_review_normalize_output import valid_control
from scripts.ci.opencode_review_normalize_output import main, valid_control

def test_valid_control_approve():
value = {
Expand Down Expand Up @@ -164,3 +164,14 @@ def test_valid_control_invalid_findings():
finding[field] = " "
val = dict(base, findings=[finding])
assert valid_control(val, expected_head_sha="sha", expected_run_id="id", expected_run_attempt="1") is None


def test_main_rejects_output_file_outside_repo(monkeypatch, tmp_path, capsys):
monkeypatch.chdir(tmp_path)
output_file = tmp_path / "review.json"
output_file.write_text("{}", encoding="utf-8")

exit_code = main(["prog", "sha123", "run123", "1", str(output_file)])

assert exit_code == 65
assert "outside the project root" in capsys.readouterr().err
20 changes: 18 additions & 2 deletions tests/test_vibesec.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import pytest

from scanner.cli.vibesec import _collect_files, _print_scan_results, _scan_file, cmd_init, cmd_scan, cmd_review, REVIEW_PROMPT_BASE, REVIEW_PROMPT_NEXTJS, REVIEW_PROMPT_SUPABASE, REVIEW_PROMPT_FIREBASE, REVIEW_PROMPT_STRIPE, REVIEW_PROMPT_FOOTER
from scanner.cli.vibesec import _collect_files, _print_scan_results, _print_supabase_reminder, _scan_file, cmd_init, cmd_review, cmd_scan, REVIEW_PROMPT_BASE, REVIEW_PROMPT_FIREBASE, REVIEW_PROMPT_FOOTER, REVIEW_PROMPT_NEXTJS, REVIEW_PROMPT_STRIPE, REVIEW_PROMPT_SUPABASE

MOCK_RULES = [
{
Expand Down Expand Up @@ -458,6 +458,16 @@ def test_sanitize_terminal_output():
# Test non-strings
assert _sanitize_terminal_output(None) is None

def test_print_supabase_reminder(capsys):
_print_supabase_reminder()
captured = capsys.readouterr()

assert "Supabase stack detected. Quick reminders:" in captured.out
assert "Enable RLS on every user-data table" in captured.out
assert "Use getUser() not getSession() on the server" in captured.out
assert "Keep SUPABASE_SERVICE_ROLE_KEY server-side only" in captured.out


def test_collect_files_oserror_on_scandir(tmp_path):
(tmp_path / "dir1").mkdir()
(tmp_path / "dir1" / "file1.py").touch()
Expand Down Expand Up @@ -506,7 +516,6 @@ def __iter__(self):
yield MockEntry(entry)

return MockIterator(original_scandir(path))

with patch("os.scandir", side_effect=mock_scandir):
files = list(_collect_files(tmp_path))
assert len(files) == 1
Expand All @@ -526,42 +535,49 @@ def test_cmd_review_base_prompt(capsys):
assert REVIEW_PROMPT_FIREBASE not in captured.out
assert REVIEW_PROMPT_STRIPE not in captured.out


def test_cmd_review_nextjs(capsys):
args = Namespace(stack=["nextjs"], db=None, payments=None)
cmd_review(args)
captured = capsys.readouterr()
assert REVIEW_PROMPT_NEXTJS in captured.out


def test_cmd_review_supabase(capsys):
args = Namespace(stack=None, db="supabase", payments=None)
cmd_review(args)
captured = capsys.readouterr()
assert REVIEW_PROMPT_SUPABASE in captured.out


def test_cmd_review_supabase_via_stack(capsys):
args = Namespace(stack=["supabase"], db=None, payments=None)
cmd_review(args)
captured = capsys.readouterr()
assert REVIEW_PROMPT_SUPABASE in captured.out


def test_cmd_review_firebase(capsys):
args = Namespace(stack=None, db="firebase", payments=None)
cmd_review(args)
captured = capsys.readouterr()
assert REVIEW_PROMPT_FIREBASE in captured.out


def test_cmd_review_firebase_via_stack(capsys):
args = Namespace(stack=["firebase"], db=None, payments=None)
cmd_review(args)
captured = capsys.readouterr()
assert REVIEW_PROMPT_FIREBASE in captured.out


def test_cmd_review_stripe(capsys):
args = Namespace(stack=None, db=None, payments="stripe")
cmd_review(args)
captured = capsys.readouterr()
assert REVIEW_PROMPT_STRIPE in captured.out


def test_cmd_review_all_options(capsys):
args = Namespace(stack=["nextjs"], db="supabase", payments="stripe")
cmd_review(args)
Expand Down
Loading