From b485ad6c799c96b4ffd8c7080b809c0581eab5cb Mon Sep 17 00:00:00 2001 From: Julien Barreau Date: Wed, 2 Apr 2025 10:48:53 +0200 Subject: [PATCH 1/2] fix(uuid): record containing uuid doesn't crash at create anymore --- .../forestadmin/agent_toolkit/resources/collections/crud.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/agent_toolkit/forestadmin/agent_toolkit/resources/collections/crud.py b/src/agent_toolkit/forestadmin/agent_toolkit/resources/collections/crud.py index 2157700db..dcb56ead4 100644 --- a/src/agent_toolkit/forestadmin/agent_toolkit/resources/collections/crud.py +++ b/src/agent_toolkit/forestadmin/agent_toolkit/resources/collections/crud.py @@ -402,7 +402,7 @@ async def extract_data( field = collection.get_field(field_name) if is_column(field): if field["column_type"] == PrimitiveType.UUID: - record[field_name] = UUID(value) + record[field_name] = UUID(value) if isinstance(value, str) else value else: record[field_name] = value elif ( From 2919957a961f2343111d5bc8a1443eed237a9c82 Mon Sep 17 00:00:00 2001 From: Julien Barreau Date: Wed, 2 Apr 2025 10:49:23 +0200 Subject: [PATCH 2/2] chore: add test --- .../tests/resources/collections/test_crud.py | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/src/agent_toolkit/tests/resources/collections/test_crud.py b/src/agent_toolkit/tests/resources/collections/test_crud.py index 063fe348d..3b314106c 100644 --- a/src/agent_toolkit/tests/resources/collections/test_crud.py +++ b/src/agent_toolkit/tests/resources/collections/test_crud.py @@ -5,6 +5,7 @@ import sys from unittest import TestCase from unittest.mock import ANY, AsyncMock, Mock, patch +from uuid import UUID if sys.version_info >= (3, 9): import zoneinfo @@ -222,6 +223,53 @@ def _create_collections(cls): }, ) + # to test with uuid + cls.collection_book = cls._create_collection( + "book", + { + "id": { + "column_type": PrimitiveType.UUID, + "is_primary_key": True, + "type": FieldType.COLUMN, + "filter_operators": {Operator.IN, Operator.EQUAL}, + }, + "name": { + "column_type": PrimitiveType.STRING, + "is_primary_key": False, + "type": FieldType.COLUMN, + "filter_operators": {Operator.IN, Operator.EQUAL}, + }, + "author_id": { + "column_type": PrimitiveType.UUID, + "type": FieldType.COLUMN, + "filter_operators": {Operator.IN, Operator.EQUAL}, + }, + "author": { + "type": FieldType.MANY_TO_ONE, + "foreign_collection": "author", + "foreign_key_target": "id", + "foreign_key": "author_id", + }, + }, + ) + cls.collection_author = cls._create_collection( + "Author", + { + "id": { + "column_type": PrimitiveType.UUID, + "is_primary_key": True, + "type": FieldType.COLUMN, + "filter_operators": {Operator.IN, Operator.EQUAL}, + }, + "name": { + "column_type": PrimitiveType.STRING, + "is_primary_key": False, + "type": FieldType.COLUMN, + "filter_operators": {Operator.IN, Operator.EQUAL}, + }, + }, + ) + @classmethod def setUpClass(cls) -> None: cls.loop = asyncio.new_event_loop() @@ -243,6 +291,8 @@ def setUpClass(cls) -> None: "cart": cls.collection_cart, "product": cls.collection_product, "tag": cls.collection_tag, + # for uuid + "author": cls.collection_author, } cls.datasource_composite.add_datasource(cls.datasource) @@ -957,6 +1007,50 @@ def test_add_should_return_to_many_relations_as_link(self): }, ) + def test_add_with_uuid_should_work_with_uuid_as_obj_or_str(self): + for uuid in ["123e4567-e89b-12d3-a456-426614174000", UUID("123e4567-e89b-12d3-a456-426614174000")]: + request = RequestCollection( + RequestMethod.POST, + self.collection_book, + body={ + "data": { + "attributes": {"name": "Foundation", "id": uuid, "author_id": uuid}, + "relationships": {}, + }, + "type": "book", + }, + query={ + "collection_name": "book", + "timezone": "Europe/Paris", + }, + headers={}, + client_ip="127.0.0.1", + ) + crud_resource = CrudResource( + self.datasource_composite, + self.datasource, + self.permission_service, + self.ip_white_list_service, + self.options, + ) + with patch.object( + self.collection_book, + "create", + new_callable=AsyncMock, + return_value=[{"name": "Foundation", "id": str(uuid), "author_id": str(uuid)}], + ) as mock_create: + self.loop.run_until_complete(crud_resource.add(request)) + mock_create.assert_any_await( + FAKE_USER, + [ + { + "name": "Foundation", + "id": UUID("123e4567-e89b-12d3-a456-426614174000"), + "author_id": UUID("123e4567-e89b-12d3-a456-426614174000"), + } + ], + ) + # list def test_list(self): mock_orders = [{"id": 10, "cost": 200}, {"id": 11, "cost": 201}]