Files
matrix/minecraft-bridge/test_lotus_mc_status.py
T
jaredandClaude Opus 5.5 2d2ebf64a5
Lint / Shell (shellcheck) (pull_request) Successful in 26s
Lint / JS (eslint) (pull_request) Successful in 23s
Lint / No secrets in webhook configs (pull_request) Successful in 9s
Lint / No Hookshot webhook IDs in README (pull_request) Successful in 11s
Lint / Landing page is rendered (matrix (pull_request) Successful in 13s
Lint / Python (ruff) (pull_request) Successful in 12s
Lint / Secret scan (gitleaks) (pull_request) Successful in 24s
Lint / Shell (shellcheck) (push) Successful in 27s
Lint / JS (eslint) (push) Successful in 23s
Lint / No Hookshot webhook IDs in README (push) Successful in 5s
Lint / Python deps (pip-audit) (pull_request) Successful in 1m43s
Lint / No secrets in webhook configs (push) Successful in 6s
Lint / Landing page is rendered (matrix (push) Successful in 5s
Lint / Python (ruff) (push) Successful in 7s
Lint / Secret scan (gitleaks) (push) Successful in 8s
Lint / Python deps (pip-audit) (push) Successful in 56s
minecraft: show players online as the bridge bot's status
A small service on CT 154 pings the Lotus Minecraft server and sets the result
as the Matrix status of @lotus-mc-bridge, re-sent every 20 s because the mod
syncs with set_presence=offline and Synapse would otherwise drop it to offline.
Uses the mod's own token, so no new account or secret.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
2026-11-04 22:37:55 -05:00

78 lines
2.8 KiB
Python

import json
import unittest
import lotus_mc_status as s
def packet(players: dict) -> bytes:
body = json.dumps({"version": {"name": "1.21.1"}, "players": players}).encode()
return s.varint(0) + s.varint(len(body)) + body
class FormatStatus(unittest.TestCase):
def test_nobody(self):
self.assertEqual(s.format_status(0, []), "Nobody online")
def test_one(self):
self.assertEqual(s.format_status(1, ["Honnehh"]), "1 online: Honnehh")
def test_sorted_regardless_of_server_order(self):
self.assertEqual(s.format_status(3, ["b_x", "C", "a"]), "3 online: a, b_x, C")
def test_long_names_collapse_and_stay_within_the_limit(self):
names = [f"Player{i}_abcdefghi"[:16] for i in range(10)]
got = s.format_status(10, names)
self.assertLessEqual(len(got), s.MAX_LEN)
self.assertRegex(got, r"^10 online: .+ \+\d+ more$")
shown = got.split(": ")[1].split(" +")[0].split(", ")
self.assertEqual(int(got.split("+")[1].split()[0]), 10 - len(shown))
def test_exact_fit_has_no_more_suffix(self):
got = s.format_status(1, ["A" * 16], max_len=len("1 online: ") + 16)
self.assertEqual(got, "1 online: " + "A" * 16)
def test_more_players_than_the_sample(self):
self.assertEqual(s.format_status(14, ["a", "b"]), "14 online: a, b +12 more")
def test_placeholders_are_not_shown_as_players(self):
self.assertEqual(s.format_status(2, ["Anonymous Player", "a"]), "2 online: a +1 more")
self.assertEqual(s.format_status(1, ["§cinjected name"]), "1 online")
def test_count_only_when_nothing_fits(self):
self.assertEqual(s.format_status(2, ["abcdefgh"], max_len=9), "2 online")
def test_duplicates_and_stale_extras_do_not_overcount(self):
self.assertEqual(s.format_status(1, ["a", "a", "b"]), "1 online: a")
class ParseStatus(unittest.TestCase):
def test_with_sample(self):
p = packet({"max": 20, "online": 2, "sample": [{"name": "a", "id": "x"}, {"name": "b", "id": "y"}]})
self.assertEqual(s.parse_status(p), (2, ["a", "b"]))
def test_without_sample(self):
self.assertEqual(s.parse_status(packet({"max": 20, "online": 0})), (0, []))
def test_rejects_other_packets_and_truncation(self):
with self.assertRaises(ValueError):
s.parse_status(s.varint(1) + b"xx")
with self.assertRaises(ValueError):
s.parse_status(packet({"max": 20, "online": 0})[:-3])
def test_varint_round_trip(self):
for n in (0, 1, 127, 128, 300, 6087, 2097151):
data = iter([s.varint(n)])
buf = next(data)
pos = [0]
def read(k, buf=buf, pos=pos):
out = buf[pos[0] : pos[0] + k]
pos[0] += k
return out
self.assertEqual(s.read_varint(read), n)
if __name__ == "__main__":
unittest.main()