mirror of
https://github.com/l5yth/potato-mesh.git
synced 2026-08-11 19:33:09 +02:00
Default missing node role to client (#15)
This commit is contained in:
@@ -86,3 +86,42 @@ def test_post_nodes_to_web_app(tmp_path):
|
||||
assert lines[0] == "200"
|
||||
expected = len(json.load(open(nodes_json)))
|
||||
assert int(lines[1]) == expected
|
||||
|
||||
|
||||
def test_null_role_defaults_to_client(tmp_path):
|
||||
db_path = tmp_path / "nodes.db"
|
||||
os.environ["MESH_DB"] = str(db_path)
|
||||
os.environ["API_TOKEN"] = "tok"
|
||||
|
||||
web_dir = Path(__file__).resolve().parents[1] / "web"
|
||||
node = {
|
||||
"nodeA": {
|
||||
"num": 1,
|
||||
"lastHeard": int(time.time()),
|
||||
"user": {"shortName": "Foo"},
|
||||
}
|
||||
}
|
||||
nodes_json = json.dumps(node)
|
||||
try:
|
||||
subprocess.run(["bundle", "install"], cwd=web_dir, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
env = os.environ.copy()
|
||||
env["MESH_DB"] = str(db_path)
|
||||
env["API_TOKEN"] = "tok"
|
||||
ruby = (
|
||||
"require_relative 'app'; require 'json'; require 'rack/mock';"
|
||||
f"nodes = {json.dumps(nodes_json)};"
|
||||
"req = Rack::MockRequest.new(Sinatra::Application);"
|
||||
"req.post('/api/nodes', 'CONTENT_TYPE' => 'application/json', 'HTTP_AUTHORIZATION' => 'Bearer tok', :input => nodes);"
|
||||
"puts query_nodes(1000).to_json;"
|
||||
)
|
||||
out = subprocess.check_output(["bundle", "exec", "ruby", "-e", ruby], cwd=web_dir, env=env, stderr=subprocess.DEVNULL)
|
||||
except subprocess.CalledProcessError:
|
||||
pytest.skip("ruby dependencies not installed")
|
||||
|
||||
data = json.loads(out.decode().splitlines()[-1])
|
||||
assert any(n["role"] == "CLIENT" for n in data if n["node_id"] == "nodeA")
|
||||
|
||||
conn = sqlite3.connect(db_path)
|
||||
role = conn.execute("SELECT role FROM nodes WHERE node_id=?", ("nodeA",)).fetchone()[0]
|
||||
conn.close()
|
||||
assert role == "CLIENT"
|
||||
|
||||
+3
-1
@@ -21,6 +21,7 @@ def query_nodes(limit)
|
||||
LIMIT ?
|
||||
SQL
|
||||
rows.each do |r|
|
||||
r["role"] ||= "CLIENT"
|
||||
lh = r["last_heard"]; pt = r["position_time"]
|
||||
r["last_seen_iso"] = lh ? Time.at(lh.to_i).utc.iso8601 : nil
|
||||
r["pos_time_iso"] = pt ? Time.at(pt.to_i).utc.iso8601 : nil
|
||||
@@ -40,6 +41,7 @@ def upsert_node(db, node_id, n)
|
||||
user = n["user"] || {}
|
||||
met = n["deviceMetrics"] || {}
|
||||
pos = n["position"] || {}
|
||||
role = user["role"] || "CLIENT"
|
||||
row = [
|
||||
node_id,
|
||||
n["num"],
|
||||
@@ -47,7 +49,7 @@ def upsert_node(db, node_id, n)
|
||||
user["longName"],
|
||||
user["macaddr"],
|
||||
user["hwModel"] || n["hwModel"],
|
||||
user["role"],
|
||||
role,
|
||||
user["publicKey"],
|
||||
user["isUnmessagable"],
|
||||
n["isFavorite"],
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
<td>${n.short_name || ""}</td>
|
||||
<td>${n.long_name || ""}</td>
|
||||
<td>${n.hw_model || ""}</td>
|
||||
<td>${n.role || ""}</td>
|
||||
<td>${n.role || "CLIENT"}</td>
|
||||
<td>${n.snr ?? ""}</td>
|
||||
<td>${n.battery_level ?? ""}</td>
|
||||
<td>${timeAgo(n.last_heard)}</td>
|
||||
@@ -149,7 +149,7 @@
|
||||
const lines = [
|
||||
`<b>${n.short_name || ''}</b> <span class="mono">${n.node_id || ''}</span>`,
|
||||
n.hw_model ? `Model: ${n.hw_model}` : null,
|
||||
n.role ? `Role: ${n.role}` : null,
|
||||
`Role: ${n.role || 'CLIENT'}`,
|
||||
(n.snr != null ? `SNR: ${n.snr}` : null),
|
||||
(n.battery_level != null ? `Battery: ${n.battery_level}` : null),
|
||||
(n.last_heard ? `Last seen: ${timeAgo(n.last_heard)}` : null),
|
||||
|
||||
Reference in New Issue
Block a user