personal memory agent
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

link: port test_auth to solstone fork

+177
+177
tests/link/test_auth.py
··· 1 + # SPDX-License-Identifier: AGPL-3.0-only 2 + # Copyright (c) 2026 sol pbc 3 + 4 + """AuthorizedClients add/remove/reload semantics for the solstone fork.""" 5 + 6 + from __future__ import annotations 7 + 8 + import datetime as dt 9 + import json 10 + import time 11 + from pathlib import Path 12 + 13 + from think.link.auth import AuthorizedClients 14 + 15 + 16 + def test_empty_file_is_empty(tmp_path: Path) -> None: 17 + store = AuthorizedClients(tmp_path / "auth.json") 18 + 19 + assert not store.is_authorized("sha256:abc") 20 + 21 + 22 + def test_add_and_authorized(tmp_path: Path) -> None: 23 + store = AuthorizedClients(tmp_path / "auth.json") 24 + 25 + store.add("sha256:abc", "Jer's phone", "inst-1") 26 + 27 + assert store.is_authorized("sha256:abc") 28 + assert not store.is_authorized("sha256:xyz") 29 + 30 + 31 + def test_remove(tmp_path: Path) -> None: 32 + store = AuthorizedClients(tmp_path / "auth.json") 33 + store.add("sha256:abc", "Jer", "inst-1") 34 + 35 + assert store.remove("sha256:abc") is True 36 + assert not store.is_authorized("sha256:abc") 37 + assert store.remove("sha256:abc") is False 38 + 39 + 40 + def test_external_edit_reloads_on_mtime_change(tmp_path: Path) -> None: 41 + path = tmp_path / "auth.json" 42 + store = AuthorizedClients(path) 43 + store.add("sha256:abc", "Jer", "inst-1") 44 + assert store.is_authorized("sha256:abc") 45 + 46 + time.sleep(0.02) 47 + path.write_text(json.dumps([], indent=2) + "\n", encoding="utf-8") 48 + 49 + assert store.reload_if_stale() is True 50 + assert not store.is_authorized("sha256:abc") 51 + 52 + 53 + def test_is_authorized_reloads_automatically(tmp_path: Path) -> None: 54 + path = tmp_path / "auth.json" 55 + store = AuthorizedClients(path) 56 + 57 + time.sleep(0.02) 58 + path.write_text( 59 + json.dumps( 60 + [ 61 + { 62 + "fingerprint": "sha256:zzz", 63 + "device_label": "external", 64 + "paired_at": "2026-04-19T00:00:00Z", 65 + "instance_id": "inst-1", 66 + } 67 + ], 68 + indent=2, 69 + ) 70 + + "\n", 71 + encoding="utf-8", 72 + ) 73 + 74 + assert store.is_authorized("sha256:zzz") 75 + 76 + 77 + def test_snapshot_returns_entries(tmp_path: Path) -> None: 78 + store = AuthorizedClients(tmp_path / "auth.json") 79 + store.add("sha256:a", "d1", "inst-1") 80 + store.add("sha256:b", "d2", "inst-1") 81 + 82 + snapshot = store.snapshot() 83 + fingerprints = sorted(entry.fingerprint for entry in snapshot) 84 + 85 + assert fingerprints == ["sha256:a", "sha256:b"] 86 + 87 + 88 + def test_add_then_last_seen_key_absent_in_payload(tmp_path: Path) -> None: 89 + path = tmp_path / "auth.json" 90 + store = AuthorizedClients(path) 91 + 92 + store.add("sha256:abc", "Jer", "inst-1") 93 + 94 + payload = _load_payload(path) 95 + assert "last_seen_at" not in payload[0] 96 + 97 + 98 + def test_touch_last_seen_unknown_fp_returns_false(tmp_path: Path) -> None: 99 + store = AuthorizedClients(tmp_path / "auth.json") 100 + 101 + assert store.touch_last_seen("sha256:deadbeef") is False 102 + 103 + store.add("sha256:abc", "Jer", "inst-1") 104 + 105 + assert store.touch_last_seen("sha256:deadbeef") is False 106 + 107 + 108 + def test_touch_last_seen_updates_timestamp(tmp_path: Path) -> None: 109 + store = AuthorizedClients(tmp_path / "auth.json") 110 + fingerprint = "sha256:abc" 111 + later = dt.datetime(2026, 4, 19, 18, 3, 12, tzinfo=dt.UTC) 112 + 113 + store.add(fingerprint, "Jer", "inst-1") 114 + 115 + assert store.touch_last_seen(fingerprint) is True 116 + first_entry = next( 117 + entry for entry in store.snapshot() if entry.fingerprint == fingerprint 118 + ) 119 + assert first_entry.last_seen_at is not None 120 + 121 + assert store.touch_last_seen(fingerprint, now=later) is True 122 + second_entry = next( 123 + entry for entry in store.snapshot() if entry.fingerprint == fingerprint 124 + ) 125 + assert second_entry.last_seen_at == "2026-04-19T18:03:12Z" 126 + 127 + 128 + def test_touch_last_seen_persists_key_in_payload(tmp_path: Path) -> None: 129 + path = tmp_path / "auth.json" 130 + store = AuthorizedClients(path) 131 + 132 + store.add("sha256:abc", "Jer", "inst-1") 133 + assert store.touch_last_seen("sha256:abc") is True 134 + 135 + payload = _load_payload(path) 136 + assert payload[0]["last_seen_at"] 137 + 138 + 139 + def test_find_by_label(tmp_path: Path) -> None: 140 + path = tmp_path / "auth.json" 141 + store = AuthorizedClients(path) 142 + 143 + assert store.find_by_label("Jer") is None 144 + 145 + store.add("sha256:abc", "Jer", "inst-1") 146 + entry = store.find_by_label("Jer") 147 + assert entry is not None 148 + assert entry.fingerprint == "sha256:abc" 149 + assert store.find_by_label("Nope") is None 150 + 151 + time.sleep(0.02) 152 + path.write_text( 153 + json.dumps( 154 + [ 155 + { 156 + "fingerprint": "sha256:xyz", 157 + "device_label": "External", 158 + "paired_at": "2026-04-19T00:00:00Z", 159 + "instance_id": "inst-2", 160 + "last_seen_at": "2026-04-19T18:03:12Z", 161 + } 162 + ], 163 + indent=2, 164 + ) 165 + + "\n", 166 + encoding="utf-8", 167 + ) 168 + 169 + reloaded = store.find_by_label("External") 170 + assert reloaded is not None 171 + assert reloaded.fingerprint == "sha256:xyz" 172 + assert reloaded.last_seen_at == "2026-04-19T18:03:12Z" 173 + assert store.find_by_label("Jer") is None 174 + 175 + 176 + def _load_payload(path: Path) -> list[dict[str, str]]: 177 + return json.loads(path.read_text(encoding="utf-8"))