From cdfa71de7a39febdde8d170c923292ccf9438283 Mon Sep 17 00:00:00 2001 From: zrgt Date: Tue, 5 May 2026 15:59:31 +0200 Subject: [PATCH 1/2] fix: remove len(global_asset_ids)<=1 guard that silently emptied results for 2+ globalAssetId filters --- server/app/interfaces/repository.py | 5 +-- .../test/interfaces/test_shells_asset_ids.py | 43 +++++++++++++++++++ 2 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 server/test/interfaces/test_shells_asset_ids.py diff --git a/server/app/interfaces/repository.py b/server/app/interfaces/repository.py index 15a5213d..291049e2 100644 --- a/server/app/interfaces/repository.py +++ b/server/app/interfaces/repository.py @@ -463,10 +463,7 @@ def _get_shells(self, request: Request) -> Tuple[Iterator[model.AssetAdministrat for specific_asset_id in specific_asset_ids ) ) - and ( - len(global_asset_ids) <= 1 - and (not global_asset_ids or shell.asset_information.global_asset_id in global_asset_ids) - ) + and (not global_asset_ids or shell.asset_information.global_asset_id in global_asset_ids) ), aas, ) diff --git a/server/test/interfaces/test_shells_asset_ids.py b/server/test/interfaces/test_shells_asset_ids.py new file mode 100644 index 00000000..3cc6664e --- /dev/null +++ b/server/test/interfaces/test_shells_asset_ids.py @@ -0,0 +1,43 @@ +# Copyright (c) 2026 the Eclipse BaSyx Authors +# +# This program and the accompanying materials are made available under the terms of the MIT License, available in +# the LICENSE file of this project. +# +# SPDX-License-Identifier: MIT + +import base64 +import json +import unittest + +from basyx.aas import model +from basyx.aas.adapter.aasx import DictSupplementaryFileContainer +from basyx.aas.examples.data.example_aas import create_full_example +from werkzeug.test import Client + +from app.interfaces.repository import WSGIApp + +BASE_PATH = "/api/v3.1" + + +def _encode_asset_id(name: str, value: str) -> str: + payload = json.dumps({"name": name, "value": value}) + return base64.urlsafe_b64encode(payload.encode()).decode() + + +class ShellsAssetIdsTest(unittest.TestCase): + def setUp(self) -> None: + self.example_data = create_full_example() + app = WSGIApp(self.example_data, DictSupplementaryFileContainer()) + self.client = Client(app) + + def test_multiple_global_asset_ids_returns_matching_results(self) -> None: + aas_list = [obj for obj in self.example_data if isinstance(obj, model.AssetAdministrationShell)] + known_id = aas_list[0].asset_information.global_asset_id + unknown_id = "http://example.org/nonexistent_asset" + id1 = _encode_asset_id("globalAssetId", known_id) + id2 = _encode_asset_id("globalAssetId", unknown_id) + response = self.client.get(f"{BASE_PATH}/shells?assetIds={id1}&assetIds={id2}") + self.assertEqual(200, response.status_code) + result = json.loads(response.data) + returned_ids = [r["id"] for r in result] + self.assertIn(aas_list[0].id, returned_ids) From 1550a35aead4d5b56daec9856921e3af9f5a8a1b Mon Sep 17 00:00:00 2001 From: zrgt Date: Tue, 5 May 2026 17:25:31 +0200 Subject: [PATCH 2/2] fix: assert global_asset_id is not None to satisfy mypy --- server/test/interfaces/test_shells_asset_ids.py | 1 + 1 file changed, 1 insertion(+) diff --git a/server/test/interfaces/test_shells_asset_ids.py b/server/test/interfaces/test_shells_asset_ids.py index 3cc6664e..54080d81 100644 --- a/server/test/interfaces/test_shells_asset_ids.py +++ b/server/test/interfaces/test_shells_asset_ids.py @@ -33,6 +33,7 @@ def setUp(self) -> None: def test_multiple_global_asset_ids_returns_matching_results(self) -> None: aas_list = [obj for obj in self.example_data if isinstance(obj, model.AssetAdministrationShell)] known_id = aas_list[0].asset_information.global_asset_id + assert known_id is not None unknown_id = "http://example.org/nonexistent_asset" id1 = _encode_asset_id("globalAssetId", known_id) id2 = _encode_asset_id("globalAssetId", unknown_id)