From 0fa19687742caa771c4a8f0716f07005497bec49 Mon Sep 17 00:00:00 2001 From: Luc Genetier <69138830+LucGenetier@users.noreply.github.com> Date: Mon, 13 Jan 2025 21:51:44 +0100 Subject: [PATCH] Add UseDefaultBodyNameForSinglePropertyObject (#2815) In Power Apps, when a body parameter is used it's flattened and we create one paramaeter for each body object property. With that logic each parameter name will be the object property name. When UseDefaultBodyNameForSinglePropertyObject is set, we will use the real body name specified in the swagger instead of the property name of the object, provided there is only one property. --- .../ConnectorFunction.cs | 7 ++++++- .../Public/ConnectorSettings.cs | 10 +++++++++- .../PowerPlatformConnectorTests.cs | 19 +++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/libraries/Microsoft.PowerFx.Connectors/ConnectorFunction.cs b/src/libraries/Microsoft.PowerFx.Connectors/ConnectorFunction.cs index 52020a78bc..ee49cf5002 100644 --- a/src/libraries/Microsoft.PowerFx.Connectors/ConnectorFunction.cs +++ b/src/libraries/Microsoft.PowerFx.Connectors/ConnectorFunction.cs @@ -1460,7 +1460,12 @@ private ConnectorParameterInternals Initialize() OpenApiSchema bodyPropertySchema = bodyProperty.Value; string bodyPropertyName = bodyProperty.Key; bool bodyPropertyRequired = bodySchema.Required.Contains(bodyPropertyName); - bool bodyPropertyHiddenRequired = false; + bool bodyPropertyHiddenRequired = false; + + if (ConnectorSettings.UseDefaultBodyNameForSinglePropertyObject && bodySchema.Properties.Count == 1) + { + bodyPropertyName = bodyName; + } if (bodyPropertySchema.IsInternal()) { diff --git a/src/libraries/Microsoft.PowerFx.Connectors/Public/ConnectorSettings.cs b/src/libraries/Microsoft.PowerFx.Connectors/Public/ConnectorSettings.cs index c40b808bc0..82431b299a 100644 --- a/src/libraries/Microsoft.PowerFx.Connectors/Public/ConnectorSettings.cs +++ b/src/libraries/Microsoft.PowerFx.Connectors/Public/ConnectorSettings.cs @@ -92,7 +92,15 @@ public bool ExposeInternalParamsWithoutDefaultValue /// This flag will force all enums to be returns as FormulaType.String or FormulaType.Decimal regardless of x-ms-enum-*. /// This flag is only in effect when SupportXMsEnumValues is true. /// - public bool ReturnEnumsAsPrimitive { get; init; } = false; + public bool ReturnEnumsAsPrimitive { get; init; } = false; + + /// + /// In Power Apps, when a body parameter is used it's flattened and we create one parameter for each + /// body object property. With that logic each parameter name will be the object property name. + /// When set, this setting will use the real body name specified in the swagger instead of the property name + /// of the object, provided there is only one property. + /// + public bool UseDefaultBodyNameForSinglePropertyObject { get; init; } = false; public ConnectorCompatibility Compatibility { get; init; } = ConnectorCompatibility.Default; } diff --git a/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/PowerPlatformConnectorTests.cs b/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/PowerPlatformConnectorTests.cs index f5817a9ea9..77c7cf72fe 100644 --- a/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/PowerPlatformConnectorTests.cs +++ b/src/tests/Microsoft.PowerFx.Connectors.Tests.Shared/PowerPlatformConnectorTests.cs @@ -2399,6 +2399,25 @@ public async Task SQL_ExecuteStoredProc_Scoped() Assert.Equal(expected, actual); } + [Theory] + [InlineData(true)] + [InlineData(false)] + public void ExchangeOnlineTest2(bool useDefaultBodyNameForSinglePropertyObject) + { + using var testConnector = new LoggingTestServer(@"Swagger\ExcelOnlineBusiness.swagger.json", _output); + List functions = OpenApiParser.GetFunctions( + new ConnectorSettings("Excel") + { + Compatibility = ConnectorCompatibility.Default, + UseDefaultBodyNameForSinglePropertyObject = useDefaultBodyNameForSinglePropertyObject + }, + testConnector._apiDocument).ToList(); + + ConnectorFunction patchItem = functions.First(f => f.Name == "PatchItem"); + + Assert.Equal(!useDefaultBodyNameForSinglePropertyObject ? "dynamicProperties" : "item", patchItem.OptionalParameters[2].Name); + } + public class HttpLogger : HttpClient { private readonly ITestOutputHelper _console;