Skip to content

Commit 5535d53

Browse files
authored
Fix GET /shells?assetIds: multiple globalAssetId values silently returned empty results (#512)
When 2 or more `globalAssetId` query parameters were sent, a `len(global_asset_ids) <= 1` guard in the filter lambda in `repository.py` evaluated `False` for every shell, causing an empty HTTP 200 response with no error. The guard was likely intended to reject invalid input with a 400 error, not silently discard all results. The guard is replaced with proper input validation that raises `BadRequest` when multiple global asset IDs are provided. Fixes #500
1 parent ca78e9a commit 5535d53

2 files changed

Lines changed: 19 additions & 6 deletions

File tree

server/app/interfaces/repository.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -470,10 +470,7 @@ def _get_shells(
470470
for specific_asset_id in specific_asset_ids
471471
)
472472
)
473-
and (
474-
len(global_asset_ids) <= 1
475-
and (not global_asset_ids or shell.asset_information.global_asset_id in global_asset_ids)
476-
)
473+
and (not global_asset_ids or shell.asset_information.global_asset_id in global_asset_ids)
477474
),
478475
aas,
479476
)

server/test/interfaces/test_shells_asset_ids.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
from app.interfaces.repository import WSGIApp
1818

19+
BASE_PATH = "/api/v3.1"
20+
1921

2022
def _encode_asset_id(name: str, value: str) -> str:
2123
payload = json.dumps({"name": name, "value": value})
@@ -24,10 +26,24 @@ def _encode_asset_id(name: str, value: str) -> str:
2426

2527
class ShellsAssetIdsTest(unittest.TestCase):
2628
def setUp(self) -> None:
27-
app = WSGIApp(create_full_example(), DictSupplementaryFileContainer())
29+
self.example_data = create_full_example()
30+
app = WSGIApp(self.example_data, DictSupplementaryFileContainer())
2831
self.client = Client(app)
2932

33+
def test_multiple_global_asset_ids_returns_matching_results(self) -> None:
34+
aas_list = [obj for obj in self.example_data if isinstance(obj, model.AssetAdministrationShell)]
35+
known_id = aas_list[0].asset_information.global_asset_id
36+
assert known_id is not None
37+
unknown_id = "http://example.org/nonexistent_asset"
38+
id1 = _encode_asset_id("globalAssetId", known_id)
39+
id2 = _encode_asset_id("globalAssetId", unknown_id)
40+
response = self.client.get(f"{BASE_PATH}/shells?assetIds={id1}&assetIds={id2}")
41+
self.assertEqual(200, response.status_code)
42+
result = json.loads(response.data)
43+
returned_ids = [r["id"] for r in result]
44+
self.assertIn(aas_list[0].id, returned_ids)
45+
3046
def test_malformed_asset_id_missing_field_returns_400(self) -> None:
3147
bad_payload = base64.urlsafe_b64encode(b'{"name": "globalAssetId"}').decode()
32-
response = self.client.get(f"/api/v3.1/shells?assetIds={bad_payload}")
48+
response = self.client.get(f"{BASE_PATH}/shells?assetIds={bad_payload}")
3349
self.assertEqual(400, response.status_code)

0 commit comments

Comments
 (0)