Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port Singleton Tests #3163

Merged
merged 11 commits into from
Feb 6, 2025
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//---------------------------------------------------------------------
// <copyright file="ODataAnnotatableExtensions.cs" company="Microsoft">
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
// </copyright>
//---------------------------------------------------------------------

using System.Collections.Concurrent;
using System.Diagnostics;

namespace Microsoft.OData.Client.E2E.TestCommon.Common;

public static class ODataAnnotatableExtensions
{
public static void SetAnnotation<T>(this ODataAnnotatable annotatable, T annotation)
where T : class
{
Debug.Assert(annotatable != null, "annotatable != null");
Debug.Assert(annotation != null, "annotation != null");

InternalDictionary<T>.SetAnnotation(annotatable, annotation);
}

public static T GetAnnotation<T>(this ODataAnnotatable annotatable)
where T : class
{
Debug.Assert(annotatable != null, "annotatable != null");

return InternalDictionary<T>.GetAnnotation(annotatable);
}

private static class InternalDictionary<T> where T : class
{
private static readonly ConcurrentDictionary<ODataAnnotatable, T> Dictionary =
new ConcurrentDictionary<ODataAnnotatable, T>();

public static void SetAnnotation(ODataAnnotatable annotatable, T annotation)
{
Dictionary[annotatable] = annotation;
}

public static T GetAnnotation(ODataAnnotatable annotatable)
{
if (Dictionary.TryGetValue(annotatable, out T? annotation))
{
return annotation;
}

return default(T);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
//---------------------------------------------------------------------
// <copyright file="ODataMessageReaderTestsHelper.cs" company="Microsoft">
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
// </copyright>
//---------------------------------------------------------------------

using Microsoft.OData.Client.E2E.TestCommon.Common;
using Microsoft.OData.Edm;
using Xunit;

namespace Microsoft.OData.Client.E2E.TestCommon.Helpers;

public class ODataMessageReaderTestsHelper
{
private readonly Uri BaseUri;
private readonly IEdmModel Model;
private readonly HttpClient Client;
private const string IncludeAnnotation = "odata.include-annotations";

public ODataMessageReaderTestsHelper(Uri baseUri, IEdmModel model, HttpClient client)
{
this.BaseUri = baseUri;
this.Model = model;
this.Client = client;
}

/// <summary>
/// Queries resource entries asynchronously based on the provided query text and MIME type.
/// </summary>
/// <param name="queryText">The query text to append to the base URI.</param>
/// <param name="mimeType">The MIME type to set in the request header.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains a list of <see cref="ODataResource"/>.</returns>
public async Task<List<ODataResource>> QueryResourceEntriesAsync(string queryText, string mimeType)

{
ODataMessageReaderSettings readerSettings = new() { BaseUri = BaseUri };
var requestUrl = new Uri(BaseUri.AbsoluteUri + queryText, UriKind.Absolute);

var requestMessage = new TestHttpClientRequestMessage(requestUrl, Client);
requestMessage.SetHeader("Accept", mimeType);
requestMessage.SetHeader("Prefer", string.Format("{0}={1}", IncludeAnnotation, "*"));

var responseMessage = await requestMessage.GetResponseAsync();

Assert.Equal(200, responseMessage.StatusCode);

var entries = new List<ODataResource>();
if (!mimeType.Contains(MimeTypes.ODataParameterNoMetadata))
{
using (var messageReader = new ODataMessageReader(responseMessage, readerSettings, Model))
{
var reader = await messageReader.CreateODataResourceReaderAsync();
while (await reader.ReadAsync())
{
if (reader.State == ODataReaderState.ResourceEnd && reader.Item is ODataResource odataResource)
{
entries.Add(odataResource);
}
}
Assert.Equal(ODataReaderState.Completed, reader.State);
}
}

return entries;
}

/// <summary>
/// Queries resource sets asynchronously based on the provided query text and MIME type.
/// </summary>
/// <param name="queryText">The query text to append to the base URI.</param>
/// <param name="mimeType">The MIME type to set in the request header.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains a list of <see cref="ODataResource"/>.</returns>
public async Task<List<ODataResource>> QueryResourceSetsAsync(string queryText, string mimeType)

{
ODataMessageReaderSettings readerSettings = new() { BaseUri = BaseUri };
var requestUrl = new Uri(BaseUri.AbsoluteUri + queryText, UriKind.Absolute);

var requestMessage = new TestHttpClientRequestMessage(requestUrl, Client);
requestMessage.SetHeader("Accept", mimeType);

var responseMessage = await requestMessage.GetResponseAsync();

Assert.Equal(200, responseMessage.StatusCode);

var entries = new List<ODataResource>();
if (!mimeType.Contains(MimeTypes.ODataParameterNoMetadata))
{
using (var messageReader = new ODataMessageReader(responseMessage, readerSettings, Model))
{
var reader = await messageReader.CreateODataResourceSetReaderAsync();
while (await reader.ReadAsync())
{
if (reader.State == ODataReaderState.ResourceEnd)
{
if (reader.Item is ODataResource odataResource)
{
entries.Add(odataResource);
}
}
}
Assert.Equal(ODataReaderState.Completed, reader.State);
}

}

return entries;
}

public async Task<(List<ODataResource>, List<ODataResourceSet>)> QueryResourceAndResourceSetsAsync(string queryText, string mimeType)

{
ODataMessageReaderSettings readerSettings = new() { BaseUri = BaseUri };
var requestUrl = new Uri(BaseUri.AbsoluteUri + queryText, UriKind.Absolute);

var requestMessage = new TestHttpClientRequestMessage(requestUrl, Client);
requestMessage.SetHeader("Accept", mimeType);

var responseMessage = await requestMessage.GetResponseAsync();

Assert.Equal(200, responseMessage.StatusCode);

var resourceEntries = new List<ODataResource>();
var resourceSetEntries = new List<ODataResourceSet>();
if (!mimeType.Contains(MimeTypes.ODataParameterNoMetadata))
{
using (var messageReader = new ODataMessageReader(responseMessage, readerSettings, Model))
{
var reader = await messageReader.CreateODataResourceSetReaderAsync();
while (await reader.ReadAsync())
{
if (reader.State == ODataReaderState.ResourceEnd && reader.Item is ODataResource odataResource)
{
resourceEntries.Add(odataResource);
}
else if (reader.State == ODataReaderState.ResourceSetEnd && reader.Item is ODataResourceSet odataResourceSet)
{
resourceSetEntries.Add(odataResourceSet);
}
}
Assert.Equal(ODataReaderState.Completed, reader.State);
}

}

return (resourceEntries, resourceSetEntries);
}

/// <summary>
/// Queries an OData resource set asynchronously based on the provided query text and MIME type.
/// </summary>
/// <param name="queryText">The query text to append to the base URI.</param>
/// <param name="mimeType">The MIME type to set in the request header.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains an <see cref="ODataResourceSet"/> if found; otherwise, null.</returns>
public async Task<ODataResourceSet?> QueryODataResourceSetAsync(string queryText, string mimeType)
{
ODataMessageReaderSettings readerSettings = new() { BaseUri = BaseUri };
var requestUrl = new Uri(BaseUri.AbsoluteUri + queryText, UriKind.Absolute);

var requestMessage = new TestHttpClientRequestMessage(requestUrl, Client);
requestMessage.SetHeader("Accept", mimeType);

var responseMessage = await requestMessage.GetResponseAsync();

Assert.Equal(200, responseMessage.StatusCode);

if (!mimeType.Contains(MimeTypes.ODataParameterNoMetadata))
{
using (var messageReader = new ODataMessageReader(responseMessage, readerSettings, Model))
{
var reader = await messageReader.CreateODataResourceReaderAsync();
while (await reader.ReadAsync())
{
if (reader.State == ODataReaderState.ResourceSetEnd && reader.Item is ODataResourceSet oDataResourceSet)
{
return oDataResourceSet;
}
}
}
}

return null;
}

/// <summary>
/// Queries a property asynchronously based on the provided request URI and MIME type.
/// </summary>
/// <param name="requestUri">The request URI to append to the base URI.</param>
/// <param name="mimeType">The MIME type to set in the request header.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains an <see cref="ODataProperty"/> if found; otherwise, null.</returns>
public async Task<ODataProperty?> QueryPropertyAsync(string requestUri, string mimeType)
{
var readerSettings = new ODataMessageReaderSettings() { BaseUri = BaseUri };

var uri = new Uri(BaseUri.AbsoluteUri + requestUri, UriKind.Absolute);
var requestMessage = new TestHttpClientRequestMessage(uri, Client);

requestMessage.SetHeader("Accept", mimeType);

var responseMessage = await requestMessage.GetResponseAsync();

Assert.Equal(200, responseMessage.StatusCode);

ODataProperty? property = null;

if (!mimeType.Contains(MimeTypes.ODataParameterNoMetadata))
{
using (var messageReader = new ODataMessageReader(responseMessage, readerSettings, Model))
{
property = messageReader.ReadProperty();
}
}

return property;
}

public async Task<object?> QueryPropertyValueInStringAsync(string requestUri)
{
var readerSettings = new ODataMessageReaderSettings() { BaseUri = BaseUri };

var uri = new Uri(BaseUri.AbsoluteUri + requestUri, UriKind.Absolute);
var requestMessage = new TestHttpClientRequestMessage(uri, Client);

requestMessage.SetHeader("Accept", "*/*");

var responseMessage = await requestMessage.GetResponseAsync();

Assert.Equal(200, responseMessage.StatusCode);

using (var messageReader = new ODataMessageReader(responseMessage, readerSettings, Model))
{
return messageReader.ReadValue(EdmCoreModel.Instance.GetString(false));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ public static class ODataValueAssertEqualHelper

public static void AssertODataValueEqual(ODataValue expected, ODataValue actual)
{
ODataPrimitiveValue expectedPrimitiveValue = expected as ODataPrimitiveValue;
ODataPrimitiveValue actualPrimitiveValue = actual as ODataPrimitiveValue;
var expectedPrimitiveValue = expected as ODataPrimitiveValue;
var actualPrimitiveValue = actual as ODataPrimitiveValue;
if (expectedPrimitiveValue != null && actualPrimitiveValue != null)
{
AssertODataPrimitiveValueEqual(expectedPrimitiveValue, actualPrimitiveValue);
}
else
{
ODataEnumValue expectedEnumValue = expected as ODataEnumValue;
ODataEnumValue actualEnumValue = actual as ODataEnumValue;
var expectedEnumValue = expected as ODataEnumValue;
var actualEnumValue = actual as ODataEnumValue;
if (expectedEnumValue != null && actualEnumValue != null)
{
AssertODataEnumValueEqual(expectedEnumValue, actualEnumValue);
Expand All @@ -42,10 +42,12 @@ private static void AssertODataCollectionValueEqual(ODataCollectionValue expecte
Assert.NotNull(expectedCollectionValue);
Assert.NotNull(actualCollectionValue);
Assert.Equal(expectedCollectionValue.TypeName, actualCollectionValue.TypeName);

var expectedItemsArray = expectedCollectionValue.Items.OfType<object>().ToArray();
var actualItemsArray = actualCollectionValue.Items.OfType<object>().ToArray();

Assert.Equal(expectedItemsArray.Length, actualItemsArray.Length);

for (int i = 0; i < expectedItemsArray.Length; i++)
{
var expectedOdataValue = expectedItemsArray[i] as ODataValue;
Expand All @@ -61,7 +63,7 @@ private static void AssertODataCollectionValueEqual(ODataCollectionValue expecte
}
}

public static void AssertODataPropertiesEqual(IEnumerable<ODataProperty> expectedProperties, IEnumerable<ODataProperty> actualProperties)
public static void AssertODataPropertiesEqual(IEnumerable<ODataPropertyInfo> expectedProperties, IEnumerable<ODataPropertyInfo> actualProperties)
{
if (expectedProperties == null && actualProperties == null)
{
Expand All @@ -70,21 +72,43 @@ public static void AssertODataPropertiesEqual(IEnumerable<ODataProperty> expecte

Assert.NotNull(expectedProperties);
Assert.NotNull(actualProperties);

var expectedPropertyArray = expectedProperties.ToArray();
var actualPropertyArray = actualProperties.ToArray();
Assert.Equal(expectedPropertyArray.Length, actualPropertyArray.Length);

for (int i = 0; i < expectedPropertyArray.Length; i++)
{
AssertODataPropertyEqual(expectedPropertyArray[i], actualPropertyArray[i]);
}
}

public static void AssertODataPropertyEqual(ODataProperty expectedOdataProperty, ODataProperty actualOdataProperty)
public static void AssertODataPropertyAndResourceEqual(ODataResource expectedOdataProperty, ODataResource actualOdataProperty)
{
Assert.NotNull(expectedOdataProperty);
Assert.NotNull(actualOdataProperty);
Assert.Equal(expectedOdataProperty.Name, actualOdataProperty.Name);
AssertODataValueEqual(ToODataValue(expectedOdataProperty.Value), ToODataValue(actualOdataProperty.Value));
AssertODataValueAndResourceEqual(expectedOdataProperty, actualOdataProperty);
}

public static void AssertODataValueAndResourceEqual(ODataResource expected, ODataResource actual)
{
Assert.Equal(expected.TypeName, actual.TypeName);
AssertODataPropertiesEqual(expected.Properties, actual.Properties);
}

public static void AssertODataPropertyEqual(ODataPropertyInfo expectedPropertyInfo, ODataPropertyInfo actualPropertyInfo)
{
Assert.NotNull(expectedPropertyInfo);
Assert.NotNull(actualPropertyInfo);
Assert.Equal(expectedPropertyInfo.Name, actualPropertyInfo.Name);

var expectedProperty = expectedPropertyInfo as ODataProperty;
var actualProperty = actualPropertyInfo as ODataProperty;

Assert.NotNull(expectedProperty);
Assert.NotNull(actualProperty);

AssertODataValueEqual(ToODataValue(expectedProperty.Value), ToODataValue(actualProperty.Value));
}

private static ODataValue ToODataValue(object value)
Expand Down Expand Up @@ -119,5 +143,4 @@ private static void AssertODataEnumValueEqual(ODataEnumValue expectedEnumValue,
}

#endregion Util methods to AssertEqual ODataValues

}
Loading