Rig Pocket: phone status page and ntfy notifier for OpenRig
Installable PWA showing rigs, seats (working, idle, waiting for an answer), queue items and recent commits; seat screens with replies; push through ntfy. Reads state through the rig CLI only, Python standard library, no build step, styled entirely with the shared weirsoe-theme. Claude-Session: https://claude.ai/code/session_01QhLkBGEip8wQdaZ54z4AqJ
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import unittest
|
||||
|
||||
import server
|
||||
|
||||
|
||||
def snap(commits=(), queue=(), waiting=False):
|
||||
return {
|
||||
"rigs": [{"name": "team", "seats": [{"name": "dev-qa@team", "waiting": waiting}]}],
|
||||
"queue": list(queue),
|
||||
"repos": [{"name": "repo", "commits": [{"hash": h, "subject": f"commit {h}"} for h in commits]}],
|
||||
}
|
||||
|
||||
|
||||
def q(qid, state, dest="orch-lead@team"):
|
||||
return {"id": qid, "state": state, "dest": dest, "source": "operator-agent@kernel", "summary": f"task {qid}"}
|
||||
|
||||
|
||||
class WatcherTest(unittest.TestCase):
|
||||
def test_first_snapshot_only_seeds(self):
|
||||
w = server.Watcher()
|
||||
self.assertEqual(w.events(snap(commits=["a"], queue=[q("1", "in-progress")])), [])
|
||||
|
||||
def test_new_commits_grouped_per_repo(self):
|
||||
w = server.Watcher()
|
||||
w.events(snap(commits=["a"]))
|
||||
ev = w.events(snap(commits=["a", "b", "c"]))
|
||||
self.assertEqual(len(ev), 1)
|
||||
self.assertIn("2 ny commits", ev[0][0])
|
||||
|
||||
def test_lead_task_done_notifies_once(self):
|
||||
w = server.Watcher()
|
||||
w.events(snap(queue=[q("1", "in-progress"), q("2", "in-progress", "dev-build@team")]))
|
||||
ev = w.events(snap(queue=[q("1", "done"), q("2", "done", "dev-build@team")]))
|
||||
self.assertEqual([e[0] for e in ev], ["Opgave done: orch-lead@team"])
|
||||
self.assertEqual(w.events(snap(queue=[q("1", "done")])), [])
|
||||
|
||||
def test_new_request_to_human_notifies(self):
|
||||
w = server.Watcher()
|
||||
w.events(snap())
|
||||
ev = w.events(snap(queue=[q("9", "in-progress", "operator-agent@kernel")]))
|
||||
self.assertEqual(ev[0][0], "Teamet spørger dig")
|
||||
|
||||
def test_prompt_must_survive_two_polls(self):
|
||||
w = server.Watcher()
|
||||
self.assertEqual(w.events(snap(waiting=True)), [])
|
||||
ev = w.events(snap(waiting=True))
|
||||
self.assertEqual(ev[0][0], "dev-qa@team venter på svar")
|
||||
self.assertEqual(w.events(snap(waiting=True)), [])
|
||||
w.events(snap(waiting=False))
|
||||
w.events(snap(waiting=True))
|
||||
self.assertEqual(len(w.events(snap(waiting=True))), 1)
|
||||
|
||||
def test_prompt_pattern(self):
|
||||
self.assertTrue(server.PROMPT.search(" Do you want to proceed?\n ❯ 1. Yes"))
|
||||
self.assertFalse(server.PROMPT.search("❯ yes, launch it"))
|
||||
|
||||
def test_seat_names(self):
|
||||
self.assertTrue(server.SEAT.match("dev-qa@ubl-workshop"))
|
||||
self.assertFalse(server.SEAT.match("x; rm -rf /"))
|
||||
self.assertFalse(server.SEAT.match("../etc@x/y"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user