Skip to content

Commit

Permalink
Port collection tests (#3028)
Browse files Browse the repository at this point in the history
ElizabethOkerio authored Aug 6, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent ea3e253 commit 27f3c87
Showing 2 changed files with 261 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//-----------------------------------------------------------------------------
// <copyright file="CollectionNullableFacetTestController.cs" company=".NET Foundation">
// Copyright (c) .NET Foundation and Contributors. All rights reserved.
// See License.txt in the project root for license information.
// </copyright>
//------------------------------------------------------------------------------

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.OData.Query;
using Microsoft.AspNetCore.OData.Routing.Controllers;
using Microsoft.OData.Client.E2E.Tests.Common.Server.Default;

namespace Microsoft.OData.Client.E2E.Tests.CollectionTests.Server
{
public class CollectionNullableFacetTestController : ODataController
{
[EnableQuery]
[HttpGet("odata/Customers")]
public IActionResult GetCustomers()
{
var rowIndex = DefaultDataSource.Customers;
return Ok(rowIndex);
}

[EnableQuery]
[HttpGet("odata/Customers({key})")]
public IActionResult GetCustomer([FromRoute] int key)
{
var customer = DefaultDataSource.Customers.SingleOrDefault(a => a.PersonID == key);

if (customer == null)
{
return NotFound();
}

return Ok(customer);
}

[EnableQuery]
[HttpPut("odata/Customers({key})")]
public IActionResult UpdateCustomers([FromRoute] int key, [FromBody] Customer customer)
{
var updateCustomer = DefaultDataSource.Customers.FirstOrDefault(a => a.PersonID == key);

if (updateCustomer == null)
{
return NotFound();
}

updateCustomer.Numbers = customer.Numbers;
updateCustomer.Emails = customer.Emails;

return NoContent();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
//-----------------------------------------------------------------------------
// <copyright file="CollectionNullableFacetTest.cs" company=".NET Foundation">
// Copyright (c) .NET Foundation and Contributors. All rights reserved.
// See License.txt in the project root for license information.
// </copyright>
//------------------------------------------------------------------------------

using Microsoft.AspNetCore.OData;
using Microsoft.AspNetCore.OData.Routing.Controllers;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OData.Client.E2E.TestCommon;
using Microsoft.OData.Client.E2E.TestCommon.Common;
using Microsoft.OData.Client.E2E.Tests.CollectionTests.Server;
using Microsoft.OData.Client.E2E.Tests.Common.Server.Default;
using Microsoft.OData.Edm;
using Xunit;

namespace Microsoft.OData.Client.E2E.Tests.CollectionTests.Tests
{
public class CollectionNullableFacetTest : EndToEndTestBase<CollectionNullableFacetTest.TestsStartup>
{
private readonly Uri _baseUri;
private IEdmModel _model = null;
private static string NameSpacePrefix = "Microsoft.OData.Client.E2E.Tests.Common.Server.Default.";
protected readonly string[] mimeTypes =
[
MimeTypes.ApplicationJson + MimeTypes.ODataParameterFullMetadata,
MimeTypes.ApplicationJson + MimeTypes.ODataParameterMinimalMetadata,
MimeTypes.ApplicationJson + MimeTypes.ODataParameterNoMetadata,
];

public class TestsStartup : TestStartupBase
{
public override void ConfigureServices(IServiceCollection services)
{
services.ConfigureControllers(typeof(CollectionNullableFacetTestController), typeof(MetadataController));

services.AddControllers().AddOData(opt =>
{
opt.EnableQueryFeatures();
opt.AddRouteComponents("odata", DefaultEdmModel.GetEdmModel());
});
}
}

public CollectionNullableFacetTest(TestWebApplicationFactory<TestsStartup> fixture)
: base(fixture)
{
_baseUri = new Uri(Client.BaseAddress, "odata/");
_model = DefaultEdmModel.GetEdmModel();
}

/// <summary>
/// Verify collection structrual property with nullable facet specified false cannot have null element
/// And collection can be empty
/// </summary>
[Fact]
public void CollectionNullableFalseInStructrualProperty()
{
var personToAdd = new ODataResource
{
TypeName = NameSpacePrefix + "Customer",
Properties = new[]
{
new ODataProperty {Name = "Numbers", Value = new ODataCollectionValue() {TypeName = "Collection(Edm.String)", Items = new[] {"222-222-221", null}}},
new ODataProperty {Name = "Emails", Value = new ODataCollectionValue() {TypeName = "Collection(Edm.String)", Items = new string[] {}}}
}
};
this.UpdateEntityWithCollectionContainsNull(personToAdd, "Numbers");
}

/// <summary>
/// Verify collection in structrual property with nullable facet specified false can have null element
/// And collection can be empty
/// </summary>
[Fact]
public void CollectionNullableTrueInStructrualProperty()
{
var personToAdd = new ODataResource
{
TypeName = NameSpacePrefix + "Customer",
Properties = new[]
{
new ODataProperty {Name = "Numbers", Value = new ODataCollectionValue() {TypeName = "Collection(Edm.String)", Items = new string[] {}}},
new ODataProperty {Name = "Emails", Value = new ODataCollectionValue() {TypeName = "Collection(Edm.String)", Items = new[] {"a@a.b", "b@b.b", null}}}
}
};
this.UpdateEntityWithCollectionContainsNull(personToAdd, "Emails");
}

#region private methods
/// <summary>
/// Update entity with null element in collection
/// testProperty is a structual property and its collection value contains null element
/// </summary>
private void UpdateEntityWithCollectionContainsNull(ODataResource personToAdd, String testProperty)
{
var settings = new ODataMessageWriterSettings();
settings.BaseUri = _baseUri;
var customerType = _model.FindDeclaredType(NameSpacePrefix + "Customer") as IEdmEntityType;
var customerSet = _model.EntityContainer.FindEntitySet("Customers");

// get the IsNullable value of testProperty
bool isNullable = true;
foreach (IEdmStructuralProperty property in customerType.BaseEntityType().DeclaredStructuralProperties())
{
if (property.Name.Equals(testProperty))
{
IEdmCollectionTypeReference typeRef = property.Type as IEdmCollectionTypeReference;
Assert.NotNull(typeRef);
isNullable = typeRef.IsNullable;
}
}

var args = new DataServiceClientRequestMessageArgs(
"PUT",
new Uri(_baseUri.AbsoluteUri + "Customers(1)", UriKind.Absolute),
usePostTunneling: false,
new Dictionary<string, string>(),
HttpClientFactory);

foreach (var mimeType in mimeTypes)
{
var requestMessage = new HttpClientRequestMessage(args);
requestMessage.SetHeader("Content-Type", mimeType);
requestMessage.SetHeader("Accept", mimeType);

try
{
//write request message
using (var messageWriter = new ODataMessageWriter(requestMessage, settings, _model))
{
var odataWriter = messageWriter.CreateODataResourceWriter(customerSet, customerType);
odataWriter.WriteStart(personToAdd);
odataWriter.WriteEnd();
}

// send the http request
var responseMessage = requestMessage.GetResponse();

// verify the update
Assert.Equal(204, responseMessage.StatusCode);
ODataResource updatedProduct = this.QueryEntityItem("Customers(1)") as ODataResource;
ODataCollectionValue testCollection = updatedProduct.Properties.OfType<ODataProperty>().Single(p => p.Name == testProperty).Value as ODataCollectionValue;
ODataCollectionValue expectValue = personToAdd.Properties.OfType<ODataProperty>().Single(p => p.Name == testProperty).Value as ODataCollectionValue;
var actIter = testCollection.Items.GetEnumerator();
var expIter = expectValue.Items.GetEnumerator();
while ((actIter.MoveNext()) && (expIter.MoveNext()))
{
Assert.Equal(actIter.Current, expIter.Current);
}
}
catch (Exception exception)
{
if (!isNullable)
{
Assert.Equal(exception.Message, "A null value was detected in the items of a collection property value; non-nullable instances of collection types do not support null values as items.");
}
else
{
throw;
}
}
}
}

private ODataItem QueryEntityItem(string uri, int expectedStatusCode = 200)
{
ODataMessageReaderSettings readerSettings = new ODataMessageReaderSettings() { BaseUri = _baseUri };

var args = new DataServiceClientRequestMessageArgs(
"GET",
new Uri(_baseUri.AbsoluteUri + uri, UriKind.Absolute),
usePostTunneling: false,
new Dictionary<string, string>(),
HttpClientFactory);

var queryRequestMessage = new HttpClientRequestMessage(args);
queryRequestMessage.SetHeader("Accept", MimeTypes.ApplicationJsonLight);
var queryResponseMessage = queryRequestMessage.GetResponse();
Assert.Equal(expectedStatusCode, queryResponseMessage.StatusCode);

ODataItem item = null;
if (expectedStatusCode == 200)
{
using (var messageReader = new ODataMessageReader(queryResponseMessage, readerSettings, _model))
{
var reader = messageReader.CreateODataResourceReader();
while (reader.Read())
{
if (reader.State == ODataReaderState.ResourceEnd)
{
item = reader.Item;
}
}

Assert.Equal(ODataReaderState.Completed, reader.State);
}
}

return item;
}
#endregion
}
}

0 comments on commit 27f3c87

Please sign in to comment.