|
12 | 12 | using Microsoft.OData.Edm; |
13 | 13 | using Microsoft.OData.Edm.Csdl; |
14 | 14 | using Microsoft.OData.Edm.Validation; |
| 15 | +using Microsoft.OpenApi.Models; |
15 | 16 | using Microsoft.OpenApi.OData.Tests; |
16 | 17 | using Xunit; |
17 | 18 |
|
@@ -921,6 +922,76 @@ private static IEdmModel GetNavPropModel(string annotation) |
921 | 922 | return GetEdmModel(template); |
922 | 923 | } |
923 | 924 |
|
| 925 | + [Fact] |
| 926 | + public void GetPathsForDerivedTypeDeltaFunctionUsesCorrectReturnType() |
| 927 | + { |
| 928 | + // Arrange – mirrors the Graph scenario: |
| 929 | + // directoryObject (base) has delta with RequiresExplicitBinding |
| 930 | + // servicePrincipal (derived) has its own delta |
| 931 | + // agentIdentity (derived from servicePrincipal) causes servicePrincipal to have derived types |
| 932 | + // Bug: TryAddPath kept the base-type delta for /servicePrincipals/delta() because |
| 933 | + // servicePrincipal has derived types. |
| 934 | + string csdl = @"<edmx:Edmx Version=""4.0"" xmlns:edmx=""http://docs.oasis-open.org/odata/ns/edmx""> |
| 935 | + <edmx:DataServices> |
| 936 | + <Schema Namespace=""NS"" xmlns=""http://docs.oasis-open.org/odata/ns/edm""> |
| 937 | + <EntityType Name=""directoryObject""> |
| 938 | + <Key> |
| 939 | + <PropertyRef Name=""id"" /> |
| 940 | + </Key> |
| 941 | + <Property Name=""id"" Type=""Edm.String"" Nullable=""false"" /> |
| 942 | + </EntityType> |
| 943 | + <EntityType Name=""servicePrincipal"" BaseType=""NS.directoryObject""> |
| 944 | + <Property Name=""appId"" Type=""Edm.String"" /> |
| 945 | + </EntityType> |
| 946 | + <EntityType Name=""agentIdentity"" BaseType=""NS.servicePrincipal""> |
| 947 | + <Property Name=""blueprintId"" Type=""Edm.String"" /> |
| 948 | + </EntityType> |
| 949 | + <Function Name=""delta"" IsBound=""true""> |
| 950 | + <Parameter Name=""bindingParameter"" Type=""Collection(NS.directoryObject)"" /> |
| 951 | + <ReturnType Type=""Collection(NS.directoryObject)"" /> |
| 952 | + <Annotation Term=""Org.OData.Core.V1.RequiresExplicitBinding"" /> |
| 953 | + </Function> |
| 954 | + <Function Name=""delta"" IsBound=""true""> |
| 955 | + <Parameter Name=""bindingParameter"" Type=""Collection(NS.servicePrincipal)"" /> |
| 956 | + <ReturnType Type=""Collection(NS.servicePrincipal)"" /> |
| 957 | + </Function> |
| 958 | + <EntityContainer Name=""Default""> |
| 959 | + <EntitySet Name=""directoryObjects"" EntityType=""NS.directoryObject"" /> |
| 960 | + <EntitySet Name=""servicePrincipals"" EntityType=""NS.servicePrincipal"" /> |
| 961 | + </EntityContainer> |
| 962 | + <Annotations Target=""NS.directoryObject""> |
| 963 | + <Annotation Term=""Org.OData.Core.V1.ExplicitOperationBindings""> |
| 964 | + <Collection> |
| 965 | + <String>NS.delta</String> |
| 966 | + </Collection> |
| 967 | + </Annotation> |
| 968 | + </Annotations> |
| 969 | + </Schema> |
| 970 | + </edmx:DataServices> |
| 971 | +</edmx:Edmx>"; |
| 972 | + |
| 973 | + bool result = CsdlReader.TryParse(XElement.Parse(csdl).CreateReader(), out IEdmModel model, out _); |
| 974 | + Assert.True(result); |
| 975 | + |
| 976 | + var settings = new OpenApiConvertSettings(); |
| 977 | + OpenApiDocument doc = model.ConvertToOpenApi(settings); |
| 978 | + |
| 979 | + // Assert – the /servicePrincipals/NS.delta() path should exist and its response |
| 980 | + // should reference NS.servicePrincipal, not NS.directoryObject |
| 981 | + Assert.True(doc.Paths.ContainsKey("/servicePrincipals/NS.delta()"), |
| 982 | + $"Expected path not found. Available: {string.Join(", ", doc.Paths.Keys)}"); |
| 983 | + |
| 984 | + var pathItem = doc.Paths["/servicePrincipals/NS.delta()"]; |
| 985 | + var getOp = pathItem.Operations[OperationType.Get]; |
| 986 | + Assert.NotNull(getOp); |
| 987 | + |
| 988 | + // The response schema title should reference servicePrincipal, not directoryObject |
| 989 | + var responseKey = getOp.Responses.Keys.First(); |
| 990 | + var response = getOp.Responses[responseKey]; |
| 991 | + var schema = response.Content["application/json"].Schema; |
| 992 | + Assert.Contains("servicePrincipal", schema.Title); |
| 993 | + } |
| 994 | + |
924 | 995 | private static IEdmModel GetEdmModel(string schema) |
925 | 996 | { |
926 | 997 | bool parsed = SchemaReader.TryParse(new XmlReader[] { XmlReader.Create(new StringReader(schema)) }, out IEdmModel parsedModel, out IEnumerable<EdmError> errors); |
|
0 commit comments