OpenAPI.NET.OData/test/Microsoft.OpenAPI.OData.Reader.Tests/PathItem/RefPathItemHandlerTests.cs
Irvine Sunday 611067f2d3
[Enhancement] Creates DELETE operation for collection-valued nav. props $ref paths (#112)
* Generate collection nav. prop. entity paths for non-contained nav. props

* Revert previous changes

* Paths with DELETE operations for collection-valued nav. prop. $ref paths

* Don't create extra path for OData Key segment when creating DELETE for $ref

* Update tests

* Update test files

* Minor update to test commit signing

* Another minor update to trigger commit signing

* Update tests appropriately
2021-08-26 22:25:55 +03:00

159 lines
6.7 KiB
C#

// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Microsoft.OData.Edm.Validation;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Properties;
using Xunit;
namespace Microsoft.OpenApi.OData.PathItem.Tests
{
public class RefPathItemHandlerTest
{
private RefPathItemHandler _pathItemHandler = new RefPathItemHandler();
[Fact]
public void CreatePathItemThrowsForNullContext()
{
// Arrange & Act & Assert
Assert.Throws<ArgumentNullException>("context",
() => _pathItemHandler.CreatePathItem(context: null, path: new ODataPath()));
}
[Fact]
public void CreatePathItemThrowsForNullPath()
{
// Arrange & Act & Assert
Assert.Throws<ArgumentNullException>("path",
() => _pathItemHandler.CreatePathItem(new ODataContext(EdmCoreModel.Instance), path: null));
}
[Fact]
public void CreatePathItemThrowsForNonNavigationPropertyPath()
{
// Arrange
IEdmModel model = EntitySetPathItemHandlerTests.GetEdmModel(annotation: "");
ODataContext context = new ODataContext(model);
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("Customers");
Assert.NotNull(entitySet); // guard
var path = new ODataPath(new ODataNavigationSourceSegment(entitySet));
Assert.Equal(ODataPathKind.EntitySet, path.Kind); // guard
// Act
Action test = () => _pathItemHandler.CreatePathItem(context, path);
// Assert
var exception = Assert.Throws<InvalidOperationException>(test);
Assert.Equal(String.Format(SRResource.InvalidPathKindForPathItemHandler, "RefPathItemHandler", path.Kind), exception.Message);
}
[Theory]
[InlineData(true, new OperationType[] { OperationType.Delete})]
[InlineData(true, new OperationType[] { OperationType.Get, OperationType.Post})]
[InlineData(false, new OperationType[] { OperationType.Get, OperationType.Put, OperationType.Delete })]
public void CreateNavigationPropertyRefPathItemReturnsCorrectPathItem(bool collectionNav, OperationType[] expected)
{
// Arrange
IEdmModel model = GetEdmModel("");
ODataContext context = new ODataContext(model);
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("Customers");
Assert.NotNull(entitySet); // guard
IEdmEntityType entityType = entitySet.EntityType();
IEdmNavigationProperty property = entityType.DeclaredNavigationProperties()
.FirstOrDefault(c => !c.ContainsTarget &&
(collectionNav ? c.TargetMultiplicity() == EdmMultiplicity.Many : c.TargetMultiplicity() != EdmMultiplicity.Many));
Assert.NotNull(property);
ODataPath path;
if (collectionNav && expected.Contains(OperationType.Delete))
{
// DELETE ~/entityset/{key}/collection-valued-Nav/{key}/$ref
path = new ODataPath(new ODataNavigationSourceSegment(entitySet),
new ODataKeySegment(entityType),
new ODataNavigationPropertySegment(property),
new ODataKeySegment(property.ToEntityType()),
ODataRefSegment.Instance);
}
else
{
path = new ODataPath(new ODataNavigationSourceSegment(entitySet),
new ODataKeySegment(entityType),
new ODataNavigationPropertySegment(property),
ODataRefSegment.Instance);
}
// Act
var pathItem = _pathItemHandler.CreatePathItem(context, path);
// Assert
Assert.NotNull(pathItem);
Assert.NotNull(pathItem.Operations);
Assert.NotEmpty(pathItem.Operations);
Assert.Equal(expected, pathItem.Operations.Select(o => o.Key));
}
public static IEdmModel GetEdmModel(string annotation)
{
const string template = @"<edmx:Edmx Version=""4.0"" xmlns:edmx=""http://docs.oasis-open.org/odata/ns/edmx"">
<edmx:DataServices>
<Schema Namespace=""NS"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
<EntityType Name=""Customer"">
<Key>
<PropertyRef Name=""ID"" />
</Key>
<Property Name=""ID"" Type=""Edm.Int32"" Nullable=""false"" />
<NavigationProperty Name=""ContainedOrders"" Type=""Collection(NS.Order)"" ContainsTarget=""true"" />
<NavigationProperty Name=""Orders"" Type=""Collection(NS.Order)"" />
<NavigationProperty Name=""ContainedMyOrder"" Type=""NS.Order"" Nullable=""false"" ContainsTarget=""true"" />
<NavigationProperty Name=""MyOrder"" Type=""NS.Order"" Nullable=""false"" />
</EntityType>
<EntityType Name=""Order"">
<Key>
<PropertyRef Name=""ID"" />
</Key>
<Property Name=""ID"" Type=""Edm.Int32"" Nullable=""false"" />
<NavigationProperty Name=""ContainedOrderLines"" Type=""Collection(NS.OrderLine)"" ContainsTarget=""true"" />
<NavigationProperty Name=""OrderLines"" Type=""Collection(NS.OrderLine)"" />
<NavigationProperty Name=""ContainedMyOrderLine"" Type=""NS.OrderLine"" Nullable=""false"" ContainsTarget=""true"" />
<NavigationProperty Name=""MyOrderLine"" Type=""NS.OrderLine"" Nullable=""false"" />
</EntityType>
<EntityType Name=""OrderLine"">
<Key>
<PropertyRef Name=""ID"" />
</Key>
<Property Name=""ID"" Type=""Edm.Int32"" Nullable=""false"" />
</EntityType>
<EntityContainer Name =""Default"">
<EntitySet Name=""Customers"" EntityType=""NS.Customer"" />
<EntitySet Name=""Orders"" EntityType=""NS.Order"" />
</EntityContainer>
<Annotations Target=""NS.Default/Customers"">
{0}
</Annotations>
</Schema>
</edmx:DataServices>
</edmx:Edmx>";
string modelText = string.Format(template, annotation);
IEdmModel model;
IEnumerable<EdmError> errors;
bool result = CsdlReader.TryParse(XElement.Parse(modelText).CreateReader(), out model, out errors);
Assert.True(result);
return model;
}
}
}