Files
hate_crack/tests/conftest.py
Justin BollingerandClaude Opus 4.8 048ed7cac1 feat(test): run live Hashview tests against a local docker stack
The live Hashview tests previously could only run against a remote server
configured in config.json, and the CLI ignored env-var overrides, so the
suite always hit prod. Prod runs an older Hashview whose /v1/jobs/add 500s
on a notify_email kwarg, which masked real client/server drift.

Wire the suite up to a local Hashview docker stack:

- main.py: HASHVIEW_URL / HASHVIEW_API_KEY env vars now override config.json,
  so the CLI can be pointed at a local instance without editing config.
- tests/_hashview_local.py + pytest_configure: when HASHVIEW_TEST_LOCAL=1,
  bring up + seed the Hashview compose stack (HASHVIEW_REPO), verify
  authenticated API access, export the HASHVIEW_* env, and tear down
  (HASHVIEW_KEEP=1 keeps it). Runs in configure so collection-time skipif
  on HASHVIEW_TEST_REAL sees the exported env.
- tests/hashview_local_seed.py: seed an admin api_key + non-default password
  (else Hashview's setup guard redirects every request to /setup), a
  customer, a hashfile, and cracked "effective task" data (else /v1/jobs/add
  has no tasks to schedule).
- api.py: download_left_hashes now uses GET /v1/hashfiles/<id>; the old
  /v1/hashfiles/<id>/left route 404s on current servers.
- subprocess tests: assert on the CLI's actual output ("Job ID:") rather than
  the literal "Job created", and strip ambient HASHVIEW_* creds from the
  no-key-configured check so the env override doesn't defeat it.
- README/CLAUDE: document HASHVIEW_TEST_LOCAL and the env overrides.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 10:17:49 -04:00

82 lines
2.7 KiB
Python

import importlib.util
import sys
from pathlib import Path
import pytest
def load_hate_crack_module(monkeypatch):
monkeypatch.setenv("HATE_CRACK_SKIP_INIT", "1")
module_path = Path(__file__).resolve().parents[1] / "hate_crack.py"
module_name = "hate_crack_script"
if module_name in sys.modules:
del sys.modules[module_name]
spec = importlib.util.spec_from_file_location(module_name, module_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
@pytest.fixture
def hc_module(monkeypatch):
return load_hate_crack_module(monkeypatch)
@pytest.fixture(autouse=True)
def _isolate_notify_state():
"""Reset notify module state between tests.
``hate_crack.main`` calls ``notify.init()`` at import time with whatever
``config.json`` is resolved from the user's environment (e.g.
``~/.hate_crack/config.json``). If that config has
``notify_enabled: true``, the per-attack prompt in ``attacks.py`` fires
``input()`` during tests and blows up capture. Forcing the notify
package back to its disabled-by-default state before every test keeps
the suite hermetic regardless of the developer's local config.
"""
try:
from hate_crack import notify
except ImportError:
yield
return
notify.clear_state_for_tests()
yield
notify.clear_state_for_tests()
def pytest_configure(config):
"""Spin up + seed a local Hashview docker stack for the live test suite.
No-op unless ``HASHVIEW_TEST_LOCAL=1``. When enabled, brings up the stack
from the hashview repo, seeds the DB, and exports the ``HASHVIEW_*`` env
vars the live tests (and the hate_crack CLI) read so they target the local
instance instead of whatever ``config.json`` points at.
This runs in ``pytest_configure`` — *before* collection — on purpose: the
live subprocess tests gate on ``HASHVIEW_TEST_REAL`` via ``@skipif``, which
is evaluated at collection time. A session fixture would set the env too
late and every live test would skip. On failure we deliberately leave
``HASHVIEW_TEST_REAL`` unset so the live tests skip with their normal
reason rather than erroring. See ``tests/_hashview_local.py`` for config.
"""
from tests import _hashview_local as hv
if not hv.enabled():
return
reason = hv.setup()
if reason is not None:
config.issue_config_time_warning(
pytest.PytestWarning(
f"HASHVIEW_TEST_LOCAL set but local stack unavailable "
f"({reason}); live Hashview tests will skip."
),
stacklevel=2,
)
def pytest_unconfigure(config):
from tests import _hashview_local as hv
if hv.enabled():
hv.teardown()