47 lines
1.7 KiB
Python
47 lines
1.7 KiB
Python
|
|
"""Tests für die Zustandsdatei, die die Wochen-Prüfungen steuert."""
|
||
|
|
from datetime import datetime, timedelta, timezone
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
|
||
|
|
from scanner.baseline import BaselineManager
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.fixture
|
||
|
|
def bm(tmp_path):
|
||
|
|
return BaselineManager(tmp_path)
|
||
|
|
|
||
|
|
|
||
|
|
class TestRunState:
|
||
|
|
def test_never_run_is_due(self, bm):
|
||
|
|
assert bm.is_check_due("cloak_check", 7) is True
|
||
|
|
|
||
|
|
def test_just_run_is_not_due(self, bm):
|
||
|
|
bm.mark_check_run("cloak_check")
|
||
|
|
assert bm.is_check_due("cloak_check", 7) is False
|
||
|
|
|
||
|
|
def test_old_run_is_due(self, bm):
|
||
|
|
# Lauf vor 10 Tagen → bei Intervall 7 fällig
|
||
|
|
old = (datetime.now(timezone.utc) - timedelta(days=10)).isoformat()
|
||
|
|
bm.save_state({"last_runs": {"assets": old}})
|
||
|
|
assert bm.is_check_due("assets", 7) is True
|
||
|
|
|
||
|
|
def test_recent_run_within_interval_not_due(self, bm):
|
||
|
|
recent = (datetime.now(timezone.utc) - timedelta(days=3)).isoformat()
|
||
|
|
bm.save_state({"last_runs": {"assets": recent}})
|
||
|
|
assert bm.is_check_due("assets", 7) is False
|
||
|
|
|
||
|
|
def test_save_load_roundtrip(self, bm):
|
||
|
|
bm.mark_check_run("ext_links")
|
||
|
|
state = bm.load_state()
|
||
|
|
assert "ext_links" in state["last_runs"]
|
||
|
|
|
||
|
|
def test_corrupt_state_file_recovers(self, bm):
|
||
|
|
bm._state_path.parent.mkdir(parents=True, exist_ok=True)
|
||
|
|
bm._state_path.write_text("{ not valid json", encoding="utf-8")
|
||
|
|
# Darf nicht crashen, sondern als "nie gelaufen" gelten
|
||
|
|
assert bm.load_state() == {"last_runs": {}}
|
||
|
|
assert bm.is_check_due("cloak_check", 7) is True
|
||
|
|
|
||
|
|
def test_invalid_timestamp_is_due(self, bm):
|
||
|
|
bm.save_state({"last_runs": {"assets": "kein-datum"}})
|
||
|
|
assert bm.is_check_due("assets", 7) is True
|