mirror of
https://github.com/Quad4-Software/MeshChatX.git
synced 2026-08-18 09:49:09 -04:00
170 lines
5.2 KiB
Python
170 lines
5.2 KiB
Python
# SPDX-License-Identifier: 0BSD
|
|
|
|
import os
|
|
import tempfile
|
|
|
|
from meshchatx.src.backend.database import Database
|
|
from meshchatx.src.backend.database.provider import DatabaseProvider
|
|
|
|
|
|
def _insert(db, dest_hex, aspect, updated_order, identity_hex=None):
|
|
db.announces.upsert_announce(
|
|
{
|
|
"destination_hash": dest_hex,
|
|
"aspect": aspect,
|
|
"identity_hash": identity_hex or ("a" * 32),
|
|
"identity_public_key": "cHVibmtleQ==",
|
|
"app_data": None,
|
|
"rssi": None,
|
|
"snr": None,
|
|
"quality": None,
|
|
},
|
|
)
|
|
db.provider.execute(
|
|
"UPDATE announces SET updated_at = ? WHERE destination_hash = ?",
|
|
(updated_order, dest_hex),
|
|
)
|
|
|
|
|
|
def _new_db():
|
|
with tempfile.NamedTemporaryFile(suffix=".db", delete=False) as f:
|
|
path = f.name
|
|
db = Database(path)
|
|
db.initialize()
|
|
return db, path
|
|
|
|
|
|
def _cleanup(db, path):
|
|
if db is not None:
|
|
try:
|
|
db.close()
|
|
except Exception:
|
|
pass
|
|
DatabaseProvider._instance = None
|
|
if path:
|
|
try:
|
|
os.unlink(path)
|
|
except OSError:
|
|
pass
|
|
for suffix in ("-wal", "-shm"):
|
|
try:
|
|
os.unlink(path + suffix)
|
|
except OSError:
|
|
pass
|
|
|
|
|
|
def test_trim_announces_for_aspect_noop_when_max_rows_below_one():
|
|
db = path = None
|
|
try:
|
|
db, path = _new_db()
|
|
aspect = "lxmf.delivery"
|
|
_insert(db, "01" * 16, aspect, "2000-01-01T00:00:00Z")
|
|
_insert(db, "02" * 16, aspect, "2000-01-02T00:00:00Z")
|
|
db.announces.trim_announces_for_aspect(aspect, 0)
|
|
assert db.announces.get_announce_count_by_aspect(aspect) == 2
|
|
finally:
|
|
_cleanup(db, path)
|
|
|
|
|
|
def test_trim_announces_for_aspect_drops_oldest():
|
|
db = path = None
|
|
try:
|
|
db, path = _new_db()
|
|
aspect = "lxmf.delivery"
|
|
_insert(db, "01" * 16, aspect, "2000-01-01T00:00:00Z")
|
|
_insert(db, "02" * 16, aspect, "2000-01-02T00:00:00Z")
|
|
_insert(db, "03" * 16, aspect, "2000-01-03T00:00:00Z")
|
|
db.announces.trim_announces_for_aspect(aspect, 2)
|
|
rows = db.announces.get_announces(aspect=aspect)
|
|
hashes = {r["destination_hash"] for r in rows}
|
|
assert hashes == {"03" * 16, "02" * 16}
|
|
finally:
|
|
_cleanup(db, path)
|
|
|
|
|
|
def test_trim_preserves_favourited_destination():
|
|
"""Favourited NomadNet/destination announces must survive aspect trim."""
|
|
db = path = None
|
|
try:
|
|
db, path = _new_db()
|
|
aspect = "nomadnetwork.node"
|
|
|
|
_insert(db, "01" * 16, aspect, "2000-01-01T00:00:00Z")
|
|
_insert(db, "02" * 16, aspect, "2000-01-02T00:00:00Z")
|
|
_insert(db, "03" * 16, aspect, "2000-01-03T00:00:00Z")
|
|
_insert(db, "04" * 16, aspect, "2000-01-04T00:00:00Z")
|
|
|
|
db.announces.upsert_favourite("01" * 16, "Favourite Node", aspect)
|
|
|
|
db.announces.trim_announces_for_aspect(aspect, 2)
|
|
|
|
rows = db.announces.get_announces(aspect=aspect)
|
|
hashes = {r["destination_hash"] for r in rows}
|
|
|
|
assert "01" * 16 in hashes, "favourited announce was wrongly trimmed"
|
|
assert "04" * 16 in hashes, "newest announce should be retained"
|
|
assert "02" * 16 not in hashes
|
|
assert "03" * 16 not in hashes
|
|
finally:
|
|
_cleanup(db, path)
|
|
|
|
|
|
def test_trim_preserves_contact_announce_by_identity_hash():
|
|
"""Announces tied to a saved contact via identity hash must not be dropped."""
|
|
db = path = None
|
|
try:
|
|
db, path = _new_db()
|
|
aspect = "lxmf.delivery"
|
|
|
|
contact_identity = "b" * 32
|
|
|
|
_insert(db, "01" * 16, aspect, "2000-01-01T00:00:00Z", contact_identity)
|
|
_insert(db, "02" * 16, aspect, "2000-01-02T00:00:00Z")
|
|
_insert(db, "03" * 16, aspect, "2000-01-03T00:00:00Z")
|
|
_insert(db, "04" * 16, aspect, "2000-01-04T00:00:00Z")
|
|
|
|
db.contacts.add_contact(
|
|
name="Friend",
|
|
remote_identity_hash=contact_identity,
|
|
)
|
|
|
|
db.announces.trim_announces_for_aspect(aspect, 2)
|
|
|
|
rows = db.announces.get_announces(aspect=aspect)
|
|
hashes = {r["destination_hash"] for r in rows}
|
|
|
|
assert "01" * 16 in hashes, "contact-linked announce was wrongly trimmed"
|
|
assert "04" * 16 in hashes
|
|
finally:
|
|
_cleanup(db, path)
|
|
|
|
|
|
def test_trim_preserves_contact_announce_by_lxmf_address():
|
|
"""Announces matching contacts.lxmf_address must be retained."""
|
|
db = path = None
|
|
try:
|
|
db, path = _new_db()
|
|
aspect = "lxmf.delivery"
|
|
|
|
protected_dest = "01" * 16
|
|
|
|
_insert(db, protected_dest, aspect, "2000-01-01T00:00:00Z")
|
|
_insert(db, "02" * 16, aspect, "2000-01-02T00:00:00Z")
|
|
_insert(db, "03" * 16, aspect, "2000-01-03T00:00:00Z")
|
|
_insert(db, "04" * 16, aspect, "2000-01-04T00:00:00Z")
|
|
|
|
db.contacts.add_contact(
|
|
name="Friend",
|
|
remote_identity_hash="c" * 32,
|
|
lxmf_address=protected_dest,
|
|
)
|
|
|
|
db.announces.trim_announces_for_aspect(aspect, 2)
|
|
|
|
rows = db.announces.get_announces(aspect=aspect)
|
|
hashes = {r["destination_hash"] for r in rows}
|
|
|
|
assert protected_dest in hashes
|
|
assert "04" * 16 in hashes
|
|
finally:
|
|
_cleanup(db, path)
|