"""储物格下拉关键词:须支持完整 fullSlotCode 模糊匹配。""" from types import SimpleNamespace from app.crud.storage_facility import ( _build_node_path_cache, _collect_slot_host_node_ids, _exact_node_ids_for_path, _leaf_node_ids_for_path_prefix, _resolve_path_keyword, _slot_matches_select_keyword, _slot_to_dict, ) from app.services.storage_facility_code import build_full_slot_code def _facility(node_id: str, node_code: str, parent_id: str = "0") -> SimpleNamespace: return SimpleNamespace( id=node_id, node_code=node_code, parent_id=parent_id, node_name=node_code, ) def _slot(slot_id: str, facility_node_id: str, slot_code: str, remark: str = "") -> SimpleNamespace: return SimpleNamespace( id=slot_id, facility_node_id=facility_node_id, slot_code=slot_code, slot_status="空", occupied_count=0, tenant_no="zkxw", order_num=1, remark=remark, create_time=None, update_time=None, ) def test_full_slot_code_substring_match(): facilities = { "box": _facility("box", "BOX01", "shelf"), "shelf": _facility("shelf", "A1", "root"), "root": _facility("root", "FRZ", "0"), } slot = _slot("s1", "box", "03") full = build_full_slot_code("box", "03", facilities) assert full == "FRZ-A1-BOX01-03" row = _slot_to_dict(slot, facilities) assert row["fullSlotCode"] == full assert _slot_matches_select_keyword(slot, "FRZ-A1-BOX01-03", facilities, set()) assert _slot_matches_select_keyword(slot, "BOX01-03", facilities, set()) assert _slot_matches_select_keyword(slot, "FRZ-A1", facilities, set()) def test_local_slot_code_and_remark_still_match(): facilities = {"box": _facility("box", "BOX01", "0")} slot = _slot("s1", "box", "07", remark="备用格") assert _slot_matches_select_keyword(slot, "07", facilities, set()) assert _slot_matches_select_keyword(slot, "备用", facilities, set()) def test_facility_node_name_match(): facilities = { "box": _facility("box", "BOX01", "0"), } facilities["box"].node_name = "液氮盒A" slot = _slot("s1", "box", "01") assert _slot_matches_select_keyword(slot, "液氮", facilities, {"box"}) def test_leaf_node_ids_for_path_prefix(): facilities = { "box": _facility("box", "BOX01", "shelf"), "shelf": _facility("shelf", "A1", "root"), "root": _facility("root", "FRZ", "0"), } ids = _leaf_node_ids_for_path_prefix(facilities, "FRZ-A1") assert ids == {"box", "shelf", "root"} assert "box" in _leaf_node_ids_for_path_prefix(facilities, "BOX01") def test_no_match_returns_false(): facilities = {"box": _facility("box", "BOX01", "0")} slot = _slot("s1", "box", "01") assert not _slot_matches_select_keyword(slot, "NOT-EXIST", facilities, set()) def test_resolve_path_keyword_for_box_prefix(): facilities = { "box": _facility("box", "2", "shelf"), "shelf": _facility("shelf", "1", "root"), "root": _facility("root", "1", "0"), } path_cache = _build_node_path_cache(facilities) assert _resolve_path_keyword(path_cache, "1-1-2-") == ("1-1-2", None) assert _resolve_path_keyword(path_cache, "1-1-2") == ("1-1-2", None) assert _resolve_path_keyword(path_cache, "1-1-2-1") == ("1-1-2", "1") assert _exact_node_ids_for_path(path_cache, "1-1-2") == ["box"] def test_trailing_dash_matches_all_slots_in_box(): facilities = { "box": _facility("box", "2", "shelf"), "shelf": _facility("shelf", "1", "root"), "root": _facility("root", "1", "0"), } slots = [_slot("s1", "box", "1"), _slot("s2", "box", "2")] kw = "1-1-2-" for slot in slots: assert _slot_matches_select_keyword(slot, kw, facilities, set()) def test_non_leaf_path_expands_to_descendant_leaves(): facilities = { "layer2": _facility("layer2", "2", "shelf"), "layer10": _facility("layer10", "10", "shelf"), "shelf": _facility("shelf", "1", "root"), "root": _facility("root", "1", "0"), } facilities["layer2"].is_leaf = 1 facilities["layer10"].is_leaf = 1 path_cache = _build_node_path_cache(facilities) host_ids = _collect_slot_host_node_ids(path_cache, facilities, "1-1") assert set(host_ids) == {"layer2", "layer10"} assert _collect_slot_host_node_ids(path_cache, facilities, "1-1-2") == ["layer2"]