88 lines
2.9 KiB
Python
88 lines
2.9 KiB
Python
|
|
"""Pure, offline tests for scripts/trf_onboard.py (WP-0006-T07).
|
||
|
|
|
||
|
|
No network call is made in these tests — they verify the offline
|
||
|
|
pre-flight validation short-circuits before any HTTP attempt, and that a
|
||
|
|
missing token env var fails loudly rather than silently sending an
|
||
|
|
unauthenticated request.
|
||
|
|
"""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import importlib.util
|
||
|
|
import json
|
||
|
|
import sys
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
from conftest import golden_manifest
|
||
|
|
|
||
|
|
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||
|
|
_SPEC = importlib.util.spec_from_file_location("trf_onboard", REPO_ROOT / "scripts" / "trf_onboard.py")
|
||
|
|
trf_onboard = importlib.util.module_from_spec(_SPEC)
|
||
|
|
_SPEC.loader.exec_module(trf_onboard)
|
||
|
|
|
||
|
|
|
||
|
|
def test_validate_accepts_golden_manifest(tmp_path, capsys):
|
||
|
|
manifest_path = tmp_path / "manifest.json"
|
||
|
|
manifest_path.write_text(json.dumps(golden_manifest()), encoding="utf-8")
|
||
|
|
|
||
|
|
trf_onboard.main(["validate", str(manifest_path)])
|
||
|
|
|
||
|
|
assert "OK" in capsys.readouterr().out
|
||
|
|
|
||
|
|
|
||
|
|
def test_validate_rejects_broken_manifest(tmp_path):
|
||
|
|
broken = golden_manifest()
|
||
|
|
del broken["phase"]["initial_target"]
|
||
|
|
manifest_path = tmp_path / "manifest.json"
|
||
|
|
manifest_path.write_text(json.dumps(broken), encoding="utf-8")
|
||
|
|
|
||
|
|
with pytest.raises(SystemExit):
|
||
|
|
trf_onboard.main(["validate", str(manifest_path)])
|
||
|
|
|
||
|
|
|
||
|
|
def test_register_phase_rejects_offline_before_any_network_call(tmp_path, monkeypatch):
|
||
|
|
"""A non-conformant manifest must be caught by the offline check —
|
||
|
|
_request must never be called at all."""
|
||
|
|
broken = golden_manifest()
|
||
|
|
del broken["phase"]["initial_target"]
|
||
|
|
manifest_path = tmp_path / "manifest.json"
|
||
|
|
manifest_path.write_text(json.dumps(broken), encoding="utf-8")
|
||
|
|
|
||
|
|
def _boom(*args, **kwargs):
|
||
|
|
raise AssertionError("no network call should have been made")
|
||
|
|
|
||
|
|
monkeypatch.setattr(trf_onboard, "_request", _boom)
|
||
|
|
monkeypatch.setenv("TRF_TEST_TOKEN", "irrelevant")
|
||
|
|
|
||
|
|
with pytest.raises(SystemExit):
|
||
|
|
trf_onboard.main(
|
||
|
|
[
|
||
|
|
"register-phase",
|
||
|
|
"--url", "http://example.invalid",
|
||
|
|
"--token-env", "TRF_TEST_TOKEN",
|
||
|
|
"--manifest", str(manifest_path),
|
||
|
|
]
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
def test_register_phase_requires_token_env_to_be_set(tmp_path, monkeypatch):
|
||
|
|
manifest_path = tmp_path / "manifest.json"
|
||
|
|
manifest_path.write_text(json.dumps(golden_manifest()), encoding="utf-8")
|
||
|
|
monkeypatch.delenv("TRF_TEST_TOKEN_UNSET", raising=False)
|
||
|
|
|
||
|
|
def _boom(*args, **kwargs):
|
||
|
|
raise AssertionError("no network call should have been made without a token")
|
||
|
|
|
||
|
|
monkeypatch.setattr(trf_onboard, "_request", _boom)
|
||
|
|
|
||
|
|
with pytest.raises(SystemExit, match="TRF_TEST_TOKEN_UNSET"):
|
||
|
|
trf_onboard.main(
|
||
|
|
[
|
||
|
|
"register-phase",
|
||
|
|
"--url", "http://example.invalid",
|
||
|
|
"--token-env", "TRF_TEST_TOKEN_UNSET",
|
||
|
|
"--manifest", str(manifest_path),
|
||
|
|
]
|
||
|
|
)
|