fieldwitness/tests/test_paths.py
Aaron D. Lee 16318daea3
Some checks failed
CI / lint (push) Failing after 12s
CI / typecheck (push) Failing after 12s
Add comprehensive test suite: integration tests + Playwright e2e
Integration tests (350 passing):
- test_evidence_summary.py: HTML/PDF generation, XSS safety, anchor rendering
- test_tor.py: Tor module unit tests (mocked, no Tor needed)
- test_c2pa_importer.py: Import result dataclass, trust evaluation, graceful degradation
- test_file_attestation.py: All file types (PNG, PDF, CSV, empty, large), determinism
- test_paths.py: Registry correctness, env var override, all paths under BASE_DIR
- test_killswitch_coverage.py: Tor keys, trusted keys, carrier history destruction

Playwright e2e infrastructure:
- tests/e2e/ with conftest (live server, auth fixtures), helpers (test file generators)
- test_auth.py: Setup flow, login/logout, protected routes
- test_attest.py: Image/PDF/CSV attestation, verify, attestation log
- test_dropbox.py: Token creation, source upload, branding check
- test_keys.py: Identity display, trust store
- test_fieldkit.py: Status dashboard, killswitch page
- test_navigation.py: All nav links, responsive layout

Run: pytest (unit/integration) or pytest -m e2e tests/e2e/ (browser)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 20:22:12 -04:00

218 lines
7.8 KiB
Python

