mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2026-04-15 22:51:37 -07:00
This commit is contained in:
@@ -327,20 +327,30 @@ class DeviceInstance:
|
|||||||
return {"success": True, "inserted": row_count, "skipped_lines": skipped}
|
return {"success": True, "inserted": row_count, "skipped_lines": skipped}
|
||||||
|
|
||||||
def getTotals(self):
|
def getTotals(self):
|
||||||
"""Get device totals by status."""
|
"""Get device totals by status.
|
||||||
|
|
||||||
|
Returns a list of 6 counts in the documented positional order:
|
||||||
|
[all, connected, favorites, new, down, archived]
|
||||||
|
|
||||||
|
IMPORTANT: This order is a public API contract consumed by:
|
||||||
|
- presence.php (reads indices 0-5)
|
||||||
|
- /devices/totals/named (maps indices 0-5 to named fields)
|
||||||
|
- homepage widget datav2 (reads /devices/totals indices)
|
||||||
|
DO NOT change the order or add/remove fields without a breaking-change release.
|
||||||
|
"""
|
||||||
conn = get_temp_db_connection()
|
conn = get_temp_db_connection()
|
||||||
sql = conn.cursor()
|
sql = conn.cursor()
|
||||||
|
|
||||||
conditions = get_device_conditions()
|
all_conditions = get_device_conditions()
|
||||||
|
|
||||||
# Build sub-selects dynamically for all dictionary entries
|
# Only the 6 public fields, in documented positional order.
|
||||||
sub_queries = []
|
# DO NOT change this order — it is a stable API contract.
|
||||||
for key, condition in conditions.items():
|
keys = ["all", "connected", "favorites", "new", "down", "archived"]
|
||||||
# Make sure the alias is SQL-safe (no spaces or special chars)
|
sub_queries = [
|
||||||
alias = key.replace(" ", "_").lower()
|
f'(SELECT COUNT(*) FROM DevicesView {all_conditions[key]}) AS "{key}"'
|
||||||
sub_queries.append(f'(SELECT COUNT(*) FROM DevicesView {condition}) AS "{alias}"')
|
for key in keys
|
||||||
|
]
|
||||||
|
|
||||||
# Join all sub-selects with commas
|
|
||||||
query = "SELECT\n " + ",\n ".join(sub_queries)
|
query = "SELECT\n " + ",\n ".join(sub_queries)
|
||||||
sql.execute(query)
|
sql.execute(query)
|
||||||
row = sql.fetchone()
|
row = sql.fetchone()
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import pytest
|
|||||||
|
|
||||||
from helper import get_setting_value
|
from helper import get_setting_value
|
||||||
from api_server.api_server_start import app
|
from api_server.api_server_start import app
|
||||||
from db.db_helper import get_device_conditions
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
@@ -163,17 +162,15 @@ def test_devices_totals(client, api_token, test_mac):
|
|||||||
data = resp.json
|
data = resp.json
|
||||||
assert isinstance(data, list)
|
assert isinstance(data, list)
|
||||||
|
|
||||||
# 3. Dynamically get expected length
|
# 3. Verify the response has exactly 6 elements in documented order:
|
||||||
conditions = get_device_conditions()
|
# [all, connected, favorites, new, down, archived]
|
||||||
expected_length = len(conditions)
|
expected_length = 6
|
||||||
assert len(data) == expected_length
|
assert len(data) == expected_length, (
|
||||||
|
f"Expected 6 totals (all, connected, favorites, new, down, archived), got {len(data)}"
|
||||||
|
)
|
||||||
|
|
||||||
# 4. Check that at least 1 device exists when there are any conditions
|
# 4. Check that at least 1 device exists (all count includes the dummy device)
|
||||||
if expected_length > 0:
|
assert data[0] >= 1 # index 0 = 'all'
|
||||||
assert data[0] >= 1 # 'devices' count includes the dummy device
|
|
||||||
else:
|
|
||||||
# no conditions defined; data should be an empty list
|
|
||||||
assert data == []
|
|
||||||
finally:
|
finally:
|
||||||
delete_dummy(client, api_token, test_mac)
|
delete_dummy(client, api_token, test_mac)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user