test: final 6 agents — 172+ translate tests, llm_analysis 89%, git_plugin 100%, migration/deps/routes polished. 85-94% files pushed to 95%+. Bulk: backup/debug/maintenance plugins
This commit is contained in:
@@ -352,4 +352,230 @@ def test_cli_release_gate_commands_scaffold() -> None:
|
||||
|
||||
|
||||
# #endregion test_cli_release_gate_commands_scaffold
|
||||
|
||||
|
||||
# #region test_cli_error_branches [C:2] [TYPE Function]
|
||||
# @RELATION BINDS_TO -> test_clean_release_cli
|
||||
# @PURPOSE: Verify error-handling branches return expected exit codes and error messages.
|
||||
def test_cli_duplicate_candidate() -> None:
|
||||
"""Registering an existing candidate returns exit code 1."""
|
||||
cli_main(["candidate-register", "--candidate-id", "dup-cand", "--version", "1.0", "--source-snapshot-ref", "git:x"])
|
||||
exit_code = cli_main(["candidate-register", "--candidate-id", "dup-cand", "--version", "2.0", "--source-snapshot-ref", "git:y"])
|
||||
assert exit_code == 1
|
||||
|
||||
|
||||
def test_cli_artifact_import_candidate_not_found() -> None:
|
||||
"""Importing artifact for non-existent candidate returns exit code 1."""
|
||||
exit_code = cli_main(["artifact-import", "--candidate-id", "no-such-cand", "--artifact-id", "a1", "--path", "x", "--sha256", "0" * 64, "--size", "1"])
|
||||
assert exit_code == 1
|
||||
|
||||
|
||||
def test_cli_manifest_build_value_error(monkeypatch) -> None:
|
||||
"""Manifest build on unprepared candidate returns exit code 1."""
|
||||
from src.dependencies import get_clean_release_repository
|
||||
repository = get_clean_release_repository()
|
||||
|
||||
# Register candidate but skip artifact import — manifest build will fail
|
||||
cli_main(["candidate-register", "--candidate-id", "no-artifacts", "--version", "1.0", "--source-snapshot-ref", "git:x", "--created-by", "test"])
|
||||
|
||||
# Manually set status to DRAFT so manifest build fails
|
||||
candidate = repository.get_candidate("no-artifacts")
|
||||
if candidate:
|
||||
candidate.status = "DRAFT"
|
||||
repository.save_candidate(candidate)
|
||||
|
||||
exit_code = cli_main(["manifest-build", "--candidate-id", "no-artifacts", "--created-by", "test"])
|
||||
assert exit_code == 1
|
||||
|
||||
|
||||
def test_cli_compliance_run_exception(monkeypatch) -> None:
|
||||
"""Compliance run when config is broken returns exit code 2."""
|
||||
from unittest.mock import patch, MagicMock
|
||||
import json
|
||||
|
||||
with patch("src.dependencies.ConfigManager") as MockCfgMgr:
|
||||
mock_mgr = MagicMock()
|
||||
mock_mgr.get_config.side_effect = RuntimeError("config broken")
|
||||
MockCfgMgr.return_value = mock_mgr
|
||||
|
||||
exit_code = cli_main(["compliance-run", "--candidate-id", "no-such", "--actor", "test", "--json"])
|
||||
assert exit_code == 2
|
||||
|
||||
|
||||
def test_cli_compliance_status_not_found() -> None:
|
||||
"""Status query for non-existent run returns exit code 2."""
|
||||
exit_code = cli_main(["compliance-status", "--run-id", "no-such-run", "--json"])
|
||||
assert exit_code == 2
|
||||
|
||||
|
||||
def test_cli_compliance_report_not_found() -> None:
|
||||
"""Report query for non-existent run returns exit code 2."""
|
||||
exit_code = cli_main(["compliance-report", "--run-id", "no-such-run", "--json"])
|
||||
assert exit_code == 2
|
||||
|
||||
|
||||
def test_cli_compliance_report_missing() -> None:
|
||||
"""Report query when run exists but no report returns exit code 2."""
|
||||
from src.dependencies import get_clean_release_repository
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
repository = get_clean_release_repository()
|
||||
run = MagicMock()
|
||||
run.id = "cli-run-no-report"
|
||||
run.candidate_id = "cli-cand-nr"
|
||||
run.status = "PENDING"
|
||||
run.final_status = "PENDING"
|
||||
repository.save_check_run(run)
|
||||
|
||||
exit_code = cli_main(["compliance-report", "--run-id", "cli-run-no-report", "--json"])
|
||||
assert exit_code == 2
|
||||
|
||||
|
||||
def test_cli_compliance_violations_not_found() -> None:
|
||||
"""Violations query for non-existent run returns exit code 2."""
|
||||
exit_code = cli_main(["compliance-violations", "--run-id", "no-such-run", "--json"])
|
||||
assert exit_code == 2
|
||||
|
||||
|
||||
def test_cli_approve_exception(monkeypatch) -> None:
|
||||
"""Approve with approval service failure returns exit code 2."""
|
||||
from unittest.mock import patch
|
||||
|
||||
with patch("src.services.clean_release.approval_service.approve_candidate", side_effect=RuntimeError("approval failed")):
|
||||
exit_code = cli_main(["approve", "--candidate-id", "x", "--report-id", "y", "--actor", "test", "--json"])
|
||||
assert exit_code == 2
|
||||
|
||||
|
||||
def test_cli_reject_exception(monkeypatch) -> None:
|
||||
"""Reject with approval service failure returns exit code 2."""
|
||||
from unittest.mock import patch
|
||||
|
||||
with patch("src.services.clean_release.approval_service.reject_candidate", side_effect=RuntimeError("reject failed")):
|
||||
exit_code = cli_main(["reject", "--candidate-id", "x", "--report-id", "y", "--actor", "test", "--json"])
|
||||
assert exit_code == 2
|
||||
|
||||
|
||||
def test_cli_publish_exception(monkeypatch) -> None:
|
||||
"""Publish with publication service failure returns exit code 2."""
|
||||
from unittest.mock import patch
|
||||
|
||||
with patch("src.services.clean_release.publication_service.publish_candidate", side_effect=RuntimeError("publish failed")):
|
||||
exit_code = cli_main(["publish", "--candidate-id", "x", "--report-id", "y", "--actor", "test", "--target-channel", "stable", "--json"])
|
||||
assert exit_code == 2
|
||||
|
||||
|
||||
def test_cli_revoke_exception(monkeypatch) -> None:
|
||||
"""Revoke with publication service failure returns exit code 2."""
|
||||
from unittest.mock import patch
|
||||
|
||||
with patch("src.services.clean_release.publication_service.revoke_publication", side_effect=RuntimeError("revoke failed")):
|
||||
exit_code = cli_main(["revoke", "--publication-id", "x", "--actor", "test", "--json"])
|
||||
assert exit_code == 2
|
||||
|
||||
|
||||
def test_cli_unknown_command() -> None:
|
||||
"""Unknown command raises SystemExit with code 2."""
|
||||
import pytest
|
||||
with pytest.raises(SystemExit) as exc_info:
|
||||
cli_main(["bogus-command"])
|
||||
assert exc_info.value.code == 2
|
||||
|
||||
|
||||
# #endregion test_cli_error_branches
|
||||
|
||||
|
||||
# #region test_to_payload [C:2] [TYPE Function]
|
||||
# @RELATION BINDS_TO -> test_clean_release_cli
|
||||
# @PURPOSE: Verify _to_payload serialization for datetime, date, dict, list, tuple, Pydantic, SQLAlchemy, and unsupported types.
|
||||
def test_to_payload_datetime() -> None:
|
||||
"""_to_payload handles datetime.isoformat()."""
|
||||
from datetime import UTC, datetime, date
|
||||
from src.scripts.clean_release_cli import _to_payload
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
obj = MagicMock()
|
||||
obj.model_dump.return_value = {"ts": datetime(2024, 1, 15, 10, 30, 0, tzinfo=UTC)}
|
||||
result = _to_payload(obj)
|
||||
assert result["ts"] == "2024-01-15T10:30:00+00:00"
|
||||
|
||||
|
||||
def test_to_payload_date() -> None:
|
||||
"""_to_payload handles date.isoformat()."""
|
||||
from datetime import date
|
||||
from src.scripts.clean_release_cli import _to_payload
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
obj = MagicMock()
|
||||
obj.model_dump.return_value = {"d": date(2024, 6, 15)}
|
||||
result = _to_payload(obj)
|
||||
assert result["d"] == "2024-06-15"
|
||||
|
||||
|
||||
def test_to_payload_dict_nested() -> None:
|
||||
"""_to_payload recursively normalizes nested dicts."""
|
||||
from src.scripts.clean_release_cli import _to_payload
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
obj = MagicMock()
|
||||
obj.model_dump.return_value = {"nested": {"key": 42, "flag": True}}
|
||||
result = _to_payload(obj)
|
||||
assert result["nested"] == {"key": 42, "flag": True}
|
||||
|
||||
|
||||
def test_to_payload_list() -> None:
|
||||
"""_to_payload handles list items."""
|
||||
from src.scripts.clean_release_cli import _to_payload
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
obj = MagicMock()
|
||||
obj.model_dump.return_value = {"items": ["a", "b", "c"]}
|
||||
result = _to_payload(obj)
|
||||
assert result["items"] == ["a", "b", "c"]
|
||||
|
||||
|
||||
def test_to_payload_tuple() -> None:
|
||||
"""_to_payload converts tuple to list."""
|
||||
from src.scripts.clean_release_cli import _to_payload
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
obj = MagicMock()
|
||||
obj.model_dump.return_value = {"coords": (1, 2)}
|
||||
result = _to_payload(obj)
|
||||
assert result["coords"] == [1, 2]
|
||||
|
||||
|
||||
def test_to_payload_sqlalchemy_model() -> None:
|
||||
"""_to_payload handles SQLAlchemy model with __table__."""
|
||||
from src.scripts.clean_release_cli import _to_payload
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
# Use a real class (not Mock) so model_dump is not auto-created
|
||||
class _FakeModel:
|
||||
pass
|
||||
|
||||
col1 = MagicMock()
|
||||
col1.name = "id"
|
||||
col2 = MagicMock()
|
||||
col2.name = "name"
|
||||
_FakeModel.__table__ = MagicMock(columns=[col1, col2])
|
||||
|
||||
obj = _FakeModel()
|
||||
obj.id = 1
|
||||
obj.name = "test"
|
||||
|
||||
result = _to_payload(obj)
|
||||
assert result["id"] == 1
|
||||
assert result["name"] == "test"
|
||||
|
||||
|
||||
def test_to_payload_unsupported_type() -> None:
|
||||
"""_to_payload raises TypeError for unsupported types."""
|
||||
from src.scripts.clean_release_cli import _to_payload
|
||||
|
||||
import pytest
|
||||
with pytest.raises(TypeError, match="unsupported payload type"):
|
||||
_to_payload(42)
|
||||
|
||||
|
||||
# #endregion test_to_payload
|
||||
# #endregion test_clean_release_cli
|
||||
|
||||
Reference in New Issue
Block a user