# tests/test_operator_cookies.py import time import base64 import json from backend.auth_cookies import sign, read def test_sign_then_read_round_trips(): now = int(time.time()) raw = sign({"uid": "abc", "iat": now}) data = read(raw, max_age=3600) assert data == {"uid": "abc", "iat": now} def test_tampered_signature_is_rejected(): raw = sign({"uid": "abc", "iat": int(time.time())}) body, _sig = raw.rsplit(".", 1) assert read(body + ".deadbeef", max_age=3600) is None def test_tampered_body_is_rejected(): raw = sign({"uid": "abc", "iat": int(time.time())}) body, sig = raw.rsplit(".", 1) forged = base64.urlsafe_b64encode(json.dumps({"uid": "evil", "iat": int(time.time())}).encode()).decode() assert read(forged + "." + sig, max_age=3600) is None def test_expired_by_iat_is_rejected(): raw = sign({"uid": "abc", "iat": int(time.time()) - 10_000}) assert read(raw, max_age=3600) is None def test_garbage_input_is_none_not_raise(): assert read("not-a-cookie", max_age=3600) is None assert read("", max_age=3600) is None assert read(None, max_age=3600) is None def test_wrong_secret_is_rejected(monkeypatch): import backend.auth_cookies as ac monkeypatch.setattr(ac, "SECRET_KEY", "secret-A") raw = ac.sign({"uid": "x", "iat": int(time.time())}) monkeypatch.setattr(ac, "SECRET_KEY", "secret-B") assert ac.read(raw, max_age=3600) is None def test_future_dated_iat_is_rejected(): raw = sign({"uid": "x", "iat": int(time.time()) + 10_000}) assert read(raw, max_age=3600) is None