from pathlib import Path from hockey_data.agent_bridge import _stable_vmix_inventory_fingerprint ROOT = Path(__file__).resolve().parents[1] def test_stable_project_fingerprint_ignores_input_number_order_and_title_when_key_exists(): before = [ { "key": "key-score", "number": "22", "title": "Верхний счёт", "type": "GT", "fields": [ {"name": "Таймер.Text", "type": "text", "index": "0"}, {"name": "HOME.Text", "type": "text", "index": "1"}, ], }, { "key": "key-penalty", "number": "114", "title": "Удаление HOME", "type": "GT", "fields": [{"name": "Таймер.Text", "type": "text", "index": "0"}], }, ] after = [ { "key": "key-penalty", "number": "7", "title": "Удаление HOME (новое имя)", "type": "GT", "fields": [{"name": "Таймер.Text", "type": "text", "index": "4"}], }, { "key": "key-score", "number": "91", "title": "Счёт", "type": "GT", "fields": [ {"name": "HOME.Text", "type": "text", "index": "9"}, {"name": "Таймер.Text", "type": "text", "index": "2"}, ], }, ] assert _stable_vmix_inventory_fingerprint(before) == _stable_vmix_inventory_fingerprint(after) def test_legacy_project_fingerprint_uses_title_instead_of_number(): before = [{"key": "", "number": "3", "title": "Score", "type": "GT", "fields": []}] after = [{"key": "", "number": "99", "title": "Score", "type": "GT", "fields": []}] assert _stable_vmix_inventory_fingerprint(before) == _stable_vmix_inventory_fingerprint(after) def test_shortcut_editor_persists_key_before_number(): app_js = (ROOT / "ui_builder" / "static" / "app.js").read_text(encoding="utf-8") assert 'return String(item?.key || item?.title || item?.number || "").trim();' in app_js assert "старый номер Input — выберите Input заново один раз" in app_js def test_mapping_links_do_not_resave_positional_number(): mapping_js = (ROOT / "hockey_data" / "static" / "admin-directories.js").read_text(encoding="utf-8") assert 'vmix_input_number: ""' in mapping_js assert 'vmix_input_number: (row.vmix_input_key || row.vmix_input_title) ? ""' in mapping_js