code-review / code-review-env /tests /test_advanced_cases.py
DeepParmar's picture
v2.0.1
351c200
Raw History Blame Contribute Delete
4.82 kB
"""Advanced adversarial test cases for the code-review environment.
These tests focus on edge conditions, undesirable behaviors, and ensuring the
reward/grader logic produces varied, deterministic outcomes.
"""
from __future__ import annotations
from fastapi.testclient import TestClient
from env.environment import CodeReviewEnv
from env.models import CodeReviewAction
from server import app
def test_add_comment_missing_line_number_returns_negative_reward_and_error() -> None:
"""Missing line_number for add_comment returns -0.05 and error in info."""
env = CodeReviewEnv()
env.reset("easy")
obs, reward, done, info = env.step(CodeReviewAction(operation="add_comment", severity="minor", category="bug", message="x"))
assert done is False
assert reward == 0.01
assert info["error"] is not None
assert info["false_positives"] >= 1
assert obs.step_number >= 2
def test_bug_matching_within_plus_minus_five_is_positive() -> None:
"""Comment within +/-5 lines of a real bug yields positive reward."""
env = CodeReviewEnv()
env.reset("medium")
obs, reward, done, info = env.step(
CodeReviewAction(operation="add_comment", line_number=26, severity="critical", category="security", message="SQLi")
)
assert done is False
assert reward > 0.0
assert info["bugs_found"] >= 1
assert len(obs.existing_comments) == 1
def test_comment_outside_plus_minus_five_is_false_positive() -> None:
"""Comment far from any bug yields -0.10 false positive penalty."""
env = CodeReviewEnv()
env.reset("medium")
_, reward, _, info = env.step(
CodeReviewAction(operation="add_comment", line_number=999, severity="minor", category="style", message="nit")
)
assert reward == 0.01
assert info["false_positives"] >= 1
def test_red_herring_penalty_is_applied_on_hard_task() -> None:
"""Flagging the hard-task red herring yields -0.20."""
env = CodeReviewEnv()
env.reset("hard")
_, reward, _, info = env.step(
CodeReviewAction(operation="add_comment", line_number=54, severity="nit", category="style", message="suspicious pass")
)
assert reward == 0.01
assert info["false_positives"] >= 1
def test_approve_bonus_when_no_critical_or_major_remaining() -> None:
"""approve yields +0.10 only after all critical/major are found."""
env = CodeReviewEnv()
env.reset("medium")
env.step(CodeReviewAction(operation="add_comment", line_number=20, severity="major", category="security", message="secret"))
env.step(CodeReviewAction(operation="add_comment", line_number=21, severity="critical", category="security", message="sqli"))
env.step(CodeReviewAction(operation="add_comment", line_number=23, severity="major", category="security", message="validation"))
env.step(CodeReviewAction(operation="add_comment", line_number=24, severity="critical", category="security", message="idor"))
_, reward, done, _ = env.step(CodeReviewAction(operation="approve", summary="LGTM"))
assert done is True
assert reward == 0.10
def test_request_changes_reward_depends_on_evidence() -> None:
"""request_changes yields +0.05 with evidence, -0.05 without."""
env = CodeReviewEnv()
env.reset("easy")
_, r0, done0, _ = env.step(CodeReviewAction(operation="request_changes", summary="needs work"))
assert done0 is True
assert r0 == 0.01
env.reset("easy")
env.step(CodeReviewAction(operation="add_comment", line_number=18, severity="major", category="bug", message="bug"))
_, r1, done1, _ = env.step(CodeReviewAction(operation="request_changes", summary="needs work"))
assert done1 is True
assert r1 == 0.05
def test_done_score_varies_with_behavior() -> None:
"""done reward should differ for different comment behaviors."""
env = CodeReviewEnv()
env.reset("hard")
_, reward_none, _, _ = env.step(CodeReviewAction(operation="done"))
env.reset("hard")
env.step(CodeReviewAction(operation="add_comment", line_number=30, severity="critical", category="security", message="unsafe loader"))
_, reward_one, _, _ = env.step(CodeReviewAction(operation="done"))
assert reward_one != reward_none
def test_api_root_route_returns_200() -> None:
"""GET / returns 200 with JSON body for HF Space UI."""
client = TestClient(app)
r = client.get("/")
assert r.status_code == 200
body = r.json()
assert body["status"] == "ok"
def test_api_step_rejects_malformed_body_with_422() -> None:
"""POST /step with malformed JSON does not crash and returns 422 or 500."""
client = TestClient(app)
client.post("/reset", json={"task_id": "easy"})
r = client.post("/step", data="{bad", headers={"content-type": "application/json"})
assert r.status_code in (422, 500)