diff --git a/backend/src/baserow/contrib/automation/workflows/handler.py b/backend/src/baserow/contrib/automation/workflows/handler.py index f8434ee9c6..fe5c1e9d86 100644 --- a/backend/src/baserow/contrib/automation/workflows/handler.py +++ b/backend/src/baserow/contrib/automation/workflows/handler.py @@ -905,7 +905,7 @@ def toggle_test_run( updated. :param workflow: The workflow we want to trigger the test run for. - :param simulated_until_node: If we want to simulate until a particular node. + :param simulate_until_node: If we want to simulate until a particular node. """ if workflow.simulate_until_node is not None or workflow.allow_test_run_until: diff --git a/backend/src/baserow/contrib/integrations/local_baserow/service_types.py b/backend/src/baserow/contrib/integrations/local_baserow/service_types.py index df3db9615b..464e711992 100644 --- a/backend/src/baserow/contrib/integrations/local_baserow/service_types.py +++ b/backend/src/baserow/contrib/integrations/local_baserow/service_types.py @@ -1326,7 +1326,7 @@ def prepare_values( :param values: The values defining the aggregate rows service type. - :param user: The user on whos behalf the aggregation is + :param user: The user on whose behalf the aggregation is requested. :param instance: The service instance. """ @@ -1487,7 +1487,7 @@ def dispatch_data( raise ServiceImproperlyConfiguredDispatchException( f"The field with ID {service.field.id} is trashed." ) - field = service.field + field = service.field.specific model = self.get_table_model(service) model_field = model._meta.get_field(field.db_column) queryset = self.build_queryset( @@ -1499,6 +1499,7 @@ def dispatch_data( return { "data": {"result": result}, "baserow_table_model": model, + "field": field, } except DjangoFieldDoesNotExist as ex: raise ServiceImproperlyConfiguredDispatchException( @@ -1522,7 +1523,18 @@ def dispatch_transform( :return: A dictionary containing the aggregation result. """ - return DispatchResult(data=data["data"]) + # Use the field type's serializer field to ensure the aggregation result + # is serialized correctly. Some aggregations can return values which are not + # JSON serializable (e.g. Decimal), so we need to use the serializer field + # to convert them into a JSON serializable format. + result = ( + data["field"] + .get_type() + .get_serializer_field(data["field"]) + .to_representation(data["data"]["result"]) + ) + + return DispatchResult(data={"result": result}) def extract_properties(self, path: List[str], **kwargs) -> List[str]: """ diff --git a/backend/tests/baserow/contrib/dashboard/api/data_sources/test_dashboard_data_source_views.py b/backend/tests/baserow/contrib/dashboard/api/data_sources/test_dashboard_data_source_views.py index 2c511ebcb0..0d83370477 100644 --- a/backend/tests/baserow/contrib/dashboard/api/data_sources/test_dashboard_data_source_views.py +++ b/backend/tests/baserow/contrib/dashboard/api/data_sources/test_dashboard_data_source_views.py @@ -401,7 +401,7 @@ def test_dispatch_dashboard_data_source(api_client, data_fixture): response_json = response.json() assert response.status_code == HTTP_200_OK - assert response_json == {"result": 60} + assert response_json == {"result": "60"} @pytest.mark.django_db diff --git a/backend/tests/baserow/contrib/dashboard/data_sources/test_dashboard_data_source_handler.py b/backend/tests/baserow/contrib/dashboard/data_sources/test_dashboard_data_source_handler.py index 20226c1c35..a51b16aee5 100644 --- a/backend/tests/baserow/contrib/dashboard/data_sources/test_dashboard_data_source_handler.py +++ b/backend/tests/baserow/contrib/dashboard/data_sources/test_dashboard_data_source_handler.py @@ -361,7 +361,7 @@ def test_dispatch_data_source(data_fixture): data_source, dispatch_context ) - assert result == {"result": 60} + assert result == {"result": "60"} @pytest.mark.django_db diff --git a/backend/tests/baserow/contrib/dashboard/data_sources/test_dashboard_data_source_service.py b/backend/tests/baserow/contrib/dashboard/data_sources/test_dashboard_data_source_service.py index 255726f606..1fdf18f6f5 100644 --- a/backend/tests/baserow/contrib/dashboard/data_sources/test_dashboard_data_source_service.py +++ b/backend/tests/baserow/contrib/dashboard/data_sources/test_dashboard_data_source_service.py @@ -352,7 +352,7 @@ def test_dispatch_data_source(data_fixture): user, data_source.id, dispatch_context ) - assert result == {f"result": 60} + assert result == {"result": "60"} @pytest.mark.django_db diff --git a/backend/tests/baserow/contrib/integrations/local_baserow/service_types/test_aggregate_rows_service_type.py b/backend/tests/baserow/contrib/integrations/local_baserow/service_types/test_aggregate_rows_service_type.py index ed480892be..51a762ef13 100644 --- a/backend/tests/baserow/contrib/integrations/local_baserow/service_types/test_aggregate_rows_service_type.py +++ b/backend/tests/baserow/contrib/integrations/local_baserow/service_types/test_aggregate_rows_service_type.py @@ -15,6 +15,8 @@ ) from baserow.core.services.handler import ServiceHandler from baserow.core.services.registries import service_type_registry +from baserow.core.services.types import DispatchResult +from baserow.core.trash.handler import TrashHandler from baserow.test_utils.pytest_conftest import FakeDispatchContext @@ -238,6 +240,9 @@ def test_local_baserow_aggregate_rows_dispatch_data_with_table(data_fixture): result = service_type.dispatch_data(service, dispatch_values, dispatch_context) assert result["baserow_table_model"] assert result["data"] == {"result": Decimal("20")} + assert service_type.dispatch_transform(result) == DispatchResult( + data={"result": "20"}, status=200, output_uid="" + ) @pytest.mark.django_db @@ -278,6 +283,9 @@ def test_local_baserow_aggregate_rows_dispatch_data_with_view(data_fixture): result = service_type.dispatch_data(service, dispatch_values, dispatch_context) assert result["baserow_table_model"] assert result["data"] == {"result": Decimal("20")} + assert service_type.dispatch_transform(result) == DispatchResult( + data={"result": "20"}, status=200, output_uid="" + ) @pytest.mark.django_db @@ -501,11 +509,12 @@ def test_local_baserow_aggregate_rows_dispatch_data_field_deleted(data_fixture): dispatch_context = FakeDispatchContext() dispatch_values = service_type.resolve_service_formulas(service, dispatch_context) - field.delete() + TrashHandler.trash(user, dashboard.workspace, dashboard, field) + service.refresh_from_db(fields=["field"]) with pytest.raises(ServiceImproperlyConfiguredDispatchException) as exc: service_type.dispatch_data(service, dispatch_values, dispatch_context) - assert exc.value.args[0] == f"The field with ID {field.id} does not exist." + assert exc.value.args[0] == f"The field with ID {field.id} is trashed." @pytest.mark.django_db diff --git a/changelog/entries/unreleased/bug/resolved_an_issue_which_prevented_summarize_rows_nodes_in_au.json b/changelog/entries/unreleased/bug/resolved_an_issue_which_prevented_summarize_rows_nodes_in_au.json new file mode 100644 index 0000000000..3b47493d0d --- /dev/null +++ b/changelog/entries/unreleased/bug/resolved_an_issue_which_prevented_summarize_rows_nodes_in_au.json @@ -0,0 +1,9 @@ +{ + "type": "bug", + "message": "Resolved an issue which prevented summarize rows nodes in automation workflows from working correctly.", + "issue_origin": "github", + "issue_number": null, + "domain": "automation", + "bullet_points": [], + "created_at": "2026-02-25" +} \ No newline at end of file