Files
shelly-ui/tests/test_config_snapshot_diff.py
jonas 71803418e5 Initial commit: Shelly Manager with Textual CLI, Streamlit UI, and comprehensive .gitignore
Shelly device management app with mDNS/subnet discovery, inventory,
configuration, and mass operations for Gen1/Gen2+ devices.

Includes .gitignore excluding runtime data (device DB, user config),
AI conversation history, build artifacts, and common Python/OS patterns.
2026-03-23 21:51:59 +01:00

85 lines
2.9 KiB
Python

"""Config snapshot unified diff (GetConfig history)."""
from __future__ import annotations
from datetime import UTC, datetime, timedelta
from shelly_manager.core.config_snapshot_diff import (
pick_older_newer,
settings_unified_diff_text,
sort_snapshots_chronologically,
)
from shelly_manager.core.models import ConfigSnapshot
def _snap(
*,
sid: str,
created: datetime,
label: str,
settings: dict,
) -> ConfigSnapshot:
return ConfigSnapshot(
id=sid,
device_id="DEV",
created_at=created,
label=label,
settings=settings,
)
def test_sort_snapshots_chronologically_oldest_first() -> None:
t0 = datetime(2026, 3, 20, 0, 37, tzinfo=UTC)
t1 = datetime(2026, 3, 20, 0, 42, tzinfo=UTC)
a = _snap(sid="a", created=t1, label="newer", settings={})
b = _snap(sid="b", created=t0, label="older", settings={})
out = sort_snapshots_chronologically([a, b])
assert [x.label for x in out] == ["older", "newer"]
def test_pick_older_newer_swaps_when_user_picks_newer_as_a() -> None:
"""Oldest-first list: index 0 older, index 1 newer — if user picks A=1 B=0, still get older→newer."""
t0 = datetime(2026, 3, 20, 0, 37, tzinfo=UTC)
t1 = datetime(2026, 3, 20, 0, 42, tzinfo=UTC)
snaps = [
_snap(sid="b", created=t0, label="older", settings={"x": 1}),
_snap(sid="a", created=t1, label="newer", settings={"x": 2}),
]
older, newer = pick_older_newer(snaps, 1, 0)
assert older.label == "older"
assert newer.label == "newer"
def test_settings_unified_diff_text_has_line_separated_structure() -> None:
"""Regression: diff must contain newlines so each +/- line is separate (not one wrapped blob)."""
old = {"ble": {"enable": True}}
new = {"ble": {"enable": False}}
text = settings_unified_diff_text(old, new, fromfile="older/settings.json", tofile="newer/settings.json")
assert text.count("\n") >= 4
lines = text.splitlines()
assert lines[0].startswith("--- ")
assert lines[1].startswith("+++ ")
assert any(line.startswith("@@") for line in lines)
# Every content/hunk line must be its own line (no embedded @@ mid-line)
for line in lines:
assert "\n" not in line
minus_lines = [ln for ln in lines if ln.startswith("-") and not ln.startswith("---")]
plus_lines = [ln for ln in lines if ln.startswith("+") and not ln.startswith("+++")]
assert minus_lines
assert plus_lines
def test_settings_unified_diff_identical_empty() -> None:
cfg = {"a": 1}
assert settings_unified_diff_text(cfg, cfg) == ""
def test_pick_older_newer_same_timestamp_tie_break() -> None:
t = datetime(2026, 3, 20, 12, 0, tzinfo=UTC)
s1 = _snap(sid="aaa", created=t, label="first", settings={})
s2 = _snap(sid="zzz", created=t, label="second", settings={})
snaps = sort_snapshots_chronologically([s2, s1])
older, newer = pick_older_newer(snaps, 0, 1)
assert older.id == "aaa"
assert newer.id == "zzz"