mirror of
https://github.com/trustedsec/hate_crack.git
synced 2026-04-28 12:03:11 -07:00
117 lines
3.9 KiB
Python
117 lines
3.9 KiB
Python
from unittest.mock import MagicMock, patch
|
|
|
|
from hate_crack.menu import (
|
|
_arrow_menu,
|
|
_numbered_menu,
|
|
_use_arrow_menu,
|
|
interactive_menu,
|
|
)
|
|
|
|
SAMPLE_ITEMS = [
|
|
("1", "Quick Crack"),
|
|
("2", "Brute Force"),
|
|
("99", "Quit"),
|
|
]
|
|
|
|
|
|
class TestUseArrowMenu:
|
|
def test_falls_back_without_library(self, monkeypatch):
|
|
import hate_crack.menu as mod
|
|
|
|
monkeypatch.setattr(mod, "_HAS_TERM_MENU", False)
|
|
monkeypatch.delenv("HATE_CRACK_PLAIN_MENU", raising=False)
|
|
assert _use_arrow_menu() is False
|
|
|
|
def test_falls_back_on_non_tty(self, monkeypatch):
|
|
import hate_crack.menu as mod
|
|
|
|
monkeypatch.setattr(mod, "_HAS_TERM_MENU", True)
|
|
monkeypatch.delenv("HATE_CRACK_PLAIN_MENU", raising=False)
|
|
monkeypatch.setattr("sys.stdout.isatty", lambda: False)
|
|
assert _use_arrow_menu() is False
|
|
|
|
def test_falls_back_with_env_var(self, monkeypatch):
|
|
import hate_crack.menu as mod
|
|
|
|
monkeypatch.setattr(mod, "_HAS_TERM_MENU", True)
|
|
monkeypatch.setenv("HATE_CRACK_PLAIN_MENU", "1")
|
|
assert _use_arrow_menu() is False
|
|
|
|
def test_enabled_when_all_conditions_met(self, monkeypatch):
|
|
import hate_crack.menu as mod
|
|
|
|
monkeypatch.setattr(mod, "_HAS_TERM_MENU", True)
|
|
monkeypatch.delenv("HATE_CRACK_PLAIN_MENU", raising=False)
|
|
monkeypatch.setattr("sys.stdout.isatty", lambda: True)
|
|
assert _use_arrow_menu() is True
|
|
|
|
|
|
class TestNumberedMenu:
|
|
def test_returns_correct_key(self, monkeypatch):
|
|
monkeypatch.setattr("builtins.input", lambda _: "2")
|
|
result = _numbered_menu(SAMPLE_ITEMS, "\nSelect: ")
|
|
assert result == "2"
|
|
|
|
def test_prints_all_labels(self, monkeypatch, capsys):
|
|
monkeypatch.setattr("builtins.input", lambda _: "1")
|
|
_numbered_menu(SAMPLE_ITEMS, "\nSelect: ")
|
|
captured = capsys.readouterr().out
|
|
for key, label in SAMPLE_ITEMS:
|
|
assert f"({key}) {label}" in captured
|
|
|
|
def test_returns_none_on_empty_input(self, monkeypatch):
|
|
monkeypatch.setattr("builtins.input", lambda _: "")
|
|
result = _numbered_menu(SAMPLE_ITEMS, "\nSelect: ")
|
|
assert result is None
|
|
|
|
|
|
class TestArrowMenu:
|
|
def test_returns_correct_key(self):
|
|
mock_menu_instance = MagicMock()
|
|
mock_menu_instance.show.return_value = 1 # index 1 -> key "2"
|
|
with patch(
|
|
"hate_crack.menu.TerminalMenu",
|
|
create=True,
|
|
return_value=mock_menu_instance,
|
|
):
|
|
result = _arrow_menu(SAMPLE_ITEMS, "Title")
|
|
assert result == "2"
|
|
|
|
def test_returns_none_on_escape(self):
|
|
mock_menu_instance = MagicMock()
|
|
mock_menu_instance.show.return_value = None
|
|
with patch(
|
|
"hate_crack.menu.TerminalMenu",
|
|
create=True,
|
|
return_value=mock_menu_instance,
|
|
):
|
|
result = _arrow_menu(SAMPLE_ITEMS, "Title")
|
|
assert result is None
|
|
|
|
|
|
class TestInteractiveMenu:
|
|
def test_uses_numbered_when_no_tty(self, monkeypatch):
|
|
import hate_crack.menu as mod
|
|
|
|
monkeypatch.setattr(mod, "_HAS_TERM_MENU", False)
|
|
monkeypatch.delenv("HATE_CRACK_PLAIN_MENU", raising=False)
|
|
monkeypatch.setattr("builtins.input", lambda _: "99")
|
|
result = interactive_menu(SAMPLE_ITEMS)
|
|
assert result == "99"
|
|
|
|
def test_uses_arrow_when_available(self, monkeypatch):
|
|
import hate_crack.menu as mod
|
|
|
|
monkeypatch.setattr(mod, "_HAS_TERM_MENU", True)
|
|
monkeypatch.delenv("HATE_CRACK_PLAIN_MENU", raising=False)
|
|
monkeypatch.setattr("sys.stdout.isatty", lambda: True)
|
|
mock_menu_instance = MagicMock()
|
|
mock_menu_instance.show.return_value = 0
|
|
with patch(
|
|
"hate_crack.menu.TerminalMenu",
|
|
create=True,
|
|
return_value=mock_menu_instance,
|
|
):
|
|
result = interactive_menu(SAMPLE_ITEMS, title="Test")
|
|
assert result == "1"
|