test_schemas.py
1 """Tests for autoreview.schemas (Pydantic review payload).""" 2 from __future__ import annotations 3 4 import logging 5 6 import pytest 7 8 from autoreview.schemas import ReviewPayload, SuggestionItem 9 10 11 def test_suggestion_severity_case_and_invalid() -> None: 12 assert SuggestionItem(severity="HIGH").severity == "high" 13 assert SuggestionItem(severity="Low").severity == "low" 14 assert SuggestionItem(severity="bogus").severity == "medium" 15 assert SuggestionItem(severity=None).severity == "medium" 16 17 18 def test_suggestion_detail_strip_and_none() -> None: 19 assert SuggestionItem(detail=" x ").detail == "x" 20 assert SuggestionItem(detail=None).detail == "" 21 22 23 def test_review_payload_coerce_text_str_and_none() -> None: 24 m = ReviewPayload.model_validate( 25 { 26 "security": "ok", 27 "code_quality": None, 28 "structure": "", 29 } 30 ) 31 assert m.security == "ok" 32 assert m.code_quality == "" 33 assert m.structure == "" 34 35 36 def test_review_payload_coerce_text_number_to_str() -> None: 37 m = ReviewPayload.model_validate({"security": 42, "performance": 3.14}) 38 assert m.security == "42" 39 assert m.performance == "3.14" 40 41 42 def test_review_payload_coerce_text_non_str_logs_debug(caplog: pytest.LogCaptureFixture) -> None: 43 caplog.set_level(logging.DEBUG, logger="autoreview.schemas") 44 m = ReviewPayload.model_validate({"security": object()}) 45 assert "object at" in m.security 46 assert "Review field expected str" in caplog.text 47 48 49 def test_review_payload_extra_keys_ignored() -> None: 50 m = ReviewPayload.model_validate({"security": "x", "unknown_field": 1, "foo": "bar"}) 51 assert m.security == "x" 52 assert not hasattr(m, "unknown_field") 53 54 55 def test_review_payload_suggestions_from_dicts() -> None: 56 m = ReviewPayload.model_validate( 57 { 58 "suggestions": [ 59 {"severity": "HIGH", "detail": " z "}, 60 {"severity": "nope", "detail": "y"}, 61 ] 62 } 63 ) 64 assert len(m.suggestions) == 2 65 assert m.suggestions[0].severity == "high" 66 assert m.suggestions[0].detail == "z" 67 assert m.suggestions[1].severity == "medium" 68 assert m.suggestions[1].detail == "y" 69 70 71 def test_to_report_dict_shape() -> None: 72 m = ReviewPayload( 73 security="a", 74 suggestions=[SuggestionItem(severity="low", detail="b")], 75 ) 76 d = m.to_report_dict() 77 assert d["security"] == "a" 78 assert d["suggestions"] == [{"severity": "low", "detail": "b"}]