diff --git a/src/System.Web.OData/OData/Routing/UnboundFunctionPathSegmentTemplate.cs b/src/System.Web.OData/OData/Routing/UnboundFunctionPathSegmentTemplate.cs index 34490336..6f321d08 100644 --- a/src/System.Web.OData/OData/Routing/UnboundFunctionPathSegmentTemplate.cs +++ b/src/System.Web.OData/OData/Routing/UnboundFunctionPathSegmentTemplate.cs @@ -9,6 +9,8 @@ namespace System.Web.Http.OData.Routing /// public class UnboundFunctionPathSegmentTemplate : ODataPathSegmentTemplate { + private string _functionName; + /// /// Initializes a new instance of the class. /// @@ -20,6 +22,7 @@ namespace System.Web.Http.OData.Routing throw Error.ArgumentNull("function"); } + _functionName = function.FunctionName; ParameterMappings = KeyValuePathSegmentTemplate.BuildParameterMappings(function.Values, function.ToString()); } @@ -35,7 +38,10 @@ namespace System.Web.Http.OData.Routing if (pathSegment.SegmentKind == ODataSegmentKinds.UnboundFunction) { UnboundFunctionPathSegment functionSegment = (UnboundFunctionPathSegment)pathSegment; - return KeyValuePathSegmentTemplate.TryMatch(ParameterMappings, functionSegment.Values, values); + if (_functionName == functionSegment.FunctionName) + { + return KeyValuePathSegmentTemplate.TryMatch(ParameterMappings, functionSegment.Values, values); + } } return false; diff --git a/test/System.Web.OData.Test/OData/Routing/DefaultODataPathHandlerTest.cs b/test/System.Web.OData.Test/OData/Routing/DefaultODataPathHandlerTest.cs index 8c6d7793..efa4dc21 100644 --- a/test/System.Web.OData.Test/OData/Routing/DefaultODataPathHandlerTest.cs +++ b/test/System.Web.OData.Test/OData/Routing/DefaultODataPathHandlerTest.cs @@ -940,6 +940,30 @@ namespace System.Web.Http.OData.Routing Assert.Equal(keyValues.OrderBy(k => k), routeData.Select(d => d.Key + ":" + d.Value).OrderBy(d => d)); } + [Theory] + [InlineData("Customer")] // Customer is not a correct entity set in the model + [InlineData("UnknowFunction(foo={newFoo})")] // UnknowFunction is not a function name in the model + public void ParseTemplate_ThrowODataException_InvalidODataPathSegmentTemplate(string template) + { + // Arrange + CustomersModelWithInheritance model = new CustomersModelWithInheritance(); + + // Act & Assert + Assert.Throws(() => _parser.ParseTemplate(model.Model, template), + "The given OData path template '" + template + "' is invalid."); + } + + [Fact] + public void ParseTemplate_ThrowODataException_UnResolvedPathSegment() + { + // Arrange + CustomersModelWithInheritance model = new CustomersModelWithInheritance(); + + // Act & Assert + Assert.Throws(() => _parser.ParseTemplate(model.Model, "Customers(ID={key})/Order"), + "Found an unresolved path segment 'Order' in the OData path template 'Customers(ID={key})/Order'."); + } + private static void AssertTypeMatchesExpectedType(string odataPath, string expectedSetName, string expectedTypeName, bool isCollection) { // Arrange diff --git a/test/System.Web.OData.Test/OData/Routing/UnboundFunctionPathSegmentTemplateTest.cs b/test/System.Web.OData.Test/OData/Routing/UnboundFunctionPathSegmentTemplateTest.cs index 2e08e7ce..861318fd 100644 --- a/test/System.Web.OData.Test/OData/Routing/UnboundFunctionPathSegmentTemplateTest.cs +++ b/test/System.Web.OData.Test/OData/Routing/UnboundFunctionPathSegmentTemplateTest.cs @@ -31,7 +31,7 @@ namespace System.Web.Http.OData.Routing "Function", new EdmEntityTypeReference(returnType, isNullable: false))); - Dictionary parameterMappings = new Dictionary() + Dictionary parameterMappings = new Dictionary { { "Parameter1", "{param1}" }, { "Parameter2", "{param2}" } @@ -60,6 +60,44 @@ namespace System.Web.Http.OData.Routing "Function", new EdmEntityTypeReference(returnType, isNullable: false))); + Dictionary parameterValues = new Dictionary + { + { "Parameter1", "1" }, + { "Parameter2", "2" } + }; + + Dictionary parameterMappings = new Dictionary + { + { "Parameter1", "{param1}" }, + { "Parameter2", "{param2}" } + }; + + UnboundFunctionPathSegment segment = new UnboundFunctionPathSegment(function, model, parameterValues); + UnboundFunctionPathSegmentTemplate template = new UnboundFunctionPathSegmentTemplate( + new UnboundFunctionPathSegment(function, model, parameterMappings)); + + // Act + Dictionary values = new Dictionary(); + bool result = template.TryMatch(segment, values); + + // Assert + Assert.True(result); + Assert.Equal(2, values.Count); + Assert.Equal("1", values["param1"]); + Assert.Equal("2", values["param2"]); + } + + [Fact] + public void TryMatch_ReturnsFalse_IfDifferentUnboundFunctionWithSameParamerters() + { + // Arrange + IEdmModel model = new Mock().Object; + IEdmEntityType returnType = new Mock().Object; + EdmEntityContainer container = new EdmEntityContainer("NS", "Container"); + EdmFunction function = new EdmFunction("NS", "Function", new EdmEntityTypeReference(returnType, isNullable: false)); + EdmFunctionImport functionImport1 = new EdmFunctionImport(container,"FunctionImport1", function); + EdmFunctionImport functionImport2 = new EdmFunctionImport(container,"FunctionImport2", function); + Dictionary parameterValues = new Dictionary() { { "Parameter1", "1" }, @@ -72,19 +110,16 @@ namespace System.Web.Http.OData.Routing { "Parameter2", "{param2}" } }; - UnboundFunctionPathSegment segment = new UnboundFunctionPathSegment(function, model, parameterValues: parameterValues); - UnboundFunctionPathSegmentTemplate template = new UnboundFunctionPathSegmentTemplate( - new UnboundFunctionPathSegment(function, model, parameterValues: parameterMappings)); + UnboundFunctionPathSegment segment = new UnboundFunctionPathSegment(functionImport1, model, parameterValues); + var template = new UnboundFunctionPathSegmentTemplate( + new UnboundFunctionPathSegment(functionImport2, model, parameterMappings)); + Dictionary values = new Dictionary(); // Act - Dictionary values = new Dictionary(); bool result = template.TryMatch(segment, values); // Assert - Assert.True(result); - Assert.Equal(2, values.Count); - Assert.Equal("1", values["param1"]); - Assert.Equal("2", values["param2"]); + Assert.False(result); } } }