Skip to content

Commit 2c24f97

Browse files
fix(): Bug causing selector ID string dangling in the JSON after selector expansion (#1632)
1 parent 084a07f commit 2c24f97

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

flow360/component/simulation/framework/entity_selector.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,23 @@ def _expand_node_selectors(
767767

768768
node["stored_entities"] = base_entities
769769

770+
# Replace string tokens with full selector definitions for pydantic validation
771+
if known_selectors:
772+
expanded_selectors = []
773+
for item in selectors_value:
774+
if isinstance(item, str):
775+
# ID string token
776+
if item in known_selectors:
777+
expanded_selectors.append(known_selectors[item])
778+
else:
779+
raise ValueError(
780+
f"[Internal] Selector token '{item}' not found in known_selectors. "
781+
"This may indicate a missing or invalid selector reference."
782+
)
783+
else:
784+
expanded_selectors.append(item)
785+
node["selectors"] = expanded_selectors
786+
770787

771788
def collect_and_tokenize_selectors_in_place( # pylint: disable=too-many-branches
772789
params_as_dict: dict,

tests/simulation/framework/test_entity_selector_token.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import copy
22

3+
import pytest
4+
35
from flow360.component.simulation.framework.base_model import Flow360BaseModel
46
from flow360.component.simulation.framework.entity_selector import (
57
EntityDictDatabase,
8+
EntitySelector,
69
collect_and_tokenize_selectors_in_place,
710
expand_entity_selectors_in_place,
811
)
@@ -83,6 +86,22 @@ def test_entity_selector_token_flow():
8386
assert len(s2) == 2
8487
assert {e["name"] for e in s2} == {"wing_left", "wing_right"}
8588

89+
# 6. Verify selectors are expanded from tokens to full dicts (not strings)
90+
sel1 = expanded_params["models"][0]["selectors"]
91+
sel2 = expanded_params["models"][1]["selectors"]
92+
93+
assert len(sel1) == 1
94+
assert isinstance(sel1[0], dict), "Selector token should be expanded to dict"
95+
assert sel1[0]["selector_id"] == "sel1-token"
96+
assert sel1[0]["name"] == "sel1"
97+
98+
assert len(sel2) == 1
99+
assert isinstance(sel2[0], dict), "Selector token should be expanded to dict"
100+
101+
# 7. Verify expanded selectors can be validated as EntitySelector
102+
EntitySelector.model_validate(sel1[0])
103+
EntitySelector.model_validate(sel2[0])
104+
86105

87106
def test_entity_selector_token_round_trip_validation():
88107
params = {
@@ -176,3 +195,44 @@ def test_entity_selector_mixed_token_and_dict():
176195
assert "wing_left" in names
177196
assert "fuselage" in names
178197
assert len(names) == 2
198+
199+
# Verify selectors are all dicts after expansion (token resolved, inline kept)
200+
selectors = expanded["model"]["selectors"]
201+
assert len(selectors) == 2
202+
assert all(isinstance(s, dict) for s in selectors), "All selectors should be dicts"
203+
assert selectors[0]["selector_id"] == "sel-cache-id" # Token was expanded
204+
assert selectors[1]["selector_id"] == "sel-inline-id" # Inline kept as-is
205+
206+
# Verify both can be validated as EntitySelector
207+
for sel in selectors:
208+
EntitySelector.model_validate(sel)
209+
210+
211+
def test_entity_selector_unknown_token_raises_error():
212+
"""Test that referencing an unknown selector token raises a ValueError."""
213+
params = {
214+
"private_attribute_asset_cache": {
215+
"used_selectors": [
216+
{
217+
"selector_id": "known-selector-id",
218+
"target_class": "Surface",
219+
"name": "known_selector",
220+
"children": [{"attribute": "name", "operator": "matches", "value": "wing*"}],
221+
}
222+
]
223+
},
224+
"model": {
225+
"selectors": [
226+
"unknown-selector-id", # This token does not exist in used_selectors
227+
]
228+
},
229+
}
230+
231+
db = EntityDictDatabase(
232+
surfaces=[
233+
{"name": "wing_left", "private_attribute_entity_type_name": "Surface"},
234+
]
235+
)
236+
237+
with pytest.raises(ValueError, match="Selector token 'unknown-selector-id' not found"):
238+
expand_entity_selectors_in_place(db, params)

0 commit comments

Comments
 (0)