From 0fe7670f17e4232a8aac4e3e9dad2e134001dfcc Mon Sep 17 00:00:00 2001 From: "Eric Sibly [chullybun]" Date: Fri, 29 Mar 2024 09:21:00 -0700 Subject: [PATCH] StringSyntaxAttribute support. (#72) --- CHANGELOG.md | 3 ++ Common.targets | 2 +- src/UnitTestEx/Abstractions/TesterBaseT.cs | 7 ++- src/UnitTestEx/AspNetCore/HttpTester.cs | 25 ++++++++++ src/UnitTestEx/AspNetCore/HttpTesterBase.cs | 25 ++++++++++ src/UnitTestEx/AspNetCore/HttpTesterT.cs | 25 ++++++++++ .../Assertors/ActionResultAssertor.cs | 5 ++ .../HttpResponseMessageAssertorBaseT.cs | 5 ++ src/UnitTestEx/Assertors/ValueAssertor.cs | 5 ++ .../Functions/FunctionTesterBase.cs | 49 +++++++++++++++++++ src/UnitTestEx/Json/JsonElementComparer.cs | 5 ++ src/UnitTestEx/Mocking/MockHttpClient.cs | 5 ++ .../Mocking/MockHttpClientRequest.cs | 5 ++ .../Mocking/MockHttpClientResponse.cs | 5 ++ 14 files changed, 169 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53be3ee..358e2ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ Represents the **NuGet** versions. +## v4.3.1 +- *Fixed*: Added `StringSyntaxAttribute` support to improve intellisense for JSON and URI specification. + ## v4.3.0 - *Enhancement:* A new `MockHttpClient.WithRequestsFromResource` method enables the specification of the Request/Response configuration from a YAML/JSON embedded resource. The [`mock.unittestex.json`](./src/UnitTestEx/Schema/mock.unittestex.json) JSON schema defines content. diff --git a/Common.targets b/Common.targets index 38a1192..8d9db7e 100644 --- a/Common.targets +++ b/Common.targets @@ -1,6 +1,6 @@  - 4.3.0 + 4.3.1 preview Avanade Avanade diff --git a/src/UnitTestEx/Abstractions/TesterBaseT.cs b/src/UnitTestEx/Abstractions/TesterBaseT.cs index dcc33cc..ae2ef41 100644 --- a/src/UnitTestEx/Abstractions/TesterBaseT.cs +++ b/src/UnitTestEx/Abstractions/TesterBaseT.cs @@ -6,6 +6,7 @@ using Microsoft.Extensions.DependencyInjection; using Moq; using System; +using System.Diagnostics.CodeAnalysis; using System.Net.Mime; using System.Reflection; using System.Text; @@ -304,7 +305,11 @@ public ServiceBusReceivedMessage CreateServiceBusMessageFromResource(string reso /// The JSON body. /// Optional modifier than enables the message to be further configured. /// The . +#if NET7_0_OR_GREATER + public ServiceBusReceivedMessage CreateServiceBusMessageFromJson([StringSyntax(StringSyntaxAttribute.Json)] string json, Action? messageModify = null) +#else public ServiceBusReceivedMessage CreateServiceBusMessageFromJson(string json, Action? messageModify = null) +#endif { var message = new AmqpAnnotatedMessage(AmqpMessageBody.FromData(new ReadOnlyMemory[] { Encoding.UTF8.GetBytes(json ?? throw new ArgumentNullException(nameof(json))) })); message.Properties.ContentType = MediaTypeNames.Application.Json; @@ -394,6 +399,6 @@ public ServiceBusReceivedMessage CreateServiceBusMessage(AmqpAnnotatedMessage me /// The . public WorkerServiceBusMessageActionsAssertor CreateWorkerServiceBusMessageActions() => new(Implementor); - #endregion +#endregion } } \ No newline at end of file diff --git a/src/UnitTestEx/AspNetCore/HttpTester.cs b/src/UnitTestEx/AspNetCore/HttpTester.cs index caa1368..807593a 100644 --- a/src/UnitTestEx/AspNetCore/HttpTester.cs +++ b/src/UnitTestEx/AspNetCore/HttpTester.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.TestHost; using System; +using System.Diagnostics.CodeAnalysis; using System.Net.Http; using System.Net.Mime; using System.Threading.Tasks; @@ -24,7 +25,11 @@ public class HttpTester(TesterBase owner, TestServer testServer) : HttpTesterBas /// The string that represents the request . /// The optional modifier. /// An . +#if NET7_0_OR_GREATER + public HttpResponseMessageAssertor Run(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, Action? requestModifier = null) +#else public HttpResponseMessageAssertor Run(HttpMethod httpMethod, string? requestUri, Action? requestModifier = null) +#endif => RunAsync(httpMethod, requestUri, requestModifier).GetAwaiter().GetResult(); /// @@ -36,7 +41,11 @@ public HttpResponseMessageAssertor Run(HttpMethod httpMethod, string? requestUri /// The content type. Defaults to . /// The optional modifier. /// An . +#if NET7_0_OR_GREATER + public HttpResponseMessageAssertor Run(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, string? body, string? contentType = MediaTypeNames.Text.Plain, Action? requestModifier = null) +#else public HttpResponseMessageAssertor Run(HttpMethod httpMethod, string? requestUri, string? body, string? contentType = MediaTypeNames.Text.Plain, Action? requestModifier = null) +#endif => RunAsync(httpMethod, requestUri, body, contentType, requestModifier).GetAwaiter().GetResult(); /// @@ -47,7 +56,11 @@ public HttpResponseMessageAssertor Run(HttpMethod httpMethod, string? requestUri /// The request body value. /// The optional modifier. /// An . +#if NET7_0_OR_GREATER + public HttpResponseMessageAssertor Run(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, T? value, Action? requestModifier = null) +#else public HttpResponseMessageAssertor Run(HttpMethod httpMethod, string? requestUri, T? value, Action? requestModifier = null) +#endif => SendAsync(httpMethod, requestUri, value, requestModifier).GetAwaiter().GetResult(); /// @@ -57,7 +70,11 @@ public HttpResponseMessageAssertor Run(HttpMethod httpMethod, string? request /// The string that represents the request . /// The optional modifier. /// An . +#if NET7_0_OR_GREATER + public Task RunAsync(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, Action? requestModifier = null) +#else public Task RunAsync(HttpMethod httpMethod, string? requestUri, Action? requestModifier = null) +#endif => SendAsync(httpMethod, requestUri, requestModifier); /// @@ -69,7 +86,11 @@ public Task RunAsync(HttpMethod httpMethod, string? /// The content type. Defaults to . /// The optional modifier. /// An . +#if NET7_0_OR_GREATER + public Task RunAsync(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, string? body, string? contentType = MediaTypeNames.Text.Plain, Action? requestModifier = null) +#else public Task RunAsync(HttpMethod httpMethod, string? requestUri, string? body, string? contentType = MediaTypeNames.Text.Plain, Action? requestModifier = null) +#endif => SendAsync(httpMethod, requestUri, body, contentType, requestModifier); /// @@ -80,7 +101,11 @@ public Task RunAsync(HttpMethod httpMethod, string? /// The request body value. /// The optional modifier. /// An . +#if NET7_0_OR_GREATER + public Task RunAsync(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, T? value, Action? requestModifier = null) +#else public Task RunAsync(HttpMethod httpMethod, string? requestUri, T? value, Action? requestModifier = null) +#endif => SendAsync(httpMethod, requestUri, value, requestModifier); } } \ No newline at end of file diff --git a/src/UnitTestEx/AspNetCore/HttpTesterBase.cs b/src/UnitTestEx/AspNetCore/HttpTesterBase.cs index dcbc161..83a001b 100644 --- a/src/UnitTestEx/AspNetCore/HttpTesterBase.cs +++ b/src/UnitTestEx/AspNetCore/HttpTesterBase.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Net.Http; using System.Net.Mime; @@ -83,7 +84,11 @@ public HttpTesterBase(TesterBase owner, TestServer testServer) /// The string that represents the request . /// The optional modifier. /// The . +#if NET7_0_OR_GREATER + protected async Task SendAsync(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, Action? requestModifier) +#else protected async Task SendAsync(HttpMethod httpMethod, string? requestUri, Action? requestModifier) +#endif { using var client = CreateHttpClient(); var res = await new TypedHttpClient(client, JsonSerializer).SendAsync(httpMethod, requestUri, requestModifier).ConfigureAwait(false); @@ -101,7 +106,11 @@ protected async Task SendAsync(HttpMethod httpMetho /// The content type. /// The optional modifier. /// The . +#if NET7_0_OR_GREATER + protected async Task SendAsync(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, string? content, string? contentType, Action? requestModifier) +#else protected async Task SendAsync(HttpMethod httpMethod, string? requestUri, string? content, string? contentType, Action? requestModifier) +#endif { if (content != null && httpMethod == HttpMethod.Get) Owner.LoggerProvider.CreateLogger("ApiTester").LogWarning("A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request (see https://www.rfc-editor.org/rfc/rfc7231)."); @@ -121,7 +130,11 @@ protected async Task SendAsync(HttpMethod httpMetho /// The value to be JSON serialized. /// The optional modifier. /// The . +#if NET7_0_OR_GREATER + protected async Task SendAsync(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, object? value, Action? requestModifier) +#else protected async Task SendAsync(HttpMethod httpMethod, string? requestUri, object? value, Action? requestModifier) +#endif { if (value != null && httpMethod == HttpMethod.Get) Owner.LoggerProvider.CreateLogger("ApiTester").LogWarning("A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request (see https://www.rfc-editor.org/rfc/rfc7231)."); @@ -181,19 +194,31 @@ public class TypedHttpClient(HttpClient client, IJsonSerializer jsonSerializer) /// /// Sends with no content. /// +#if NET7_0_OR_GREATER + public async Task SendAsync(HttpMethod method, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, Action? requestModifier) +#else public async Task SendAsync(HttpMethod method, string? requestUri, Action? requestModifier) +#endif => await SendAsync(CreateRequest(method, requestUri ?? "", null, requestModifier), default).ConfigureAwait(false); /// /// Sends with content. /// +#if NET7_0_OR_GREATER + public async Task SendAsync(HttpMethod method, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, string? content, string? contentType, Action? requestModifier) +#else public async Task SendAsync(HttpMethod method, string? requestUri, string? content, string? contentType, Action? requestModifier) +#endif => await SendAsync(CreateRequest(method, requestUri ?? "", new StringContent(content ?? string.Empty, Encoding.UTF8, contentType ?? MediaTypeNames.Text.Plain), requestModifier), default).ConfigureAwait(false); /// /// Sends with JSON value. /// +#if NET7_0_OR_GREATER + public async Task SendAsync(HttpMethod method, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, object? value, Action? requestModifier) +#else public async Task SendAsync(HttpMethod method, string? requestUri, object? value, Action? requestModifier) +#endif => await SendAsync(CreateRequest(method, requestUri ?? "", new StringContent(_jsonSerializer.Serialize(value), Encoding.UTF8, MediaTypeNames.Application.Json), requestModifier), default).ConfigureAwait(false); /// diff --git a/src/UnitTestEx/AspNetCore/HttpTesterT.cs b/src/UnitTestEx/AspNetCore/HttpTesterT.cs index 74d92a6..2904f02 100644 --- a/src/UnitTestEx/AspNetCore/HttpTesterT.cs +++ b/src/UnitTestEx/AspNetCore/HttpTesterT.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.TestHost; using System; +using System.Diagnostics.CodeAnalysis; using System.Net.Http; using System.Net.Mime; using System.Threading.Tasks; @@ -25,7 +26,11 @@ public class HttpTester(TesterBase owner, TestServer testServer) : HttpT /// The string that represents the request . /// The optional modifier. /// An . +#if NET7_0_OR_GREATER + public HttpResponseMessageAssertor Run(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, Action? requestModifier = null) +#else public HttpResponseMessageAssertor Run(HttpMethod httpMethod, string? requestUri, Action? requestModifier = null) +#endif => RunAsync(httpMethod, requestUri, requestModifier).GetAwaiter().GetResult(); /// @@ -37,7 +42,11 @@ public HttpResponseMessageAssertor Run(HttpMethod httpMethod, string? requestUri /// The content type. Defaults to . /// The optional modifier. /// An . +#if NET7_0_OR_GREATER + public HttpResponseMessageAssertor Run(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, string? body, string? contentType = MediaTypeNames.Text.Plain, Action? requestModifier = null) +#else public HttpResponseMessageAssertor Run(HttpMethod httpMethod, string? requestUri, string? body, string? contentType = MediaTypeNames.Text.Plain, Action? requestModifier = null) +#endif => RunAsync(httpMethod, requestUri, body, contentType, requestModifier).GetAwaiter().GetResult(); /// @@ -48,7 +57,11 @@ public HttpResponseMessageAssertor Run(HttpMethod httpMethod, string? requestUri /// The request body value. /// The optional modifier. /// An . +#if NET7_0_OR_GREATER + public HttpResponseMessageAssertor Run(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, T? value, Action? requestModifier = null) +#else public HttpResponseMessageAssertor Run(HttpMethod httpMethod, string? requestUri, T? value, Action? requestModifier = null) +#endif => SendAsync(httpMethod, requestUri, value, requestModifier).GetAwaiter().GetResult(); /// @@ -58,7 +71,11 @@ public HttpResponseMessageAssertor Run(HttpMethod httpMethod, string? request /// The string that represents the request . /// The optional modifier. /// An . +#if NET7_0_OR_GREATER + public Task RunAsync(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, Action? requestModifier = null) +#else public Task RunAsync(HttpMethod httpMethod, string? requestUri, Action? requestModifier = null) +#endif => SendAsync(httpMethod, requestUri, requestModifier); /// @@ -70,7 +87,11 @@ public Task RunAsync(HttpMethod httpMethod, string? /// The content type. Defaults to . /// The optional modifier. /// An . +#if NET7_0_OR_GREATER + public Task RunAsync(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, string? body, string? contentType = MediaTypeNames.Text.Plain, Action? requestModifier = null) +#else public Task RunAsync(HttpMethod httpMethod, string? requestUri, string? body, string? contentType = MediaTypeNames.Text.Plain, Action? requestModifier = null) +#endif => SendAsync(httpMethod, requestUri, body, contentType, requestModifier); /// @@ -81,7 +102,11 @@ public Task RunAsync(HttpMethod httpMethod, string? /// The request body value. /// The optional modifier. /// An . +#if NET7_0_OR_GREATER + public Task RunAsync(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, T? value, Action? requestModifier = null) +#else public Task RunAsync(HttpMethod httpMethod, string? requestUri, T? value, Action? requestModifier = null) +#endif => SendAsync(httpMethod, requestUri, value, requestModifier); } } \ No newline at end of file diff --git a/src/UnitTestEx/Assertors/ActionResultAssertor.cs b/src/UnitTestEx/Assertors/ActionResultAssertor.cs index e12c2b1..3b78443 100644 --- a/src/UnitTestEx/Assertors/ActionResultAssertor.cs +++ b/src/UnitTestEx/Assertors/ActionResultAssertor.cs @@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Mvc.Infrastructure; using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Net; using System.Net.Mime; using System.Reflection; @@ -367,7 +368,11 @@ public ActionResultAssertor AssertJsonFromResource(string resourceName, params s /// The expected JSON. /// The JSON paths to ignore from the comparison. /// The to support fluent-style method-chaining. +#if NET7_0_OR_GREATER + public ActionResultAssertor AssertJson([StringSyntax(StringSyntaxAttribute.Json)] string json, params string[] pathsToIgnore) +#else public ActionResultAssertor AssertJson(string json, params string[] pathsToIgnore) +#endif { if (string.IsNullOrEmpty(json)) throw new ArgumentNullException(nameof(json)); diff --git a/src/UnitTestEx/Assertors/HttpResponseMessageAssertorBaseT.cs b/src/UnitTestEx/Assertors/HttpResponseMessageAssertorBaseT.cs index 778c29a..8b43c7f 100644 --- a/src/UnitTestEx/Assertors/HttpResponseMessageAssertorBaseT.cs +++ b/src/UnitTestEx/Assertors/HttpResponseMessageAssertorBaseT.cs @@ -3,6 +3,7 @@ using Microsoft.Net.Http.Headers; using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Net; using System.Net.Http; using System.Net.Mime; @@ -218,7 +219,11 @@ public TSelf AssertErrors(params ApiError[] errors) /// The expected JSON. /// The JSON paths to ignore from the comparison. /// The instance to support fluent-style method-chaining. +#if NET7_0_OR_GREATER + public TSelf AssertJson([StringSyntax(StringSyntaxAttribute.Json)] string json, params string[] pathsToIgnore) +#else public TSelf AssertJson(string json, params string[] pathsToIgnore) +#endif { if (string.IsNullOrEmpty(json)) throw new ArgumentNullException(nameof(json)); diff --git a/src/UnitTestEx/Assertors/ValueAssertor.cs b/src/UnitTestEx/Assertors/ValueAssertor.cs index 735f4c4..5ae7bdb 100644 --- a/src/UnitTestEx/Assertors/ValueAssertor.cs +++ b/src/UnitTestEx/Assertors/ValueAssertor.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Mvc; using System; +using System.Diagnostics.CodeAnalysis; using System.Net.Http; using System.Reflection; using UnitTestEx.Abstractions; @@ -49,7 +50,11 @@ public ValueAssertor AssertValue(TValue expectedValue, params string[] p /// The JSON . /// The JSON paths to ignore from the comparison. /// The to support fluent-style method-chaining. +#if NET7_0_OR_GREATER + public ValueAssertor AssertJson([StringSyntax(StringSyntaxAttribute.Json)] string json, params string[] pathsToIgnore) => AssertValue(JsonSerializer.Deserialize(json)!, pathsToIgnore); +#else public ValueAssertor AssertJson(string json, params string[] pathsToIgnore) => AssertValue(JsonSerializer.Deserialize(json)!, pathsToIgnore); +#endif /// /// Asserts that the matches the JSON serialized value from the named embedded resource. diff --git a/src/UnitTestEx/Functions/FunctionTesterBase.cs b/src/UnitTestEx/Functions/FunctionTesterBase.cs index 47b8ff3..bc8a14b 100644 --- a/src/UnitTestEx/Functions/FunctionTesterBase.cs +++ b/src/UnitTestEx/Functions/FunctionTesterBase.cs @@ -10,6 +10,7 @@ using Moq; using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Net.Http; using System.Net.Mime; @@ -234,7 +235,11 @@ private IHost GetHost() /// The . /// The requuest uri. /// The . +#if NET7_0_OR_GREATER + public HttpRequest CreateHttpRequest(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri) +#else public HttpRequest CreateHttpRequest(HttpMethod httpMethod, string? requestUri) +#endif => CreateHttpRequest(httpMethod, requestUri, null, MediaTypeNames.Text.Plain, null); /// @@ -244,7 +249,11 @@ public HttpRequest CreateHttpRequest(HttpMethod httpMethod, string? requestUri) /// The requuest uri. /// The optional body content. /// The . +#if NET7_0_OR_GREATER + public HttpRequest CreateHttpRequest(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, string? body) +#else public HttpRequest CreateHttpRequest(HttpMethod httpMethod, string? requestUri, string? body) +#endif => CreateHttpRequest(httpMethod, requestUri, body, null, null); /// @@ -255,7 +264,11 @@ public HttpRequest CreateHttpRequest(HttpMethod httpMethod, string? requestUri, /// The optional body content. /// The content type. Defaults to . /// The . +#if NET7_0_OR_GREATER + public HttpRequest CreateHttpRequest(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, string? body, string? contentType) +#else public HttpRequest CreateHttpRequest(HttpMethod httpMethod, string? requestUri, string? body, string? contentType) +#endif => CreateHttpRequest(httpMethod, requestUri, body, contentType, null); /// @@ -265,7 +278,11 @@ public HttpRequest CreateHttpRequest(HttpMethod httpMethod, string? requestUri, /// The requuest uri. /// The optional modifier. /// The . +#if NET7_0_OR_GREATER + public HttpRequest CreateHttpRequest(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, Action? requestModifier = null) +#else public HttpRequest CreateHttpRequest(HttpMethod httpMethod, string? requestUri, Action? requestModifier = null) +#endif => CreateHttpRequest(httpMethod, requestUri, null, MediaTypeNames.Text.Plain, requestModifier); /// @@ -276,7 +293,11 @@ public HttpRequest CreateHttpRequest(HttpMethod httpMethod, string? requestUri, /// The optional body content. /// The optional modifier. /// The . +#if NET7_0_OR_GREATER + public HttpRequest CreateHttpRequest(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, string? body, Action? requestModifier = null) +#else public HttpRequest CreateHttpRequest(HttpMethod httpMethod, string? requestUri, string? body, Action? requestModifier = null) +#endif => CreateHttpRequest(httpMethod, requestUri, body, null, requestModifier); /// @@ -288,7 +309,11 @@ public HttpRequest CreateHttpRequest(HttpMethod httpMethod, string? requestUri, /// The content type. Defaults to . /// The optional modifier. /// The . +#if NET7_0_OR_GREATER + public HttpRequest CreateHttpRequest(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri = null, string? body = null, string? contentType = null, Action? requestModifier = null) +#else public HttpRequest CreateHttpRequest(HttpMethod httpMethod, string? requestUri = null, string? body = null, string? contentType = null, Action? requestModifier = null) +#endif { if (httpMethod == HttpMethod.Get && body != null) LoggerProvider.CreateLogger("FunctionTesterBase").LogWarning("A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request (see https://www.rfc-editor.org/rfc/rfc7231)."); @@ -328,7 +353,11 @@ public HttpRequest CreateHttpRequest(HttpMethod httpMethod, string? requestUri = /// The requuest uri. /// The value to JSON serialize. /// The . +#if NET7_0_OR_GREATER + public HttpRequest CreateJsonHttpRequest(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, object? value) +#else public HttpRequest CreateJsonHttpRequest(HttpMethod httpMethod, string? requestUri, object? value) +#endif => CreateJsonHttpRequest(httpMethod, requestUri, value, null); /// @@ -339,7 +368,11 @@ public HttpRequest CreateJsonHttpRequest(HttpMethod httpMethod, string? requestU /// The value to JSON serialize. /// The optional modifier. /// The . +#if NET7_0_OR_GREATER + public HttpRequest CreateJsonHttpRequest(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, object? value, Action? requestModifier = null) +#else public HttpRequest CreateJsonHttpRequest(HttpMethod httpMethod, string? requestUri, object? value, Action? requestModifier = null) +#endif { if (httpMethod == HttpMethod.Get) LoggerProvider.CreateLogger("FunctionTesterBase").LogWarning("A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request (see https://www.rfc-editor.org/rfc/rfc7231)."); @@ -358,7 +391,11 @@ public HttpRequest CreateJsonHttpRequest(HttpMethod httpMethod, string? requestU /// The requuest uri. /// The embedded resource name (matches to the end of the fully qualifed resource name). /// The . +#if NET7_0_OR_GREATER + public HttpRequest CreateJsonHttpRequestFromResource(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, string resourceName) +#else public HttpRequest CreateJsonHttpRequestFromResource(HttpMethod httpMethod, string? requestUri, string resourceName) +#endif => CreateJsonHttpRequestFromResource(httpMethod, requestUri, resourceName, null); /// @@ -370,7 +407,11 @@ public HttpRequest CreateJsonHttpRequestFromResource(HttpMethod httpM /// The embedded resource name (matches to the end of the fully qualifed resource name). /// The optional modifier. /// The . +#if NET7_0_OR_GREATER + public HttpRequest CreateJsonHttpRequestFromResource(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, string resourceName, Action? requestModifier = null) +#else public HttpRequest CreateJsonHttpRequestFromResource(HttpMethod httpMethod, string? requestUri, string resourceName, Action? requestModifier = null) +#endif => CreateJsonHttpRequestFromResource(httpMethod, requestUri, resourceName, typeof(TAssembly).Assembly, requestModifier); /// @@ -381,7 +422,11 @@ public HttpRequest CreateJsonHttpRequestFromResource(HttpMethod httpM /// The embedded resource name (matches to the end of the fully qualifed resource name). /// The that contains the embedded resource; defaults to . /// The . +#if NET7_0_OR_GREATER + public HttpRequest CreateJsonHttpRequestFromResource(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, string resourceName, Assembly assembly) +#else public HttpRequest CreateJsonHttpRequestFromResource(HttpMethod httpMethod, string? requestUri, string resourceName, Assembly assembly) +#endif => CreateJsonHttpRequestFromResource(httpMethod, requestUri, resourceName, assembly, null); /// @@ -393,7 +438,11 @@ public HttpRequest CreateJsonHttpRequestFromResource(HttpMethod httpMethod, stri /// The that contains the embedded resource; defaults to . /// The optional modifier. /// The . +#if NET7_0_OR_GREATER + public HttpRequest CreateJsonHttpRequestFromResource(HttpMethod httpMethod, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, string resourceName, Assembly assembly, Action? requestModifier = null) +#else public HttpRequest CreateJsonHttpRequestFromResource(HttpMethod httpMethod, string? requestUri, string resourceName, Assembly assembly, Action? requestModifier = null) +#endif { if (httpMethod == HttpMethod.Get) LoggerProvider.CreateLogger("FunctionTesterBase").LogWarning("A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request (see https://www.rfc-editor.org/rfc/rfc7231)."); diff --git a/src/UnitTestEx/Json/JsonElementComparer.cs b/src/UnitTestEx/Json/JsonElementComparer.cs index 7cbd0d7..940feb9 100644 --- a/src/UnitTestEx/Json/JsonElementComparer.cs +++ b/src/UnitTestEx/Json/JsonElementComparer.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text.Json; using System.Text.Json.Nodes; @@ -290,7 +291,11 @@ public bool Equals(JsonElement x, JsonElement y) } /// +#if NET7_0_OR_GREATER + public int GetHashCode([StringSyntax(StringSyntaxAttribute.Json)] string json) +#else public int GetHashCode(string json) +#endif { if (json == null) return 0; diff --git a/src/UnitTestEx/Mocking/MockHttpClient.cs b/src/UnitTestEx/Mocking/MockHttpClient.cs index 1b4bfb7..18aa345 100644 --- a/src/UnitTestEx/Mocking/MockHttpClient.cs +++ b/src/UnitTestEx/Mocking/MockHttpClient.cs @@ -6,6 +6,7 @@ using Moq; using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Net; using System.Net.Http; @@ -237,7 +238,11 @@ public void WithoutMocking(params Type[] excludeTypes) /// The . Defaults to . /// The string that represents the request . /// The . +#if NET7_0_OR_GREATER + public MockHttpClientRequest Request(HttpMethod? method = null, [StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri = null) +#else public MockHttpClientRequest Request(HttpMethod? method = null, string? requestUri = null) +#endif { if (_noMocking) throw new InvalidOperationException($"{nameof(Request)} is not supported where {nameof(WithoutMocking)} has been specified."); diff --git a/src/UnitTestEx/Mocking/MockHttpClientRequest.cs b/src/UnitTestEx/Mocking/MockHttpClientRequest.cs index d060286..3f0567c 100644 --- a/src/UnitTestEx/Mocking/MockHttpClientRequest.cs +++ b/src/UnitTestEx/Mocking/MockHttpClientRequest.cs @@ -3,6 +3,7 @@ using Moq; using Moq.Protected; using System; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Net; using System.Net.Http; @@ -289,7 +290,11 @@ public MockHttpClientRequestBody WithJsonBody(T value, params string[] pathsT /// The content. /// The JSON paths to ignore from the comparison. /// The resulting to accordingly. +#if NET7_0_OR_GREATER + public MockHttpClientRequestBody WithJsonBody([StringSyntax(StringSyntaxAttribute.Json)] string json, params string[] pathsToIgnore) +#else public MockHttpClientRequestBody WithJsonBody(string json, params string[] pathsToIgnore) +#endif { try { diff --git a/src/UnitTestEx/Mocking/MockHttpClientResponse.cs b/src/UnitTestEx/Mocking/MockHttpClientResponse.cs index c7150e9..bd55212 100644 --- a/src/UnitTestEx/Mocking/MockHttpClientResponse.cs +++ b/src/UnitTestEx/Mocking/MockHttpClientResponse.cs @@ -1,6 +1,7 @@ // Copyright (c) Avanade. Licensed under the MIT License. See https://github.com/Avanade/UnitTestEx using System; +using System.Diagnostics.CodeAnalysis; using System.Net; using System.Net.Http; using System.Net.Http.Headers; @@ -156,7 +157,11 @@ public void With(HttpContent? content = null, HttpStatusCode? statusCode = null, /// The content. /// The optional (defaults to ). /// The optional action to enable additional configuration of the . +#if NET7_0_OR_GREATER + public void WithJson([StringSyntax(StringSyntaxAttribute.Json)] string json, HttpStatusCode? statusCode = null, Action? response = null) +#else public void WithJson(string json, HttpStatusCode? statusCode = null, Action? response = null) +#endif { var content = new StringContent(json ?? throw new ArgumentNullException(nameof(json))); content.Headers.ContentType = MediaTypeHeaderValue.Parse(MediaTypeNames.Application.Json);