Files
hate_crack/TESTING.md
Justin Bollinger aa9d326e2d chore: remove GitHub Actions workflows
Quality checks run locally via prek pre-push hooks. CI workflows
(ruff, ty, pytest, lint-infra, version-bump) are no longer needed.
Updated docs to remove all GitHub Actions references.
2026-03-03 14:42:57 -05:00

140 lines
5.4 KiB
Markdown

# Testing
## Quick Start
```bash
# Run all tests (auto-sets HATE_CRACK_SKIP_INIT when needed)
make test
# With coverage
make coverage
```
## Environment Variables
| Variable | Purpose |
|----------|---------|
| `HATE_CRACK_SKIP_INIT=1` | Skip binary/config validation at startup. Required in worktrees and CI where submodules are not built. `make test` sets this automatically. |
| `HASHMOB_TEST_REAL=1` | Enable live Hashmob connectivity tests |
| `HASHVIEW_TEST_REAL=1` | Enable live Hashview CLI menu tests |
| `WEAKPASS_TEST_REAL=1` | Enable live Weakpass CLI menu tests |
| `HATE_CRACK_REQUIRE_DEPS=1` | Fail if `7z` or `transmission-cli` are missing |
| `HATE_CRACK_RUN_LIVE_TESTS=1` | Enable live Hashview upload test (requires valid credentials in `config.json`) |
| `HATE_CRACK_RUN_LIVE_HASHVIEW_TESTS=1` | Enable live Hashview wordlist upload test |
| `HATE_CRACK_RUN_E2E=1` | Enable local uv tool install E2E test |
| `HATE_CRACK_RUN_DOCKER_TESTS=1` | Enable Docker-based E2E test |
| `HATE_CRACK_RUN_LIMA_TESTS=1` | Enable Lima VM E2E test (macOS, requires `limactl`) |
## Running Tests Directly
```bash
# All tests
uv run pytest -v
# Single file
HATE_CRACK_SKIP_INIT=1 uv run pytest tests/test_attacks_behavior.py -v
# Specific test
uv run pytest tests/test_hashview.py::TestHashviewAPI::test_create_job_workflow -v
# With coverage
uv run pytest --cov=hate_crack --cov-report=term-missing
```
## Test Files
### Unit / Offline Tests (always run)
No external services, binaries, or network access required.
| File | What it covers |
|------|---------------|
| `test_attacks_behavior.py` | Attack handler logic via mocked `ctx` |
| `test_hashcat_wrappers.py` | Low-level hashcat subprocess wrappers |
| `test_api.py` | Hashview, Weakpass, Hashmob API clients (mocked HTTP) |
| `test_api_downloads.py` | Download helpers and file extraction |
| `test_cli_menus.py` | CLI argument parsing and menu dispatch |
| `test_cli_weakpass.py` | Weakpass CLI subcommands |
| `test_hashview.py` | HashviewAPI class (mocked responses) |
| `test_hashview_cli_subcommands.py` | Hashview CLI subcommand routing |
| `test_hashview_cli_subcommands_subprocess.py` | Hashview subcommands via subprocess |
| `test_ui_menu_options.py` | Menu option snapshot tests via `CLI_MODULE` |
| `test_proxy.py` | `hate_crack.py` proxy to `hate_crack.main` |
| `test_main_utils.py` | Utility functions in `main.py` |
| `test_utils.py` | Shared utility helpers |
| `test_ntlm_preprocessing.py` | NTLM hash preprocessing |
| `test_ntlm_preprocessing_edge_cases.py` | Edge cases for NTLM preprocessing |
| `test_fingerprint_expander_and_hybrid.py` | Fingerprint and hybrid attack helpers |
| `test_hashcat_rules.py` | Hashcat rule parsing and analysis |
| `test_asset_path_separation.py` | `hate_path` vs `hcatPath` path distinction |
| `test_invalid_hcatpath.py` | Startup error on invalid hashcat path |
| `test_version_check.py` | Update check logic |
| `test_omen_attack.py` | OMEN attack handler |
| `test_pipal.py` | Pipal integration helpers |
| `test_pipal_integration.py` | Pipal menu and output parsing |
| `test_dependencies.py` | External dependency detection |
| `test_hashmob_connectivity.py` | Hashmob connectivity check (mocked by default) |
### Opt-In Tests
#### Live API
```bash
HASHMOB_TEST_REAL=1 uv run pytest tests/test_hashmob_connectivity.py -v
HASHVIEW_TEST_REAL=1 uv run pytest tests/test_cli_menus.py -v
WEAKPASS_TEST_REAL=1 uv run pytest tests/test_cli_weakpass.py -v
```
#### Live Hashview Upload
Requires valid `hashview_url` and `hashview_api_key` in `config.json`.
```bash
HATE_CRACK_RUN_LIVE_TESTS=1 uv run pytest tests/test_upload_cracked_hashes.py -v
HATE_CRACK_RUN_LIVE_HASHVIEW_TESTS=1 uv run pytest tests/test_upload_wordlist.py -v
```
#### Submodules
Requires built submodules (`make` first).
```bash
uv run pytest tests/test_submodule_hashcat_utils.py -v
```
#### End-to-End
```bash
# Local uv tool install (creates a temporary HOME)
HATE_CRACK_RUN_E2E=1 uv run pytest tests/test_e2e_local_install.py -v
# Docker-based full install and basic hashcat crack
HATE_CRACK_RUN_DOCKER_TESTS=1 uv run pytest tests/test_docker_script_install.py -v
# Lima VM install (macOS only, requires: brew install lima)
HATE_CRACK_RUN_LIMA_TESTS=1 uv run pytest tests/test_lima_vm_install.py -v
# Installed tool smoke test
uv run pytest tests/test_installed_tool_execution.py -v
uv run pytest tests/test_uv_tool_install_dryrun.py -v
```
The Lima test provisions a real Ubuntu 24.04 VM via [Lima](https://lima-vm.io/). The first run is slow (VM provisioning + apt-get). The VM is named uniquely per session and deleted in teardown - verify cleanup with `limactl list`.
## Test Architecture
- **`conftest.py`** - Provides the `hc_module` fixture via `load_hate_crack_module()`, which dynamically imports `hate_crack.py` with `HATE_CRACK_SKIP_INIT=1`. Each test gets an isolated module instance.
- **`CLI_MODULE`** - Menu option tests patch against this reference to exercise the proxy layer between `hate_crack.py` and `hate_crack.main`.
- **HTTP mocking** - API tests mock `requests` at the boundary. No real network calls in offline tests.
- **Subprocess mocking** - Hashcat wrapper tests mock `subprocess.Popen`; no hashcat binary required.
Pre-push hooks (via [prek](https://github.com/j178/prek)) run `ruff`, `ty`, and `pytest` locally before each push:
```bash
# Install hooks
prek install --hook-type pre-push --hook-type post-commit
# Run manually
prek run
```