|
| 1 | +import click |
| 2 | +import pytest |
| 3 | +import typer |
| 4 | + |
| 5 | +from cycode.cli.apps.scan.scan_command import scan_command_result_callback |
| 6 | +from cycode.cli.consts import ISSUE_DETECTED_STATUS_CODE, NO_ISSUES_STATUS_CODE, SCAN_ERROR_STATUS_CODE |
| 7 | + |
| 8 | + |
| 9 | +def _make_ctx(**obj_overrides: object) -> click.Context: |
| 10 | + obj = { |
| 11 | + 'soft_fail': False, |
| 12 | + 'did_fail': False, |
| 13 | + 'issue_detected': False, |
| 14 | + 'stop_on_error': False, |
| 15 | + } |
| 16 | + obj.update(obj_overrides) |
| 17 | + ctx = click.Context(click.Command('scan')) |
| 18 | + ctx.obj = obj |
| 19 | + return ctx |
| 20 | + |
| 21 | + |
| 22 | +def _invoke_result_callback(ctx: click.Context) -> int: |
| 23 | + with pytest.raises(typer.Exit) as exc_info, ctx: |
| 24 | + scan_command_result_callback() |
| 25 | + return exc_info.value.exit_code |
| 26 | + |
| 27 | + |
| 28 | +class TestScanCommandResultCallback: |
| 29 | + def test_no_issues_no_errors_exits_zero(self) -> None: |
| 30 | + assert _invoke_result_callback(_make_ctx()) == NO_ISSUES_STATUS_CODE |
| 31 | + |
| 32 | + def test_issue_detected_exits_one(self) -> None: |
| 33 | + assert _invoke_result_callback(_make_ctx(issue_detected=True)) == ISSUE_DETECTED_STATUS_CODE |
| 34 | + |
| 35 | + def test_did_fail_without_stop_on_error_exits_one(self) -> None: |
| 36 | + assert _invoke_result_callback(_make_ctx(did_fail=True)) == ISSUE_DETECTED_STATUS_CODE |
| 37 | + |
| 38 | + def test_did_fail_with_stop_on_error_exits_two(self) -> None: |
| 39 | + assert _invoke_result_callback(_make_ctx(did_fail=True, stop_on_error=True)) == SCAN_ERROR_STATUS_CODE |
| 40 | + |
| 41 | + def test_issue_detected_with_stop_on_error_exits_one(self) -> None: |
| 42 | + # stop_on_error only affects the error code path, not violations |
| 43 | + assert _invoke_result_callback(_make_ctx(issue_detected=True, stop_on_error=True)) == ISSUE_DETECTED_STATUS_CODE |
| 44 | + |
| 45 | + def test_soft_fail_overrides_violations(self) -> None: |
| 46 | + assert _invoke_result_callback(_make_ctx(soft_fail=True, issue_detected=True)) == NO_ISSUES_STATUS_CODE |
| 47 | + |
| 48 | + def test_soft_fail_overrides_stop_on_error(self) -> None: |
| 49 | + assert ( |
| 50 | + _invoke_result_callback(_make_ctx(soft_fail=True, did_fail=True, stop_on_error=True)) |
| 51 | + == NO_ISSUES_STATUS_CODE |
| 52 | + ) |
0 commit comments