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