Display role vocabulary, migration commit fix, stale enforcement reports

This commit is contained in:
2026-08-13 09:30:40 -04:00
parent d327ea1a5c
commit 5dcc7e30af
16 changed files with 490 additions and 46 deletions

View File

@@ -100,7 +100,11 @@ def test_non_admin_cannot_update_or_delete(client, db, auth_headers,
def test_lobby_role_needs_no_businessunit_and_resolves_path(client, db, auth_headers):
"""A lobby-role mapping needs no business unit; display-role returns its path."""
"""A Lobby mapping needs no business unit; display-role returns its path.
Posts the RETIRED lowercase spelling on purpose: an existing caller must not
start failing over a capital, and what comes back is the canonical name.
"""
created = client.post('/api/dashboarddefaults', json={
'ipaddress': '10.20.30.99', 'displayrole': 'lobby',
'description': 'Front lobby TV',
@@ -110,17 +114,19 @@ def test_lobby_role_needs_no_businessunit_and_resolves_path(client, db, auth_hea
resolved = client.get('/api/dashboarddefaults/display-role?ipaddress=10.20.30.99')
data = resolved.get_json()['data']
assert data['role'] == 'lobby'
assert data['role'] == 'Lobby'
assert data['path'] == '/tv'
assert data['businessunitid'] is None
def test_partskiosk_role_resolves_path(client, db, auth_headers):
def test_retired_partskiosk_spelling_maps_to_3dprintroom(client, db, auth_headers):
# 'partskiosk' was core's name for the room the kiosks call '3DPrintRoom'.
# It still posts, and stores as the name the kiosk itself would report.
client.post('/api/dashboarddefaults', json={
'ipaddress': '10.20.30.77', 'displayrole': 'partskiosk',
}, headers=auth_headers)
data = client.get('/api/dashboarddefaults/display-role?ipaddress=10.20.30.77').get_json()['data']
assert data['role'] == 'partskiosk'
assert data['role'] == '3DPrintRoom'
assert data['path'] == '/parts-kiosk'
@@ -143,7 +149,7 @@ def test_fqdn_mapping_create_and_resolve(client, db, auth_headers):
# resolve by FQDN (case-insensitive)
r = client.get('/api/dashboarddefaults/display-role?fqdn=fabc123.device.geaerospace.net')
body = r.get_json()['data']
assert body['role'] == 'lobby'
assert body['role'] == 'Lobby'
assert body['path'] == '/tv'
@@ -164,3 +170,63 @@ def test_invalid_role_rejected(client, db, auth_headers):
def test_unmapped_ip_display_role_null(client, db):
data = client.get('/api/dashboarddefaults/display-role?ipaddress=9.9.9.9').get_json()['data']
assert data['role'] is None and data['path'] is None
# --- role vocabulary -------------------------------------------------------
#
# The role names are not ours to choose: they are the literal values a person
# types into C:\Enrollment\display-type.txt on the kiosk, which the GE-Enforce
# dispatcher reads. These tests exist because core and the kiosks each used to
# hold their own map, and a display could report a role core could not store.
def test_display_roles_are_the_kiosk_vocabulary():
from shopdb.core.models.dashboarddefault import DISPLAY_ROLE_PATHS
assert DISPLAY_ROLE_PATHS == {
'Dashboard': '/shopfloor',
'Lobby': '/tv',
'3DPrintRoom': '/parts-kiosk',
}
def test_geenforce_display_targets_are_core_roles():
"""The display scope must not carry a second copy of the map."""
from shopdb.core.models.dashboarddefault import DISPLAY_ROLE_PATHS
from plugins.geenforce.seed_display_scope import DISPLAY_TYPE_TARGETS
assert DISPLAY_TYPE_TARGETS is DISPLAY_ROLE_PATHS
def test_normalize_display_role_accepts_any_casing():
from shopdb.core.models.dashboarddefault import normalize_display_role
for value in ('Lobby', 'lobby', 'LOBBY', ' Lobby '):
assert normalize_display_role(value) == 'Lobby'
assert normalize_display_role('3dprintroom') == '3DPrintRoom'
assert normalize_display_role('DASHBOARD') == 'Dashboard'
def test_normalize_display_role_maps_retired_spelling():
from shopdb.core.models.dashboarddefault import normalize_display_role
assert normalize_display_role('partskiosk') == '3DPrintRoom'
assert normalize_display_role('PartsKiosk') == '3DPrintRoom'
def test_normalize_display_role_refuses_to_guess():
from shopdb.core.models.dashboarddefault import normalize_display_role
for value in (None, '', ' ', 'bogus', '3d', 'lobbyy'):
assert normalize_display_role(value) is None
def test_mixed_case_role_stores_canonically(client, db, auth_headers):
resp = client.post('/api/dashboarddefaults', json={
'ipaddress': '10.20.30.31', 'displayrole': 'LOBBY',
}, headers=auth_headers)
assert resp.status_code == 201, resp.get_json()
assert resp.get_json()['data']['displayrole'] == 'Lobby'
def test_legacy_stored_value_still_resolves_a_path(db):
"""A row written before the merge keeps working without being rewritten."""
from shopdb.core.models.dashboarddefault import DashboardDefault
row = DashboardDefault(ipaddress='10.20.30.32', displayrole='partskiosk')
db.session.add(row)
db.session.flush()
assert row.displaypath == '/parts-kiosk'