Apollo Beach on its own: a standalone panel to send them
- tools/standalone.py builds dist/<Name> Status Panel.zip: program, install.command, READ ME FIRST.txt - setup --standalone: campuses.json standalone, tells nobody, no hub, no NA key - Standalone backs itself up nightly to ~/Documents/Status Panel Backups/<id> - upgrade-companion --from <.dmg/.zip from bitfocus.io> (no NA needed) - Only the hub lists campuses or shows other campuses' install lines Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -459,3 +459,75 @@ class TestCampusHello(TestRoutes):
|
||||
get(self.port, "/api/campus/hello", {"id": "new", "url": "http://10.5.1.9:8020"})
|
||||
get(self.port, "/api/campus/hello", {"id": "sc", "name": "Southcoast", "url": "http://10.5.1.9:8020"})
|
||||
self.assertNotIn("new", cv.load(self.data)["list"]) # same Mac, now named: the old entry goes
|
||||
|
||||
|
||||
class TestStandalone(unittest.TestCase):
|
||||
"""Apollo Beach runs its own panel (2026-10-21): it tells nobody, keeps no campus list, backs itself up."""
|
||||
|
||||
def test_a_standalone_campus_tells_nobody_and_is_no_hub(self):
|
||||
from settings import campuses as cv
|
||||
data_dir = tempfile.mkdtemp(prefix="sp-sa-")
|
||||
cv.save(data_dir, {"standalone": True})
|
||||
self.assertFalse(cv.Mirror.is_hub(cv.load(data_dir)))
|
||||
self.assertTrue(cv.Mirror.is_hub({})) # NA: no home
|
||||
self.assertFalse(cv.Mirror.is_hub({"home": "http://10.1.1.1:8020"}))
|
||||
|
||||
class FakeSite:
|
||||
def __init__(self):
|
||||
self.data_dir = data_dir
|
||||
|
||||
def load(self):
|
||||
return {"site": {"id": "ab", "name": "Apollo Beach"}}
|
||||
sent = []
|
||||
real, real_url = cv.http_json, cv.my_url
|
||||
cv.http_json = lambda url, body=None, timeout=3: sent.append(url) or {"ok": True}
|
||||
cv.my_url = lambda cfg: "http://10.4.1.1:8020"
|
||||
try:
|
||||
m = cv.Mirror(FakeSite())
|
||||
data = m.sync_registry()
|
||||
m.poll()
|
||||
m.refresh_pages()
|
||||
finally:
|
||||
cv.http_json, cv.my_url = real, real_url
|
||||
self.assertEqual(sent, [])
|
||||
self.assertEqual(list(data["list"]), ["ab"])
|
||||
|
||||
def test_setup_marks_it_standalone_and_drops_any_home(self):
|
||||
from settings import campuses as cv
|
||||
data_dir = tempfile.mkdtemp(prefix="sp-sa-")
|
||||
cv.save(data_dir, {"home": "http://10.1.1.1:8020"})
|
||||
real = campus.is_fresh
|
||||
campus.is_fresh = lambda cfg: False # set up already: only the look runs
|
||||
real_look = campus.look_and_add
|
||||
campus.look_and_add = lambda site, say=print, force=False: None
|
||||
real_site = server.Site
|
||||
server.Site = lambda d: type("S", (), {"load": lambda self: {}})()
|
||||
try:
|
||||
campus.setup(data_dir, "ab", "Apollo Beach", say=lambda *a: None, standalone=True)
|
||||
finally:
|
||||
campus.is_fresh, campus.look_and_add, server.Site = real, real_look, real_site
|
||||
data = cv.load(data_dir)
|
||||
self.assertTrue(data.get("standalone"))
|
||||
self.assertNotIn("home", data)
|
||||
|
||||
def test_the_standalone_zip_has_the_program_an_installer_and_no_settings(self):
|
||||
import zipfile
|
||||
sys.path.insert(0, os.path.join(ROOT, "tools"))
|
||||
import standalone
|
||||
out = tempfile.mkdtemp(prefix="sp-zip-")
|
||||
path = standalone.build("ab", "Apollo Beach", out)
|
||||
with zipfile.ZipFile(path) as z:
|
||||
names = z.namelist()
|
||||
inst = z.read("Apollo Beach Status Panel/install.command").decode()
|
||||
mode = z.getinfo("Apollo Beach Status Panel/install.command").external_attr >> 16
|
||||
top = "Apollo Beach Status Panel/program/"
|
||||
for f in ("status_panel.py", "install.sh", "settings/campus.py", "sites/_template/config.json", "backup/backup-campuses.sh"):
|
||||
self.assertIn(top + f, names)
|
||||
for never in ("config.json", "outlets.json", "campuses.json", "sites/ws/config.json", "sites/sc/config.json"):
|
||||
self.assertNotIn(top + never, names)
|
||||
self.assertFalse([n for n in names if "__pycache__" in n or "/._" in n])
|
||||
self.assertIn("Apollo Beach Status Panel/READ ME FIRST.txt", names)
|
||||
self.assertTrue(mode & 0o100)
|
||||
self.assertIn("--standalone", inst)
|
||||
self.assertNotIn("10.1.1.1", inst)
|
||||
self.assertNotIn("authorized_keys", inst) # no one else's key is let in
|
||||
|
||||
Reference in New Issue
Block a user