personal memory agent
0

Configure Feed

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

solstone / tests / test_status_mark_assets.py
2.6 kB 74 lines
1# SPDX-License-Identifier: AGPL-3.0-only 2# Copyright (c) 2026 sol pbc 3 4from __future__ import annotations 5 6import shutil 7import subprocess 8from pathlib import Path 9 10import pytest 11 12ROOT = Path(__file__).resolve().parents[1] 13DEGRADED_SVG = ROOT / "solstone" / "convey" / "static" / "sol-status" / "degraded.svg" 14WEBSOCKET_JS = ROOT / "solstone" / "convey" / "static" / "websocket.js" 15 16 17def test_degraded_status_asset_uses_red_glyph_and_keeps_ring_rays(): 18 text = DEGRADED_SVG.read_text(encoding="utf-8") 19 20 assert 'stroke="#dc2626"' in text 21 assert '<circle cx="16.0" cy="18.6" r="0.7" fill="#dc2626"/>' in text 22 assert "#d97706" not in text 23 assert "#E8923A" in text 24 assert "#FFCF33" in text 25 26 27def test_websocket_status_mark_degraded_wiring(): 28 text = WEBSOCKET_JS.read_text(encoding="utf-8") 29 30 assert "captureStatus === 'degraded'" in text 31 assert "degraded: 'a device needs attention'" in text 32 33 34def test_websocket_derive_status_mark_device_labels(tmp_path): 35 node = shutil.which("node") 36 if node is None: 37 pytest.skip("node is not available") 38 39 source = WEBSOCKET_JS.read_text(encoding="utf-8") 40 start = source.index(" function deriveStatusMark") 41 end = source.index("\n\n function renderStatusMark", start) 42 script = tmp_path / "derive-status-mark-test.js" 43 script.write_text( 44 """ 45function assert(condition, message) { 46 if (!condition) throw new Error(message); 47} 48 49""" 50 + source[start:end] 51 + """ 52 53const cases = [ 54 ['connected', 'offline', false, 'error', false, 'devices offline'], 55 ['connected', 'degraded', false, 'degraded', false, 'a device needs attention'], 56 ['connected', 'stale', false, 'half', false, 'devices out of touch'], 57 ['connected', 'no_observers', false, 'paused', false, 'no devices running sol'], 58 ['connected', 'active', false, 'active', false, 'active'], 59 ['disconnected', 'active', false, 'x', false, 'disconnected'], 60 ['connected', 'unknown', false, 'question', false, 'status unknown'], 61 ['connected', 'active', true, 'bang', false, 'attention'], 62]; 63 64for (const [wsState, captureStatus, hasUnviewed, variant, spin, label] of cases) { 65 const actual = deriveStatusMark(wsState, captureStatus, hasUnviewed); 66 assert(actual.variant === variant, `${label}: wrong variant ${actual.variant}`); 67 assert(actual.spin === spin, `${label}: wrong spin ${actual.spin}`); 68 assert(actual.label === label, `${label}: wrong label ${actual.label}`); 69} 70""", 71 encoding="utf-8", 72 ) 73 74 subprocess.run([node, str(script)], check=True, text=True)