"""Tests for the centralized path registry (fieldwitness/paths.py)."""
from __future__ import annotations
from pathlib import Path
import pytest
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
def _fresh_paths_module(monkeypatch: pytest.MonkeyPatch, base_dir: Path):
"""Return the paths module with BASE_DIR patched to base_dir.
The monkeypatch is applied to the already-imported module attribute so that
__getattr__ picks up the new value on subsequent calls.
"""
import fieldwitness.paths as paths
monkeypatch.setattr(paths, "BASE_DIR", base_dir)
return paths
# ---------------------------------------------------------------------------
# test_base_dir_default_is_fwmetadata
# ---------------------------------------------------------------------------
class TestBaseDirDefault:
def test_default_base_dir_ends_with_fwmetadata(self, monkeypatch):
"""Verify the default data directory name is .fwmetadata."""
import os
monkeypatch.delenv("FIELDWITNESS_DATA_DIR", raising=False)
# Re-derive the default the same way paths.py does at import time.
default = Path.home() / ".fwmetadata"
assert default.name == ".fwmetadata"
def test_default_base_dir_is_under_home(self, monkeypatch):
"""Verify the default data directory is under the user's home."""
monkeypatch.delenv("FIELDWITNESS_DATA_DIR", raising=False)
default = Path.home() / ".fwmetadata"
assert str(default).startswith(str(Path.home()))
# ---------------------------------------------------------------------------
# test_base_dir_override_via_env
# ---------------------------------------------------------------------------
class TestBaseDirOverrideViaEnv:
def test_env_override_changes_base_dir(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
):
"""Setting FIELDWITNESS_DATA_DIR must relocate BASE_DIR."""
custom = tmp_path / "custom-fw-dir"
monkeypatch.setenv("FIELDWITNESS_DATA_DIR", str(custom))
# Re-evaluate the path that the module would compute at import time.
# Since BASE_DIR is module-level, we test it after patching the attribute.
import fieldwitness.paths as paths
monkeypatch.setattr(paths, "BASE_DIR", custom)
assert paths.BASE_DIR == custom
def test_derived_paths_follow_overridden_base_dir(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
):
"""Derived paths (IDENTITY_DIR etc.) must be under the overridden BASE_DIR."""
custom = tmp_path / "relocated"
paths = _fresh_paths_module(monkeypatch, custom)
assert str(paths.IDENTITY_DIR).startswith(str(custom))
assert str(paths.CHAIN_DIR).startswith(str(custom))
assert str(paths.ATTESTATIONS_DIR).startswith(str(custom))
# ---------------------------------------------------------------------------
# test_trusted_keys_dir_exists
# ---------------------------------------------------------------------------
class TestTrustedKeysDirDefined:
def test_trusted_keys_dir_is_defined(self):
import fieldwitness.paths as paths
# Access must not raise AttributeError
td = paths.TRUSTED_KEYS_DIR
assert isinstance(td, Path)
def test_trusted_keys_dir_under_base_dir(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
):
paths = _fresh_paths_module(monkeypatch, tmp_path / ".fwmetadata")
assert str(paths.TRUSTED_KEYS_DIR).startswith(str(paths.BASE_DIR))
def test_trusted_keys_dir_name(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
paths = _fresh_paths_module(monkeypatch, tmp_path / ".fw")
assert paths.TRUSTED_KEYS_DIR.name == "trusted_keys"
# ---------------------------------------------------------------------------
# test_carrier_history_exists
# ---------------------------------------------------------------------------
class TestCarrierHistoryDefined:
def test_carrier_history_is_defined(self):
import fieldwitness.paths as paths
ch = paths.CARRIER_HISTORY
assert isinstance(ch, Path)
def test_carrier_history_under_base_dir(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
):
paths = _fresh_paths_module(monkeypatch, tmp_path / ".fwmetadata")
assert str(paths.CARRIER_HISTORY).startswith(str(paths.BASE_DIR))
def test_carrier_history_filename(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
paths = _fresh_paths_module(monkeypatch, tmp_path / ".fw")
assert paths.CARRIER_HISTORY.name == "carrier_history.json"
# ---------------------------------------------------------------------------
# test_tor_dir_exists
# ---------------------------------------------------------------------------
class TestTorDirDefined:
def test_tor_dir_is_defined(self):
import fieldwitness.paths as paths
td = paths.TOR_DIR
assert isinstance(td, Path)
def test_tor_hidden_service_dir_is_defined(self):
import fieldwitness.paths as paths
hs = paths.TOR_HIDDEN_SERVICE_DIR
assert isinstance(hs, Path)
def test_tor_hidden_service_dir_under_tor_dir(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
):
paths = _fresh_paths_module(monkeypatch, tmp_path / ".fwmetadata")
assert str(paths.TOR_HIDDEN_SERVICE_DIR).startswith(str(paths.TOR_DIR))
def test_tor_dir_under_fieldkit_dir(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
):
paths = _fresh_paths_module(monkeypatch, tmp_path / ".fwmetadata")
assert str(paths.TOR_DIR).startswith(str(paths.FIELDKIT_DIR))
# ---------------------------------------------------------------------------
# test_all_paths_under_base_dir
# ---------------------------------------------------------------------------
class TestAllPathsUnderBaseDir:
# Names that are files directly under BASE_DIR (one-segment paths where
# the parent IS BASE_DIR, not a sub-directory).
_SINGLE_SEGMENT = {"AUDIT_LOG", "CONFIG_FILE", "CARRIER_HISTORY", "LAST_BACKUP"}
def test_every_defined_path_is_under_base_dir(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
):
"""Every path in _PATH_DEFS must resolve to a location inside BASE_DIR."""
import fieldwitness.paths as _paths_module
base = tmp_path / ".fwmetadata"
monkeypatch.setattr(_paths_module, "BASE_DIR", base)
for name in _paths_module._PATH_DEFS:
resolved: Path = _paths_module.__getattr__(name)
assert str(resolved).startswith(str(base)), (
f"Path {name!r} resolves to {resolved}, which is outside BASE_DIR {base}"
)
def test_no_absolute_hardcoded_paths_outside_base(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
):
"""Changing BASE_DIR must change ALL derived paths — no hardcoded roots."""
import fieldwitness.paths as _paths_module
original_base = _paths_module.BASE_DIR
new_base = tmp_path / "relocated"
monkeypatch.setattr(_paths_module, "BASE_DIR", new_base)
for name in _paths_module._PATH_DEFS:
resolved: Path = _paths_module.__getattr__(name)
# Must be under the new base, not the original one
assert str(resolved).startswith(str(new_base)), (
f"Path {name!r} still points under the old BASE_DIR after override"
)
def test_path_defs_is_non_empty(self):
import fieldwitness.paths as paths
assert len(paths._PATH_DEFS) > 0
def test_unknown_attribute_raises_attribute_error(self):
import fieldwitness.paths as paths
with pytest.raises(AttributeError):
paths.__getattr__("DOES_NOT_EXIST_9999")