diff --git a/props/PayPal.props b/props/PayPal.props index 91afe91c..7c0a1017 100644 --- a/props/PayPal.props +++ b/props/PayPal.props @@ -1,5 +1,12 @@ - - true - + + + true + + + + $(NoWarn);MA0002;MA0012;MA0051;MA0061 + $(WarningsAsErrors);MA0007 + + diff --git a/samples/PayPal.Sdk.Checkout.Samples/AuthorizeIntentExamples/AuthorizeOrderSample.cs b/samples/PayPal.Sdk.Checkout.Samples/AuthorizeIntentExamples/AuthorizeOrderSample.cs index 233232e3..5ff64968 100644 --- a/samples/PayPal.Sdk.Checkout.Samples/AuthorizeIntentExamples/AuthorizeOrderSample.cs +++ b/samples/PayPal.Sdk.Checkout.Samples/AuthorizeIntentExamples/AuthorizeOrderSample.cs @@ -24,7 +24,7 @@ public static class AuthorizeOrderSample request.SetPreferReturn(EPreferReturn.Representation); request.SetRequestBody(new AuthorizeRequest()); } - ); + ).ConfigureAwait(false); if (debug && response != null) { diff --git a/samples/PayPal.Sdk.Checkout.Samples/AuthorizeIntentExamples/CaptureOrderSample.cs b/samples/PayPal.Sdk.Checkout.Samples/AuthorizeIntentExamples/CaptureOrderSample.cs index 57494d98..dcef55f6 100644 --- a/samples/PayPal.Sdk.Checkout.Samples/AuthorizeIntentExamples/CaptureOrderSample.cs +++ b/samples/PayPal.Sdk.Checkout.Samples/AuthorizeIntentExamples/CaptureOrderSample.cs @@ -23,7 +23,7 @@ public static class CaptureOrderSample request.SetPreferReturn(EPreferReturn.Representation); request.SetRequestBody(new CaptureRequest()); } - ); + ).ConfigureAwait(false); if (debug && response != null) { diff --git a/samples/PayPal.Sdk.Checkout.Samples/AuthorizeIntentExamples/RunAllAuthorizeIntentFlow.cs b/samples/PayPal.Sdk.Checkout.Samples/AuthorizeIntentExamples/RunAllAuthorizeIntentFlow.cs index 41bd636c..ca3d0ac6 100644 --- a/samples/PayPal.Sdk.Checkout.Samples/AuthorizeIntentExamples/RunAllAuthorizeIntentFlow.cs +++ b/samples/PayPal.Sdk.Checkout.Samples/AuthorizeIntentExamples/RunAllAuthorizeIntentFlow.cs @@ -12,10 +12,10 @@ private static async Task Main() { var payPalHttpClient = SampleHttpClientFactory.CreateHttpClient(); - var accessToken = await payPalHttpClient.AuthenticateAsync(); + var accessToken = await payPalHttpClient.AuthenticateAsync().ConfigureAwait(false); Console.WriteLine("Running Authorize Intent Flow.."); - var createOrderResponse = await payPalHttpClient.CreateOrder(accessToken!); + var createOrderResponse = await payPalHttpClient.CreateOrder(accessToken!).ConfigureAwait(false); Console.WriteLine("Status: {0}", createOrderResponse!.Status); Console.WriteLine("Order Id: {0}", createOrderResponse.Id); @@ -33,7 +33,7 @@ private static async Task Main() Console.Read(); Console.WriteLine("Authorizing the Order...."); - var authorizeOrderResponse = await payPalHttpClient.AuthorizeOrder(accessToken!, createOrderResponse.Id); + var authorizeOrderResponse = await payPalHttpClient.AuthorizeOrder(accessToken!, createOrderResponse.Id).ConfigureAwait(false); Console.WriteLine("Status: {0}", authorizeOrderResponse!.Status); var authorizationId = authorizeOrderResponse.PurchaseUnits.Single().Payments.Authorizations.Single().Id; @@ -52,7 +52,7 @@ private static async Task Main() Console.WriteLine("AuthorizedAmount: {0}", authorizedAmount); Console.WriteLine("Capturing the payment..."); - var captureOrderResponse = await payPalHttpClient.CaptureOrder(accessToken!, authorizationId); + var captureOrderResponse = await payPalHttpClient.CaptureOrder(accessToken!, authorizationId).ConfigureAwait(false); Console.WriteLine("Status: {0}", captureOrderResponse!.Status); Console.WriteLine("Capture Id: {0}", captureOrderResponse.Id); @@ -63,7 +63,7 @@ private static async Task Main() } Console.WriteLine("Refunding the Order...."); - var refundOrderResponse = await payPalHttpClient.CapturesRefund(accessToken!, captureOrderResponse.Id); + var refundOrderResponse = await payPalHttpClient.CapturesRefund(accessToken!, captureOrderResponse.Id).ConfigureAwait(false); Console.WriteLine("Status: {0}", refundOrderResponse!.Status); Console.WriteLine("Refund Id: {0}", refundOrderResponse.Id); diff --git a/samples/PayPal.Sdk.Checkout.Samples/CaptureIntentExamples/CaptureOrderSample.cs b/samples/PayPal.Sdk.Checkout.Samples/CaptureIntentExamples/CaptureOrderSample.cs index 6a66d579..57a24a14 100644 --- a/samples/PayPal.Sdk.Checkout.Samples/CaptureIntentExamples/CaptureOrderSample.cs +++ b/samples/PayPal.Sdk.Checkout.Samples/CaptureIntentExamples/CaptureOrderSample.cs @@ -17,7 +17,7 @@ passed an argument to this method. public static async Task CaptureOrder(this IPayPalHttpClient payPalHttpClient, AccessToken accessToken, string orderId, bool debug = false) { - var response = await payPalHttpClient.CaptureOrderAsync(accessToken, orderId); + var response = await payPalHttpClient.CaptureOrderAsync(accessToken, orderId).ConfigureAwait(false); if (debug && response != null) { diff --git a/samples/PayPal.Sdk.Checkout.Samples/CaptureIntentExamples/RunAllCaptureIntentFlow.cs b/samples/PayPal.Sdk.Checkout.Samples/CaptureIntentExamples/RunAllCaptureIntentFlow.cs index 9136d47f..7196b300 100644 --- a/samples/PayPal.Sdk.Checkout.Samples/CaptureIntentExamples/RunAllCaptureIntentFlow.cs +++ b/samples/PayPal.Sdk.Checkout.Samples/CaptureIntentExamples/RunAllCaptureIntentFlow.cs @@ -6,7 +6,7 @@ namespace PayPal.Sdk.Checkout.Samples.CaptureIntentExamples; -public static class RunAll +public static class RunAllCaptureIntentFlow { //Rename to Main1 => Main [SuppressMessage("ReSharper", "UnusedMember.Local")] @@ -14,10 +14,10 @@ private static async Task Main1() { var payPalHttpClient = SampleHttpClientFactory.CreateHttpClient(); - var accessToken = await payPalHttpClient.AuthenticateAsync(); + var accessToken = await payPalHttpClient.AuthenticateAsync().ConfigureAwait(false); Console.WriteLine("Running Capture Intent Flow.."); - var createOrderResponse = await payPalHttpClient.CreateOrder(accessToken!, true); + var createOrderResponse = await payPalHttpClient.CreateOrder(accessToken!, true).ConfigureAwait(false); Console.WriteLine("Status: {0}", createOrderResponse!.Status); Console.WriteLine("Order Id: {0}", createOrderResponse.Id); @@ -35,7 +35,7 @@ private static async Task Main1() Console.Read(); Console.WriteLine("Capturing the payment..."); - var captureOrderResponse = await payPalHttpClient.CaptureOrder(accessToken!, createOrderResponse.Id, true); + var captureOrderResponse = await payPalHttpClient.CaptureOrder(accessToken!, createOrderResponse.Id, true).ConfigureAwait(false); var captureId = ""; Console.WriteLine("Status: {0}", captureOrderResponse!.Status); @@ -61,7 +61,7 @@ private static async Task Main1() Console.WriteLine("CaptureAmount: {0}", captureAmount); Console.WriteLine("Refunding the Order...."); - var refundOrderResponse = await payPalHttpClient.CapturesRefund(accessToken!, captureId, true); + var refundOrderResponse = await payPalHttpClient.CapturesRefund(accessToken!, captureId, true).ConfigureAwait(false); Console.WriteLine("Status: {0}", refundOrderResponse!.Status); Console.WriteLine("Refund Id: {0}", refundOrderResponse.Id); Console.WriteLine("Links:"); diff --git a/samples/PayPal.Sdk.Checkout.Samples/CapturesRefundSample.cs b/samples/PayPal.Sdk.Checkout.Samples/CapturesRefundSample.cs index 7c0dd8ea..24c2e294 100644 --- a/samples/PayPal.Sdk.Checkout.Samples/CapturesRefundSample.cs +++ b/samples/PayPal.Sdk.Checkout.Samples/CapturesRefundSample.cs @@ -13,8 +13,10 @@ public static class CapturesRefundSample /// /// Method for refund the capture. Valid capture Id should be passed an argument to this method. /// - public static async Task CapturesRefund(this IPayPalHttpClient httpClient, AccessToken accessToken, - string captureId, bool debug = false) + public static async Task CapturesRefund( + this IPayPalHttpClient httpClient, AccessToken accessToken, + string captureId, bool debug = false + ) { var response = await httpClient.CapturesRefundAsync( accessToken, @@ -27,11 +29,11 @@ public static class CapturesRefundSample Amount = new PaymentMoney { Value = "20.00", - CurrencyCode = "USD" - } + CurrencyCode = "USD", + }, }); } - ); + ).ConfigureAwait(false); if (debug && response != null) { diff --git a/samples/PayPal.Sdk.Checkout.Samples/CreateOrderSample.cs b/samples/PayPal.Sdk.Checkout.Samples/CreateOrderSample.cs index 3d8cea75..60fbefe1 100644 --- a/samples/PayPal.Sdk.Checkout.Samples/CreateOrderSample.cs +++ b/samples/PayPal.Sdk.Checkout.Samples/CreateOrderSample.cs @@ -29,9 +29,9 @@ private static OrderRequest BuildRequestBody() UserAction = EUserAction.Continue, ShippingPreference = EShippingPreference.SetProvidedAddress, }, - PurchaseUnits = new List - { - new() + PurchaseUnits = + [ + new PurchaseUnitRequest { ReferenceId = "PUHF", Description = "Sporting Goods", @@ -46,29 +46,29 @@ private static OrderRequest BuildRequestBody() ItemTotal = new Money { CurrencyCode = "USD", - Value = "180.00" + Value = "180.00", }, Shipping = new Money { CurrencyCode = "USD", - Value = "20.00" + Value = "20.00", }, Handling = new Money { CurrencyCode = "USD", - Value = "10.00" + Value = "10.00", }, TaxTotal = new Money { CurrencyCode = "USD", - Value = "20.00" + Value = "20.00", }, ShippingDiscount = new Money { CurrencyCode = "USD", - Value = "10.00" - } - } + Value = "10.00", + }, + }, }, Items = new List { @@ -80,12 +80,12 @@ private static OrderRequest BuildRequestBody() UnitAmount = new Money { CurrencyCode = "USD", - Value = "90.00" + Value = "90.00", }, Tax = new Money { CurrencyCode = "USD", - Value = "10.00" + Value = "10.00", }, Quantity = "1", Category = EItemCategory.PhysicalGoods, @@ -98,22 +98,22 @@ private static OrderRequest BuildRequestBody() UnitAmount = new Money { CurrencyCode = "USD", - Value = "45.00" + Value = "45.00", }, Tax = new Money { CurrencyCode = "USD", - Value = "5.00" + Value = "5.00", }, Quantity = "2", Category = EItemCategory.PhysicalGoods, - } + }, }, ShippingDetail = new ShippingDetail { Name = new ShippingName { - FullName = "John Doe" + FullName = "John Doe", }, AddressPortable = new AddressPortable { @@ -122,11 +122,11 @@ private static OrderRequest BuildRequestBody() AdminArea2 = "San Francisco", AdminArea1 = "CA", PostalCode = "94107", - CountryCode = "US" - } - } - } - } + CountryCode = "US", + }, + }, + }, + ], }; return orderRequest; @@ -142,7 +142,7 @@ private static OrderRequest BuildRequestBody() { request.SetPreferReturn(EPreferReturn.Representation); request.SetRequestBody(BuildRequestBody()); - }); + }).ConfigureAwait(false); if (debug && response != null) { @@ -174,7 +174,7 @@ private static OrderRequest BuildRequestBodyWithMinimumFields() ApplicationContext = new ApplicationContext { CancelUrl = "https://www.example.com", - ReturnUrl = "https://www.example.com" + ReturnUrl = "https://www.example.com", }, PurchaseUnits = new List { @@ -183,10 +183,10 @@ private static OrderRequest BuildRequestBodyWithMinimumFields() AmountWithBreakdown = new AmountWithBreakdown { CurrencyCode = "USD", - Value = "220.00" - } - } - } + Value = "220.00", + }, + }, + }, }; return orderRequest; @@ -202,7 +202,7 @@ private static OrderRequest BuildRequestBodyWithMinimumFields() { request.SetPreferReturn(EPreferReturn.Representation); request.SetRequestBody(BuildRequestBodyWithMinimumFields()); - }); + }).ConfigureAwait(false); if (debug && response != null) { diff --git a/samples/PayPal.Sdk.Checkout.Samples/GetOrderSample.cs b/samples/PayPal.Sdk.Checkout.Samples/GetOrderSample.cs index 024d983c..2889b881 100644 --- a/samples/PayPal.Sdk.Checkout.Samples/GetOrderSample.cs +++ b/samples/PayPal.Sdk.Checkout.Samples/GetOrderSample.cs @@ -19,7 +19,7 @@ public static class GetOrderSample var response = await httpClient.GetOrderAsync( accessToken, orderId - ); + ).ConfigureAwait(false); if (debug && response != null) { diff --git a/samples/PayPal.Sdk.Checkout.Samples/PatchOrderSample.cs b/samples/PayPal.Sdk.Checkout.Samples/PatchOrderSample.cs index ffc7a234..433c6126 100644 --- a/samples/PayPal.Sdk.Checkout.Samples/PatchOrderSample.cs +++ b/samples/PayPal.Sdk.Checkout.Samples/PatchOrderSample.cs @@ -22,14 +22,14 @@ private static IReadOnlyCollection BuildPatches() { Op = "replace", Path = "/intent", - Value = "CAPTURE" + Value = "CAPTURE", }, new() { Op = "replace", Path = "/purchase_units/@reference_id=='PUHF'/description", - Value = "Physical Goods" - } + Value = "Physical Goods", + }, }; return patches; } @@ -44,12 +44,12 @@ await httpClient.OrdersPatchRequestAsync( accessToken, orderId, BuildPatches() - ); + ).ConfigureAwait(false); var response = await httpClient.GetOrderAsync( accessToken, orderId - ); + ).ConfigureAwait(false); if (debug && response != null) { diff --git a/samples/PayPal.Sdk.Checkout.Samples/PayPal.Sdk.Checkout.Samples.csproj b/samples/PayPal.Sdk.Checkout.Samples/PayPal.Sdk.Checkout.Samples.csproj index 61779045..c4cd4454 100644 --- a/samples/PayPal.Sdk.Checkout.Samples/PayPal.Sdk.Checkout.Samples.csproj +++ b/samples/PayPal.Sdk.Checkout.Samples/PayPal.Sdk.Checkout.Samples.csproj @@ -13,6 +13,10 @@ + + + + diff --git a/src/PayPal.Sdk.Checkout/Authentication/AccessToken.cs b/src/PayPal.Sdk.Checkout/Authentication/AccessToken.cs index df8a22e1..8fc44b56 100644 --- a/src/PayPal.Sdk.Checkout/Authentication/AccessToken.cs +++ b/src/PayPal.Sdk.Checkout/Authentication/AccessToken.cs @@ -3,18 +3,17 @@ namespace PayPal.Sdk.Checkout.Authentication; -public class AccessToken +public class AccessToken( + DateTime? receivedDate = null +) { - [JsonPropertyName("access_token")] - public string Token { get; set; } = null!; + [JsonPropertyName("access_token")] public string Token { get; set; } = null!; - [JsonPropertyName("token_type")] - public string TokenType { get; set; } = null!; + [JsonPropertyName("token_type")] public string TokenType { get; set; } = null!; - [JsonPropertyName("expires_in")] - public int ExpiresIn { get; set; } + [JsonPropertyName("expires_in")] public int ExpiresIn { get; set; } - private DateTime ReceivedDate { get; } + private DateTime ReceivedDate { get; } = receivedDate ?? DateTime.Now; [JsonConstructor] public AccessToken( @@ -26,11 +25,6 @@ public AccessToken( ExpiresIn = expiresIn; } - public AccessToken(DateTime? receivedDate = null) - { - ReceivedDate = receivedDate ?? DateTime.Now; - } - public bool IsExpired(DateTime? now = null) { var expireDate = ReceivedDate.Add(TimeSpan.FromSeconds(ExpiresIn)); diff --git a/src/PayPal.Sdk.Checkout/Core/HttpRequests/BaseHttpRequest.cs b/src/PayPal.Sdk.Checkout/Core/HttpRequests/BaseHttpRequest.cs index c5e42101..0f2eb3c7 100644 --- a/src/PayPal.Sdk.Checkout/Core/HttpRequests/BaseHttpRequest.cs +++ b/src/PayPal.Sdk.Checkout/Core/HttpRequests/BaseHttpRequest.cs @@ -6,74 +6,43 @@ namespace PayPal.Sdk.Checkout.Core.HttpRequests; -public abstract class BaseHttpRequest +public abstract class BaseHttpRequest( + string path, + HttpMethod method +) { - public HttpMethod Method { get; } + public HttpMethod Method { get; } = method; - public string Path { get; protected set; } + public string Path { get; protected set; } = path; public IDictionary> Headers { get; } = new Dictionary>(); public AuthenticationHeaderValue? Authorization { get; protected set; } public string ContentType { get; protected set; } = null!; - - protected BaseHttpRequest(string path, HttpMethod method) - { - Path = path; - Method = method; - } } -public abstract class BaseHttpRequest : BaseHttpRequest, IPayPalRequestWithResponseBody - where TResponseType : notnull -{ - protected BaseHttpRequest( - string path, HttpMethod method - ) : base(path, method) - { - } -} +public abstract class BaseHttpRequest( + string path, + HttpMethod method +) : BaseHttpRequest(path, method), IPayPalRequestWithResponseBody + where TResponseType : notnull; -public abstract class BaseHttpRequest : BaseHttpRequest, +public abstract class BaseHttpRequest( + string path, + HttpMethod method +) : BaseHttpRequest(path, method), IPayPalRequestWithRequestBody where TResponseType : notnull where TRequestBody : notnull { - public string PayPalRequestId { get; } + public string PayPalRequestId { get; } = Guid.NewGuid().ToString(); public TRequestBody Body { get; private set; } = default!; - protected BaseHttpRequest( - string path, HttpMethod method - ) : base(path, method) - { - PayPalRequestId = Guid.NewGuid().ToString(); - } - // ReSharper disable once MemberCanBeProtected.Global public void SetRequestBody(TRequestBody request) { Body = request; } } - -public abstract class BaseVoidHttpRequest : BaseHttpRequest, IPayPalRequestWithRequestBody - where TRequestBody : notnull -{ - public string PayPalRequestId { get; } - - public TRequestBody Body { get; private set; } = default!; - - protected BaseVoidHttpRequest( - string path, HttpMethod method - ) : base(path, method) - { - PayPalRequestId = Guid.NewGuid().ToString(); - } - - public void SetRequestBody(TRequestBody request) - { - Body = request; - } -} diff --git a/src/PayPal.Sdk.Checkout/Core/HttpRequests/BaseVoidHttpRequest.cs b/src/PayPal.Sdk.Checkout/Core/HttpRequests/BaseVoidHttpRequest.cs new file mode 100644 index 00000000..9b9400d8 --- /dev/null +++ b/src/PayPal.Sdk.Checkout/Core/HttpRequests/BaseVoidHttpRequest.cs @@ -0,0 +1,21 @@ +using System; +using System.Net.Http; +using PayPal.Sdk.Checkout.RequestInterfaces; + +namespace PayPal.Sdk.Checkout.Core.HttpRequests; + +public abstract class BaseVoidHttpRequest( + string path, + HttpMethod method +) : BaseHttpRequest(path, method), IPayPalRequestWithRequestBody + where TRequestBody : notnull +{ + public string PayPalRequestId { get; } = Guid.NewGuid().ToString(); + + public TRequestBody Body { get; private set; } = default!; + + public void SetRequestBody(TRequestBody request) + { + Body = request; + } +} diff --git a/src/PayPal.Sdk.Checkout/Core/HttpRequests/PayPalHttpRequest.WithFormRequest.WithJsonResponse.cs b/src/PayPal.Sdk.Checkout/Core/HttpRequests/PayPalHttpRequest.WithFormRequest.WithJsonResponse.cs index ef2e9668..2e1b2a94 100644 --- a/src/PayPal.Sdk.Checkout/Core/HttpRequests/PayPalHttpRequest.WithFormRequest.WithJsonResponse.cs +++ b/src/PayPal.Sdk.Checkout/Core/HttpRequests/PayPalHttpRequest.WithFormRequest.WithJsonResponse.cs @@ -11,20 +11,15 @@ public static partial class PayPalHttpRequest [SuppressMessage("ReSharper", "PartialTypeWithSinglePart")] public static partial class WithFormRequest { - public abstract class WithJsonResponse : - BaseHttpRequest>, + public abstract class WithJsonResponse( + string path, + HttpMethod method, + JsonTypeInfo jsonTypeInfoForResponseType + ) : BaseHttpRequest>(path, method), IPayPalRequestWithJsonResponseBody where TResponseType : notnull { - public JsonTypeInfo JsonTypeInfoForResponseType { get; } - - protected WithJsonResponse( - string path, HttpMethod method, - JsonTypeInfo jsonTypeInfoForResponseType - ) : base(path, method) - { - JsonTypeInfoForResponseType = jsonTypeInfoForResponseType; - } + public JsonTypeInfo JsonTypeInfoForResponseType { get; } = jsonTypeInfoForResponseType; } } } diff --git a/src/PayPal.Sdk.Checkout/Core/HttpRequests/PayPalHttpRequest.WithGetRequest.WithJsonResponse.cs b/src/PayPal.Sdk.Checkout/Core/HttpRequests/PayPalHttpRequest.WithGetRequest.WithJsonResponse.cs index d7a399eb..5adbe87d 100644 --- a/src/PayPal.Sdk.Checkout/Core/HttpRequests/PayPalHttpRequest.WithGetRequest.WithJsonResponse.cs +++ b/src/PayPal.Sdk.Checkout/Core/HttpRequests/PayPalHttpRequest.WithGetRequest.WithJsonResponse.cs @@ -5,26 +5,19 @@ namespace PayPal.Sdk.Checkout.Core.HttpRequests; - public static partial class PayPalHttpRequest { [SuppressMessage("ReSharper", "PartialTypeWithSinglePart")] public static partial class WithGetRequest { - public abstract class WithJsonResponse : - BaseHttpRequest, + public abstract class WithJsonResponse( + string path, + JsonTypeInfo jsonTypeInfoForResponseType + ) : BaseHttpRequest(path, HttpMethod.Get), IPayPalRequestWithJsonResponseBody where TResponseType : notnull { - public JsonTypeInfo JsonTypeInfoForResponseType { get; } - - protected WithJsonResponse( - string path, - JsonTypeInfo jsonTypeInfoForResponseType - ) : base(path, HttpMethod.Get) - { - JsonTypeInfoForResponseType = jsonTypeInfoForResponseType; - } + public JsonTypeInfo JsonTypeInfoForResponseType { get; } = jsonTypeInfoForResponseType; } } } diff --git a/src/PayPal.Sdk.Checkout/Core/HttpRequests/PayPalHttpRequest.WithJsonRequest.WithJsonResponse.cs b/src/PayPal.Sdk.Checkout/Core/HttpRequests/PayPalHttpRequest.WithJsonRequest.WithJsonResponse.cs index 25b83226..5c17b24a 100644 --- a/src/PayPal.Sdk.Checkout/Core/HttpRequests/PayPalHttpRequest.WithJsonRequest.WithJsonResponse.cs +++ b/src/PayPal.Sdk.Checkout/Core/HttpRequests/PayPalHttpRequest.WithJsonRequest.WithJsonResponse.cs @@ -9,25 +9,19 @@ public static partial class PayPalHttpRequest public static partial class WithJsonRequest where TRequestBody : notnull { - public abstract class WithJsonResponse : - BaseHttpRequest, + public abstract class WithJsonResponse( + string path, + HttpMethod method, + JsonTypeInfo jsonTypeInfoForResponseType, + JsonTypeInfo jsonTypeInfoForRequestBody + ) : BaseHttpRequest(path, method), IPayPalRequestWithJsonResponseBody, IPayPalRequestWithJsonRequestBody where TResponseType : notnull { - public JsonTypeInfo JsonTypeInfoForResponseType { get; } + public JsonTypeInfo JsonTypeInfoForResponseType { get; } = jsonTypeInfoForResponseType; - public JsonTypeInfo JsonTypeInfoForRequestBody { get; } - - protected WithJsonResponse( - string path, HttpMethod method, - JsonTypeInfo jsonTypeInfoForResponseType, - JsonTypeInfo jsonTypeInfoForRequestBody - ) : base(path, method) - { - JsonTypeInfoForResponseType = jsonTypeInfoForResponseType; - JsonTypeInfoForRequestBody = jsonTypeInfoForRequestBody; - } + public JsonTypeInfo JsonTypeInfoForRequestBody { get; } = jsonTypeInfoForRequestBody; } } } diff --git a/src/PayPal.Sdk.Checkout/Core/HttpRequests/PayPalHttpRequest.WithJsonRequest.WithoutResponse.cs b/src/PayPal.Sdk.Checkout/Core/HttpRequests/PayPalHttpRequest.WithJsonRequest.WithoutResponse.cs index cdcd0987..463ab2b6 100644 --- a/src/PayPal.Sdk.Checkout/Core/HttpRequests/PayPalHttpRequest.WithJsonRequest.WithoutResponse.cs +++ b/src/PayPal.Sdk.Checkout/Core/HttpRequests/PayPalHttpRequest.WithJsonRequest.WithoutResponse.cs @@ -9,19 +9,14 @@ public static partial class PayPalHttpRequest public static partial class WithJsonRequest where TRequestBody : notnull { - public abstract class WithoutResponse : - BaseVoidHttpRequest, + public abstract class WithoutResponse( + string path, + HttpMethod method, + JsonTypeInfo jsonTypeInfoForRequestBody + ) : BaseVoidHttpRequest(path, method), IPayPalRequestWithJsonRequestBody { - public JsonTypeInfo JsonTypeInfoForRequestBody { get; } - - protected WithoutResponse( - string path, HttpMethod method, - JsonTypeInfo jsonTypeInfoForRequestBody - ) : base(path, method) - { - JsonTypeInfoForRequestBody = jsonTypeInfoForRequestBody; - } + public JsonTypeInfo JsonTypeInfoForRequestBody { get; } = jsonTypeInfoForRequestBody; } } } diff --git a/src/PayPal.Sdk.Checkout/Core/MessageSerializers/FormEncodedSerializer.cs b/src/PayPal.Sdk.Checkout/Core/MessageSerializers/FormEncodedSerializer.cs index 507b4700..785943fb 100644 --- a/src/PayPal.Sdk.Checkout/Core/MessageSerializers/FormEncodedSerializer.cs +++ b/src/PayPal.Sdk.Checkout/Core/MessageSerializers/FormEncodedSerializer.cs @@ -14,7 +14,7 @@ public class FormEncodedSerializer : IMessageSerializer public bool CanSerialize( TRequestBody body, string contentType - ) where TRequestBody : notnull => contentType == ApplicationXForm; + ) where TRequestBody : notnull => string.Equals(contentType, ApplicationXForm, StringComparison.Ordinal); public Task SerializeAsync( TRequestBody body, @@ -26,11 +26,17 @@ CancellationToken cancellationToken { if (body is IDictionary dictionary) { - return Task.FromResult((HttpContent) new FormUrlEncodedContent(dictionary)); + return Task.FromResult(new FormUrlEncodedContent(dictionary)); + } + + if (body is IReadOnlyDictionary readOnlyDictionary) + { + return Task.FromResult(new FormUrlEncodedContent(readOnlyDictionary)); } throw new ArgumentException( - "Request requestBody must be IDictionary when Content-Type is application/x-www-form-urlencoded" + "Request body must be IDictionary when Content-Type is application/x-www-form-urlencoded", + nameof(body) ); } diff --git a/src/PayPal.Sdk.Checkout/Core/MessageSerializers/JsonMessageSerializer.cs b/src/PayPal.Sdk.Checkout/Core/MessageSerializers/JsonMessageSerializer.cs index 2bedf536..5a683dab 100644 --- a/src/PayPal.Sdk.Checkout/Core/MessageSerializers/JsonMessageSerializer.cs +++ b/src/PayPal.Sdk.Checkout/Core/MessageSerializers/JsonMessageSerializer.cs @@ -16,7 +16,7 @@ public class JsonMessageSerializer : IMessageSerializer public bool CanSerialize( TRequestBody body, string contentType - ) where TRequestBody : notnull => contentType == ApplicationJson; + ) where TRequestBody : notnull => string.Equals(contentType, ApplicationJson, StringComparison.Ordinal); public async Task SerializeAsync( TRequestBody body, @@ -35,7 +35,7 @@ await JsonSerializer.SerializeAsync( body, requestBodyJsonTypeInfo, cancellationToken - ); + ).ConfigureAwait(false); memoryStream.Seek(0, SeekOrigin.Begin); @@ -50,7 +50,7 @@ await JsonSerializer.SerializeAsync( public bool CanDeserialize( HttpContent response, MediaTypeHeaderValue contentType - ) where TResponse : notnull => contentType.MediaType == ApplicationJson; + ) where TResponse : notnull => string.Equals(contentType.MediaType, ApplicationJson, StringComparison.Ordinal); public async Task DeserializeAsync( HttpContent response, @@ -64,13 +64,13 @@ CancellationToken cancellationToken var stream = await response.ReadAsStreamAsync( cancellationToken - ); + ).ConfigureAwait(false); var deserializedResponse = await JsonSerializer.DeserializeAsync( stream, responseJsonTypeInfo, cancellationToken - ); + ).ConfigureAwait(false); return deserializedResponse ?? throw new NullReferenceException("Deserialize of the HttpContent is null"); } diff --git a/src/PayPal.Sdk.Checkout/Core/MessageSerializers/TextSerializer.cs b/src/PayPal.Sdk.Checkout/Core/MessageSerializers/TextSerializer.cs index a65747ed..6f0ccc89 100644 --- a/src/PayPal.Sdk.Checkout/Core/MessageSerializers/TextSerializer.cs +++ b/src/PayPal.Sdk.Checkout/Core/MessageSerializers/TextSerializer.cs @@ -8,13 +8,14 @@ namespace PayPal.Sdk.Checkout.Core.MessageSerializers; -public class TextSerializer : IMessageSerializer +public partial class TextSerializer : IMessageSerializer { - private readonly Regex _contentTypeRegex = new("^text/.*$"); + [GeneratedRegex("^text/.*$", RegexOptions.None, matchTimeoutMilliseconds: 1000)] + private static partial Regex MyRegex(); public bool CanSerialize( TRequestBody body, string contentType - ) where TRequestBody : notnull => _contentTypeRegex.Match(contentType).Success; + ) where TRequestBody : notnull => MyRegex().Match(contentType).Success; public Task SerializeAsync( TRequestBody body, @@ -29,12 +30,15 @@ CancellationToken cancellationToken return Task.FromResult((HttpContent) new StringContent(bodyString)); } - throw new ArgumentException("Request requestBody must be string when Content-Type is text/.*"); + throw new ArgumentException( + "Request body must be string when Content-Type is text/.*", + nameof(body) + ); } public bool CanDeserialize( HttpContent response, MediaTypeHeaderValue contentType - ) where TResponse : notnull => _contentTypeRegex.Match(contentType.MediaType!).Success; + ) where TResponse : notnull => MyRegex().Match(contentType.MediaType!).Success; public async Task DeserializeAsync( HttpContent response, @@ -46,6 +50,6 @@ CancellationToken cancellationToken { return (TResponse) (object) await response.ReadAsStringAsync( cancellationToken - ); + ).ConfigureAwait(false); } } diff --git a/src/PayPal.Sdk.Checkout/Core/PayPalHttpException.cs b/src/PayPal.Sdk.Checkout/Core/PayPalHttpException.cs index 6df9caf2..6e21869d 100644 --- a/src/PayPal.Sdk.Checkout/Core/PayPalHttpException.cs +++ b/src/PayPal.Sdk.Checkout/Core/PayPalHttpException.cs @@ -4,22 +4,15 @@ namespace PayPal.Sdk.Checkout.Core; -public class PayPalHttpException : Exception +public class PayPalHttpException( + HttpStatusCode responseStatusCode, + HttpResponseHeaders responseHeaders, + string responseBodyContent +) : Exception(responseStatusCode.ToString()) { - public HttpStatusCode ResponseStatusCode { get; } + public HttpStatusCode ResponseStatusCode { get; } = responseStatusCode; - public HttpResponseHeaders ResponseHeaders { get; } + public HttpResponseHeaders ResponseHeaders { get; } = responseHeaders; - public string ResponseBodyContent { get; } - - public PayPalHttpException( - HttpStatusCode responseStatusCode, - HttpResponseHeaders responseHeaders, - string responseBodyContent - ) : base(responseStatusCode.ToString()) - { - ResponseStatusCode = responseStatusCode; - ResponseHeaders = responseHeaders; - ResponseBodyContent = responseBodyContent; - } + public string ResponseBodyContent { get; } = responseBodyContent; } diff --git a/src/PayPal.Sdk.Checkout/Core/PayPalHttpResponse.cs b/src/PayPal.Sdk.Checkout/Core/PayPalHttpResponse.cs index c3680da4..d38dd09d 100644 --- a/src/PayPal.Sdk.Checkout/Core/PayPalHttpResponse.cs +++ b/src/PayPal.Sdk.Checkout/Core/PayPalHttpResponse.cs @@ -4,32 +4,21 @@ namespace PayPal.Sdk.Checkout.Core; -public class PayPalHttpResponse : IPayPalHttpResponse +public class PayPalHttpResponse( + HttpResponseHeaders responseHeaders, + HttpStatusCode responseStatusCode +) : IPayPalHttpResponse { - public HttpResponseHeaders ResponseHeaders { get; } + public HttpResponseHeaders ResponseHeaders { get; } = responseHeaders; - public HttpStatusCode ResponseStatusCode { get; } - - public PayPalHttpResponse( - HttpResponseHeaders responseHeaders, - HttpStatusCode responseStatusCode - ) - { - ResponseHeaders = responseHeaders; - ResponseStatusCode = responseStatusCode; - } + public HttpStatusCode ResponseStatusCode { get; } = responseStatusCode; } -public class PayPalHttpResponse : PayPalHttpResponse, IPayPalHttpResponse +public class PayPalHttpResponse( + HttpResponseHeaders responseHeaders, + HttpStatusCode responseStatusCode, + TResponse? responseBody +) : PayPalHttpResponse(responseHeaders, responseStatusCode), IPayPalHttpResponse { - public TResponse? ResponseBody { get; } - - public PayPalHttpResponse( - HttpResponseHeaders responseHeaders, - HttpStatusCode responseStatusCode, - TResponse? responseBody - ) : base(responseHeaders, responseStatusCode) - { - ResponseBody = responseBody; - } + public TResponse? ResponseBody { get; } = responseBody; } diff --git a/src/PayPal.Sdk.Checkout/Core/PayPayEncoder.cs b/src/PayPal.Sdk.Checkout/Core/PayPayEncoder.cs index d83c55f9..9255cddc 100644 --- a/src/PayPal.Sdk.Checkout/Core/PayPayEncoder.cs +++ b/src/PayPal.Sdk.Checkout/Core/PayPayEncoder.cs @@ -13,17 +13,12 @@ namespace PayPal.Sdk.Checkout.Core; public class PayPayEncoder : IPayPayEncoder { - private readonly IReadOnlyCollection _messageSerializers; - - public PayPayEncoder() - { - _messageSerializers = new IMessageSerializer[] - { - new FormEncodedSerializer(), - new JsonMessageSerializer(), - new TextSerializer(), - }; - } + private readonly IReadOnlyCollection _messageSerializers = + [ + new FormEncodedSerializer(), + new JsonMessageSerializer(), + new TextSerializer(), + ]; public Task SerializeRequestAsync( TRequestBody body, @@ -45,7 +40,10 @@ CancellationToken cancellationToken ); } - throw new ArgumentException($"Not found serializer for message {contentType}"); + throw new ArgumentException( + $"Not found serializer for message {contentType}", + nameof(body) + ); } public Task DeserializeResponseAsync( @@ -71,7 +69,8 @@ CancellationToken cancellationToken } throw new ArgumentException( - $"Not found serializer for message CharSet={mediaTypeHeaderValue.CharSet} MediaType={mediaTypeHeaderValue.MediaType}" + $"Not found serializer for message CharSet={mediaTypeHeaderValue.CharSet} MediaType={mediaTypeHeaderValue.MediaType}", + typeof(TResponse).Name ); } } diff --git a/src/PayPal.Sdk.Checkout/Core/PaypalHttpClient.cs b/src/PayPal.Sdk.Checkout/Core/PaypalHttpClient.cs index c72b403e..9971ba99 100644 --- a/src/PayPal.Sdk.Checkout/Core/PaypalHttpClient.cs +++ b/src/PayPal.Sdk.Checkout/Core/PaypalHttpClient.cs @@ -13,35 +13,14 @@ namespace PayPal.Sdk.Checkout.Core; -// ReSharper disable once ClassWithVirtualMembersNeverInherited.Global -public class PayPalHttpClient : IPayPalHttpClient +public class PayPalHttpClient( + HttpClient httpClient, + IPayPayEncoder payPayEncoder, + IOptions payPalOptions, + bool leaveOpen = true +) : IPayPalHttpClient { - private readonly HttpClient _httpClient; - - private readonly IPayPayEncoder _payPayEncoder; - - private readonly IOptions _payPalOptions; - - private readonly bool _leaveOpen; - - /// - /// - /// - /// Mainly for test to call dispose on httpClient - public PayPalHttpClient( - HttpClient httpClient, - IPayPayEncoder payPayEncoder, - IOptions payPalOptions, - bool leaveOpen = true - ) - { - _httpClient = httpClient; - _payPayEncoder = payPayEncoder; - _payPalOptions = payPalOptions; - _leaveOpen = leaveOpen; - } - - public PayPalOptions GetPayPalOptions => _payPalOptions.Value; + public PayPalOptions GetPayPalOptions => payPalOptions.Value; protected virtual HttpRequestMessage CreateHttpRequest( TRequest request, @@ -85,16 +64,17 @@ CancellationToken cancellationToken { if (request is IPayPalRequestWithRequestBody requestWithRequestBody) { - return await _payPayEncoder.SerializeRequestAsync( + return await payPayEncoder.SerializeRequestAsync( requestWithRequestBody.Body, (request as IPayPalRequestWithJsonRequestBody)?.JsonTypeInfoForRequestBody, requestWithRequestBody.ContentType, cancellationToken - ); + ).ConfigureAwait(false); } throw new ArgumentException( - $"The request {typeof(TRequest)} do not implement {typeof(IPayPalRequestWithRequestBody)}" + $"The request {typeof(TRequest)} do not implement {typeof(IPayPalRequestWithRequestBody)}", + nameof(request) ); } @@ -109,7 +89,7 @@ protected virtual async Task ProcessResponseAsync( var responseBodyContent = await response.Content.ReadAsStringAsync( cancellationToken - ); + ).ConfigureAwait(false); throw new PayPalHttpException(response.StatusCode, response.Headers, responseBodyContent); } @@ -127,12 +107,12 @@ CancellationToken cancellationToken if (response.Content.Headers.ContentType != null) { - responseBody = await _payPayEncoder.DeserializeResponseAsync( + responseBody = await payPayEncoder.DeserializeResponseAsync( response.Content, jsonTypeInfoForResponseType, response.Content.Headers.ContentType, cancellationToken - ); + ).ConfigureAwait(false); } return new PayPalHttpResponse(response.Headers, response.StatusCode, responseBody); @@ -140,7 +120,7 @@ CancellationToken cancellationToken var responseBodyContent = await response.Content.ReadAsStringAsync( cancellationToken - ); + ).ConfigureAwait(false); throw new PayPalHttpException(response.StatusCode, response.Headers, responseBodyContent); } @@ -162,21 +142,21 @@ CancellationToken cancellationToken using var httpContent = await CreateHttpContent( request, cancellationToken - ); + ).ConfigureAwait(false); httpRequest.Content = httpContent; - response = await _httpClient.SendAsync(httpRequest, cancellationToken); + response = await httpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false); } else { - response = await _httpClient.SendAsync(httpRequest, cancellationToken); + response = await httpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false); } return await ProcessResponseAsync( response, (request as IPayPalRequestWithJsonResponseBody)?.JsonTypeInfoForResponseType, cancellationToken - ); + ).ConfigureAwait(false); } public virtual async Task> ExecuteAsync( @@ -190,19 +170,20 @@ CancellationToken cancellationToken if (request is IPayPalRequestWithRequestBody) { throw new ArgumentException( - $"Use the {nameof(ExecuteAsync)} method signature" + $"Use the {nameof(ExecuteAsync)} method signature", + nameof(request) ); } var httpRequest = CreateHttpRequest(request, accessToken); - var response = await _httpClient.SendAsync(httpRequest, cancellationToken); + var response = await httpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false); return await ProcessResponseAsync( response, (request as IPayPalRequestWithJsonResponseBody)?.JsonTypeInfoForResponseType, cancellationToken - ); + ).ConfigureAwait(false); } public virtual async Task ExecuteVoidAsync( @@ -221,17 +202,17 @@ CancellationToken cancellationToken using var httpContent = await CreateHttpContent( request, cancellationToken - ); + ).ConfigureAwait(false); httpRequest.Content = httpContent; - response = await _httpClient.SendAsync(httpRequest, cancellationToken); + response = await httpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false); } else { - response = await _httpClient.SendAsync(httpRequest, cancellationToken); + response = await httpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false); } - return await ProcessResponseAsync(response, cancellationToken); + return await ProcessResponseAsync(response, cancellationToken).ConfigureAwait(false); } public virtual async Task ExecuteVoidAsync( @@ -243,14 +224,17 @@ CancellationToken cancellationToken { if (request is IPayPalRequestWithRequestBody) { - throw new ArgumentException($"Use the {nameof(ExecuteVoidAsync)} method signature"); + throw new ArgumentException( + $"Use the {nameof(ExecuteVoidAsync)} method signature", + nameof(request) + ); } var httpRequest = CreateHttpRequest(request, accessToken); - var response = await _httpClient.SendAsync(httpRequest, cancellationToken); + var response = await httpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false); - return await ProcessResponseAsync(response, cancellationToken); + return await ProcessResponseAsync(response, cancellationToken).ConfigureAwait(false); } @@ -261,9 +245,9 @@ public void Dispose() { if (!_disposed) { - if (!_leaveOpen) + if (!leaveOpen) { - _httpClient.Dispose(); + httpClient.Dispose(); } _disposed = true; diff --git a/src/PayPal.Sdk.Checkout/Core/UserAgent.cs b/src/PayPal.Sdk.Checkout/Core/UserAgent.cs index 9bc3dbb4..261d0189 100644 --- a/src/PayPal.Sdk.Checkout/Core/UserAgent.cs +++ b/src/PayPal.Sdk.Checkout/Core/UserAgent.cs @@ -37,14 +37,13 @@ GitInfo.TagMajor is { } major } header.Append(" ("); - header.Append(string.Join(";", new[] - { + header.Append(string.Join(";", [ FormatUserAgentParameter("lang", "DOTNET"), FormatUserAgentParameter("v", DotNetVersion), FormatUserAgentParameter("clr", DotNetClrVersion), FormatUserAgentParameter("bit", OperatingSystemBitness), - FormatUserAgentParameter("os", OperatingSystemName) - })); + FormatUserAgentParameter("os", OperatingSystemName), + ])); header.Append(")"); return header.ToString(); diff --git a/src/PayPal.Sdk.Checkout/Extensions/AuthenticateRequestExtensions.cs b/src/PayPal.Sdk.Checkout/Extensions/AuthenticateRequestExtensions.cs index b158919a..ba09f23b 100644 --- a/src/PayPal.Sdk.Checkout/Extensions/AuthenticateRequestExtensions.cs +++ b/src/PayPal.Sdk.Checkout/Extensions/AuthenticateRequestExtensions.cs @@ -15,7 +15,9 @@ public static class AuthenticateRequestExtensions { var request = new AccessTokenRequest(payPalHttpClient.GetPayPalOptions, refreshToken); - var response = await payPalHttpClient.ExecuteAsync, AccessToken>(request, null, cancellationToken); + var response = await payPalHttpClient.ExecuteAsync, AccessToken>( + request, accessToken: null, cancellationToken + ).ConfigureAwait(false); return response.ResponseBody; } diff --git a/src/PayPal.Sdk.Checkout/Extensions/DependencyInjectionExtensions.cs b/src/PayPal.Sdk.Checkout/Extensions/DependencyInjectionExtensions.cs index 3e631de4..016e73aa 100644 --- a/src/PayPal.Sdk.Checkout/Extensions/DependencyInjectionExtensions.cs +++ b/src/PayPal.Sdk.Checkout/Extensions/DependencyInjectionExtensions.cs @@ -38,7 +38,7 @@ public static IServiceCollection AddPayPalCheckout( .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { AllowAutoRedirect = false, - AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip + AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip, }); return services; diff --git a/src/PayPal.Sdk.Checkout/Extensions/OrderRequestExtensions.cs b/src/PayPal.Sdk.Checkout/Extensions/OrderRequestExtensions.cs index c5920357..f3691b08 100644 --- a/src/PayPal.Sdk.Checkout/Extensions/OrderRequestExtensions.cs +++ b/src/PayPal.Sdk.Checkout/Extensions/OrderRequestExtensions.cs @@ -35,7 +35,7 @@ public static Task> CreateOrderRawAsync( accessToken, configureRequest, cancellationToken - ); + ).ConfigureAwait(false); return response.ResponseBody; } @@ -74,7 +74,7 @@ public static Task> AuthorizeOrderRawAsync( orderId, configureRequest, cancellationToken - ); + ).ConfigureAwait(false); return response.ResponseBody; } @@ -113,7 +113,7 @@ public static Task> CaptureOrderRawAsync( orderId, configureRequest, cancellationToken - ); + ).ConfigureAwait(false); return response.ResponseBody; } @@ -130,7 +130,9 @@ public static Task> GetOrderRawAsync( configureRequest?.Invoke(request); - return payPalHttpClient.ExecuteAsync(request, accessToken, cancellationToken); + return payPalHttpClient.ExecuteAsync( + request, accessToken, cancellationToken + ); } public static async Task GetOrderAsync( @@ -146,7 +148,7 @@ public static Task> GetOrderRawAsync( orderId, configureRequest, cancellationToken - ); + ).ConfigureAwait(false); return response.ResponseBody; } @@ -166,7 +168,9 @@ public static async Task OrdersPatchRequestRawAsync( configureRequest?.Invoke(request); - return await payPalHttpClient.ExecuteVoidAsync>(request, accessToken, cancellationToken); + return await payPalHttpClient.ExecuteVoidAsync>( + request, accessToken, cancellationToken + ).ConfigureAwait(false); } public static Task OrdersPatchRequestAsync( @@ -193,7 +197,9 @@ public static async Task> ValidateOrderRawAsync( configureRequest?.Invoke(request); - return await payPalHttpClient.ExecuteAsync(request, accessToken, cancellationToken); + return await payPalHttpClient.ExecuteAsync( + request, accessToken, cancellationToken + ).ConfigureAwait(false); } public static async Task ValidateOrderAsync( @@ -204,7 +210,9 @@ public static async Task> ValidateOrderRawAsync( CancellationToken cancellationToken = default ) { - var response = await payPalHttpClient.ValidateOrderRawAsync(accessToken, orderId, configureRequest, cancellationToken); + var response = await payPalHttpClient.ValidateOrderRawAsync( + accessToken, orderId, configureRequest, cancellationToken + ).ConfigureAwait(false); return response.ResponseBody; } diff --git a/src/PayPal.Sdk.Checkout/Extensions/PaymentRequestExtensions.cs b/src/PayPal.Sdk.Checkout/Extensions/PaymentRequestExtensions.cs index 95eacb44..3d46c33c 100644 --- a/src/PayPal.Sdk.Checkout/Extensions/PaymentRequestExtensions.cs +++ b/src/PayPal.Sdk.Checkout/Extensions/PaymentRequestExtensions.cs @@ -21,7 +21,9 @@ public static class PaymentRequestExtensions configureRequest?.Invoke(request); - var response = await payPalHttpClient.ExecuteAsync(request, accessToken, cancellationToken); + var response = await payPalHttpClient.ExecuteAsync( + request, accessToken, cancellationToken + ).ConfigureAwait(false); return response.ResponseBody; } @@ -38,7 +40,9 @@ public static class PaymentRequestExtensions configureRequest?.Invoke(request); - var response = await payPalHttpClient.ExecuteAsync(request, accessToken, cancellationToken); + var response = await payPalHttpClient.ExecuteAsync( + request, accessToken, cancellationToken + ).ConfigureAwait(false); return response.ResponseBody; } diff --git a/src/PayPal.Sdk.Checkout/Extensions/RequestContractExtensions.cs b/src/PayPal.Sdk.Checkout/Extensions/RequestContractExtensions.cs index f1398377..657525bb 100644 --- a/src/PayPal.Sdk.Checkout/Extensions/RequestContractExtensions.cs +++ b/src/PayPal.Sdk.Checkout/Extensions/RequestContractExtensions.cs @@ -24,7 +24,7 @@ public static TRequest SetPreferReturn(this TRequest request, EPreferR { EPreferReturn.Minimal => "return=minimal", EPreferReturn.Representation => "return=representation", - _ => throw new ArgumentOutOfRangeException(nameof(preferReturn), preferReturn, null) + _ => throw new ArgumentOutOfRangeException(nameof(preferReturn), preferReturn, null), }; request.Headers.Add("Prefer", preferValue); diff --git a/src/PayPal.Sdk.Checkout/Orders/OrdersPatchRequest.cs b/src/PayPal.Sdk.Checkout/Orders/OrdersPatchRequest.cs index 25fdbd79..6d8d3944 100644 --- a/src/PayPal.Sdk.Checkout/Orders/OrdersPatchRequest.cs +++ b/src/PayPal.Sdk.Checkout/Orders/OrdersPatchRequest.cs @@ -8,19 +8,6 @@ namespace PayPal.Sdk.Checkout.Orders; -/// -public class OrdersStringPatchRequest : OrdersPatchRequest -{ - public OrdersStringPatchRequest( - string orderId - ) : base( - orderId, - PayPalJsonSerializerContext.Default.IReadOnlyCollectionStringPatch - ) - { - } -} - /// /// Updates an order that has the `CREATED` or `APPROVED` status. You cannot update an order with `COMPLETED` status. /// You can patch these attributes and objects: diff --git a/src/PayPal.Sdk.Checkout/Orders/OrdersStringPatchRequest.cs b/src/PayPal.Sdk.Checkout/Orders/OrdersStringPatchRequest.cs new file mode 100644 index 00000000..39adcf7a --- /dev/null +++ b/src/PayPal.Sdk.Checkout/Orders/OrdersStringPatchRequest.cs @@ -0,0 +1,11 @@ +using PayPal.Sdk.Checkout.Core.MessageSerializers; + +namespace PayPal.Sdk.Checkout.Orders; + +/// +public class OrdersStringPatchRequest( + string orderId +) : OrdersPatchRequest( + orderId, + PayPalJsonSerializerContext.Default.IReadOnlyCollectionStringPatch +); diff --git a/src/PayPal.Sdk.Checkout/Orders/Patch.cs b/src/PayPal.Sdk.Checkout/Orders/Patch.cs index 6a9c4ebf..6c0aca93 100644 --- a/src/PayPal.Sdk.Checkout/Orders/Patch.cs +++ b/src/PayPal.Sdk.Checkout/Orders/Patch.cs @@ -2,8 +2,6 @@ namespace PayPal.Sdk.Checkout.Orders; -public class StringPatch : Patch; - /// /// The JSON patch object to apply partial updates to resources. /// diff --git a/src/PayPal.Sdk.Checkout/Orders/StringPatch.cs b/src/PayPal.Sdk.Checkout/Orders/StringPatch.cs new file mode 100644 index 00000000..52a8f1d6 --- /dev/null +++ b/src/PayPal.Sdk.Checkout/Orders/StringPatch.cs @@ -0,0 +1,3 @@ +namespace PayPal.Sdk.Checkout.Orders; + +public class StringPatch : Patch; diff --git a/src/PayPal.Sdk.Checkout/PayPal.Sdk.Checkout.csproj b/src/PayPal.Sdk.Checkout/PayPal.Sdk.Checkout.csproj index e4d08296..2d0a8a36 100644 --- a/src/PayPal.Sdk.Checkout/PayPal.Sdk.Checkout.csproj +++ b/src/PayPal.Sdk.Checkout/PayPal.Sdk.Checkout.csproj @@ -56,6 +56,7 @@ + diff --git a/src/PayPal.Sdk.Checkout/RequestInterfaces/IPayPalRequestWithJsonRequestBody.cs b/src/PayPal.Sdk.Checkout/RequestInterfaces/IPayPalRequestWithJsonRequestBody.cs new file mode 100644 index 00000000..8f2e2633 --- /dev/null +++ b/src/PayPal.Sdk.Checkout/RequestInterfaces/IPayPalRequestWithJsonRequestBody.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization.Metadata; + +namespace PayPal.Sdk.Checkout.RequestInterfaces; + +public interface IPayPalRequestWithJsonRequestBody : IPayPalRequestWithRequestBody + where TRequestBody : notnull +{ + JsonTypeInfo JsonTypeInfoForRequestBody { get; } +} diff --git a/src/PayPal.Sdk.Checkout/RequestInterfaces/IPayPalRequestWithJsonResponseBody.cs b/src/PayPal.Sdk.Checkout/RequestInterfaces/IPayPalRequestWithJsonResponseBody.cs new file mode 100644 index 00000000..25635264 --- /dev/null +++ b/src/PayPal.Sdk.Checkout/RequestInterfaces/IPayPalRequestWithJsonResponseBody.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization.Metadata; + +namespace PayPal.Sdk.Checkout.RequestInterfaces; + +public interface IPayPalRequestWithJsonResponseBody : IPayPalRequestWithResponseBody + where TResponseType : notnull +{ + JsonTypeInfo JsonTypeInfoForResponseType { get; } +} diff --git a/src/PayPal.Sdk.Checkout/RequestInterfaces/IPayPalRequestWithRequestBody.cs b/src/PayPal.Sdk.Checkout/RequestInterfaces/IPayPalRequestWithRequestBody.cs index 9239fb89..97a9f321 100644 --- a/src/PayPal.Sdk.Checkout/RequestInterfaces/IPayPalRequestWithRequestBody.cs +++ b/src/PayPal.Sdk.Checkout/RequestInterfaces/IPayPalRequestWithRequestBody.cs @@ -1,5 +1,3 @@ -using System.Text.Json.Serialization.Metadata; - namespace PayPal.Sdk.Checkout.RequestInterfaces; public interface IPayPalRequestWithRequestBody @@ -14,9 +12,3 @@ public interface IPayPalRequestWithRequestBody : IPayPalRequestWit { TRequestBody Body { get; } } - -public interface IPayPalRequestWithJsonRequestBody : IPayPalRequestWithRequestBody - where TRequestBody : notnull -{ - JsonTypeInfo JsonTypeInfoForRequestBody { get; } -} diff --git a/src/PayPal.Sdk.Checkout/RequestInterfaces/IPayPalRequestWithResponseBody.cs b/src/PayPal.Sdk.Checkout/RequestInterfaces/IPayPalRequestWithResponseBody.cs index 24a52a3e..54706cd0 100644 --- a/src/PayPal.Sdk.Checkout/RequestInterfaces/IPayPalRequestWithResponseBody.cs +++ b/src/PayPal.Sdk.Checkout/RequestInterfaces/IPayPalRequestWithResponseBody.cs @@ -1,5 +1,4 @@ using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization.Metadata; namespace PayPal.Sdk.Checkout.RequestInterfaces; @@ -10,10 +9,3 @@ public interface IPayPalRequestWithResponseBody< TResponseType > : IPayPalRequestWithResponseBody where TResponseType : notnull; - - -public interface IPayPalRequestWithJsonResponseBody : IPayPalRequestWithResponseBody - where TResponseType : notnull -{ - JsonTypeInfo JsonTypeInfoForResponseType { get; } -} diff --git a/tests/PayPal.Sdk.Checkout.Test/Infrastructure/HttpClientLoggingFilter.cs b/tests/PayPal.Sdk.Checkout.Test/Infrastructure/HttpClientLoggingFilter.cs index a12b0043..578848b2 100644 --- a/tests/PayPal.Sdk.Checkout.Test/Infrastructure/HttpClientLoggingFilter.cs +++ b/tests/PayPal.Sdk.Checkout.Test/Infrastructure/HttpClientLoggingFilter.cs @@ -4,16 +4,11 @@ namespace PayPal.Sdk.Checkout.Test.Infrastructure; -public class HttpClientLoggingFilter : IHttpMessageHandlerBuilderFilter +public class HttpClientLoggingFilter( + ILoggerFactory loggerFactory +) : IHttpMessageHandlerBuilderFilter { - private readonly ILoggerFactory _loggerFactory; - - public HttpClientLoggingFilter( - ILoggerFactory loggerFactory - ) - { - _loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); - } + private readonly ILoggerFactory _loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); public Action Configure(Action next) { diff --git a/tests/PayPal.Sdk.Checkout.Test/Infrastructure/HttpClientLoggingScopeHttpMessageHandler.cs b/tests/PayPal.Sdk.Checkout.Test/Infrastructure/HttpClientLoggingScopeHttpMessageHandler.cs index 83a1a6a4..732c8ced 100644 --- a/tests/PayPal.Sdk.Checkout.Test/Infrastructure/HttpClientLoggingScopeHttpMessageHandler.cs +++ b/tests/PayPal.Sdk.Checkout.Test/Infrastructure/HttpClientLoggingScopeHttpMessageHandler.cs @@ -11,19 +11,13 @@ namespace PayPal.Sdk.Checkout.Test.Infrastructure; -public class HttpClientLoggingScopeHttpMessageHandler : DelegatingHandler +public class HttpClientLoggingScopeHttpMessageHandler( + ILogger scopeLogger, + ILogger requestLogger +) : DelegatingHandler { - private readonly ILogger _scopeLogger; - private readonly ILogger _requestLogger; - - public HttpClientLoggingScopeHttpMessageHandler( - ILogger scopeLogger, - ILogger requestLogger - ) - { - _scopeLogger = scopeLogger ?? throw new ArgumentNullException(nameof(scopeLogger)); - _requestLogger = requestLogger ?? throw new ArgumentNullException(nameof(requestLogger)); - } + private readonly ILogger _scopeLogger = scopeLogger ?? throw new ArgumentNullException(nameof(scopeLogger)); + private readonly ILogger _requestLogger = requestLogger ?? throw new ArgumentNullException(nameof(requestLogger)); protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { @@ -34,9 +28,9 @@ protected override async Task SendAsync(HttpRequestMessage using var log = Log.BeginRequestPipelineScope(_scopeLogger, request); - await log.RequestPipelineStart(_requestLogger, request, cancellationToken); - var response = await base.SendAsync(request, cancellationToken); - await log.RequestPipelineEnd(_requestLogger, response, cancellationToken); + await log.RequestPipelineStart(_requestLogger, request, cancellationToken).ConfigureAwait(false); + var response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false); + await log.RequestPipelineEnd(_requestLogger, response, cancellationToken).ConfigureAwait(false); return response; } @@ -96,7 +90,7 @@ public async Task RequestPipelineStart(ILogger logger, HttpRequestMessage reques string? content = null; if (request.Content != null) { - content = await GetContent(request.Content, cancellationToken); + content = await GetContent(request.Content, cancellationToken).ConfigureAwait(false); } RequestPipelineStartDefine(logger, request.Method, request.RequestUri, correlationId, content, null); @@ -107,7 +101,7 @@ public async Task RequestPipelineEnd(ILogger logger, HttpResponseMessage respons { if (logger.IsEnabled(LogLevel.Trace)) { - var content = await GetContent(response.Content, cancellationToken); + var content = await GetContent(response.Content, cancellationToken).ConfigureAwait(false); RequestPipelineEndDefine(logger, response.StatusCode, content, null); } @@ -129,23 +123,26 @@ private async Task GetContent(HttpContent httpContent, CancellationToken { if (httpContent.Headers.ContentEncoding.Contains("gzip")) { - await httpContent.LoadIntoBufferAsync(); - var stream = await httpContent.ReadAsStreamAsync(cancellationToken); + await httpContent.LoadIntoBufferAsync().ConfigureAwait(false); + var stream = await httpContent.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); if (!stream.CanSeek) { return ""; } - await using var compressionStream = new GZipStream( + var compressionStream = new GZipStream( stream, CompressionMode.Decompress, leaveOpen: true ); - - using var reader = new StreamReader( - compressionStream, Encoding.UTF8, detectEncodingFromByteOrderMarks: false, bufferSize: -1, leaveOpen: true - ); - var content = await reader.ReadToEndAsync( - cancellationToken - ); + string content; + await using (compressionStream.ConfigureAwait(false)) + { + using var reader = new StreamReader( + compressionStream, Encoding.UTF8, detectEncodingFromByteOrderMarks: false, bufferSize: -1, leaveOpen: true + ); + content = await reader.ReadToEndAsync( + cancellationToken + ).ConfigureAwait(false); + } stream.Seek(0, SeekOrigin.Begin); @@ -161,7 +158,7 @@ private async Task GetContent(HttpContent httpContent, CancellationToken sb.Append(contentDisposition); sb.Append('\t'); - var content = await GetContent(innerContent, cancellationToken); + var content = await GetContent(innerContent, cancellationToken).ConfigureAwait(false); if (!string.IsNullOrEmpty(contentDisposition?.FileName)) { @@ -176,8 +173,8 @@ private async Task GetContent(HttpContent httpContent, CancellationToken if (httpContent is StreamContent streamHttpContent) { - await httpContent.LoadIntoBufferAsync(); - var streamContent = await streamHttpContent.ReadAsStreamAsync(cancellationToken); + await httpContent.LoadIntoBufferAsync().ConfigureAwait(false); + var streamContent = await streamHttpContent.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); if (streamContent.CanSeek) { @@ -188,7 +185,7 @@ private async Task GetContent(HttpContent httpContent, CancellationToken ); var stringContent = await reader.ReadToEndAsync( cancellationToken - ); + ).ConfigureAwait(false); streamContent.Seek(0, SeekOrigin.Begin); @@ -196,7 +193,7 @@ private async Task GetContent(HttpContent httpContent, CancellationToken } } - return await httpContent.ReadAsStringAsync(cancellationToken); + return await httpContent.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); } } } diff --git a/tests/PayPal.Sdk.Checkout.Test/Orders/OrdersCreateTest.cs b/tests/PayPal.Sdk.Checkout.Test/Orders/OrdersCreateTest.cs index 95ced1c8..ff56318f 100644 --- a/tests/PayPal.Sdk.Checkout.Test/Orders/OrdersCreateTest.cs +++ b/tests/PayPal.Sdk.Checkout.Test/Orders/OrdersCreateTest.cs @@ -13,36 +13,31 @@ namespace PayPal.Sdk.Checkout.Test.Orders; [Collection("Orders")] -public class OrdersCreateTest +public class OrdersCreateTest( + ITestOutputHelper testOutputHelper +) { - private readonly ITestOutputHelper _testOutputHelper; - - public OrdersCreateTest(ITestOutputHelper testOutputHelper) - { - _testOutputHelper = testOutputHelper; - } - private static OrderRequest BuildRequestBody() { var order = new OrderRequest { CheckoutPaymentIntent = EOrderIntent.Capture, - PurchaseUnits = new PurchaseUnitRequest[] - { + PurchaseUnits = + [ new() { ReferenceId = "test_ref_id1", AmountWithBreakdown = new AmountWithBreakdown { CurrencyCode = "USD", - Value = "100.00" - } - } - }, + Value = "100.00", + }, + }, + ], ApplicationContext = new ApplicationContext { ReturnUrl = "https://www.example.com", - CancelUrl = "https://www.example.com" + CancelUrl = "https://www.example.com", }, }; return order; @@ -54,7 +49,7 @@ public static async Task> CreateOrder(IPayPalHttpClie { request.SetPreferReturn(EPreferReturn.Representation); request.SetRequestBody(BuildRequestBody()); - }); + }).ConfigureAwait(false); return response; } @@ -88,13 +83,13 @@ public async Task TestOrdersCreateRequest() Assert.NotNull(createdOrder.Links); - Assert.Contains(createdOrder.Links, x => x.Rel == "approve"); - var approveUrl = createdOrder.Links.First(x => x.Rel == "approve"); + Assert.Contains(createdOrder.Links, x => string.Equals(x.Rel, "approve", System.StringComparison.Ordinal)); + var approveUrl = createdOrder.Links.First(x => string.Equals(x.Rel, "approve", System.StringComparison.Ordinal)); Assert.NotNull(approveUrl.Href); Assert.Equal(EHttpMethod.Get, approveUrl.Method); - _testOutputHelper.WriteLine("OrderId: {0}", createdOrder.Id); - _testOutputHelper.WriteLine("ApproveUrl: {0}", approveUrl.Href); + testOutputHelper.WriteLine("OrderId: {0}", createdOrder.Id); + testOutputHelper.WriteLine("ApproveUrl: {0}", approveUrl.Href); Assert.Equal(EOrderStatus.Created, createdOrder.Status); } diff --git a/tests/PayPal.Sdk.Checkout.Test/Orders/OrdersGetTest.cs b/tests/PayPal.Sdk.Checkout.Test/Orders/OrdersGetTest.cs index a4406a49..f1718a6d 100644 --- a/tests/PayPal.Sdk.Checkout.Test/Orders/OrdersGetTest.cs +++ b/tests/PayPal.Sdk.Checkout.Test/Orders/OrdersGetTest.cs @@ -9,15 +9,10 @@ namespace PayPal.Sdk.Checkout.Test.Orders; [Collection("Orders")] -public class OrdersGetTest +public class OrdersGetTest( + ITestOutputHelper testOutputHelper +) { - private readonly ITestOutputHelper _testOutputHelper; - - public OrdersGetTest(ITestOutputHelper testOutputHelper) - { - _testOutputHelper = testOutputHelper; - } - [Fact] public async Task TestOrdersGetRequest() { @@ -47,7 +42,7 @@ public async Task TestOrdersGetRequest() foreach (var purchaseUnit in retrievedOrder.PurchaseUnits) { - var createdOrderPurchaseUnit = Assert.Single(createdOrder.PurchaseUnits, x => x.ReferenceId == purchaseUnit.ReferenceId); + var createdOrderPurchaseUnit = Assert.Single(createdOrder.PurchaseUnits, x => string.Equals(x.ReferenceId, purchaseUnit.ReferenceId, System.StringComparison.Ordinal)); Assert.Equal(purchaseUnit.ReferenceId, createdOrderPurchaseUnit.ReferenceId); Assert.Equal(purchaseUnit.AmountWithBreakdown.CurrencyCode, createdOrderPurchaseUnit.AmountWithBreakdown.CurrencyCode); @@ -60,16 +55,16 @@ public async Task TestOrdersGetRequest() var foundApproveUrl = false; foreach (var linkDescription in createdOrder.Links) { - if (linkDescription.Rel == "approve") + if (string.Equals(linkDescription.Rel, "approve", System.StringComparison.Ordinal)) { foundApproveUrl = true; Assert.NotNull(linkDescription.Href); Assert.Equal(EHttpMethod.Get, linkDescription.Method); - _testOutputHelper.WriteLine(linkDescription.Href); + testOutputHelper.WriteLine(linkDescription.Href); } } - _testOutputHelper.WriteLine(createdOrder.Id); + testOutputHelper.WriteLine(createdOrder.Id); Assert.True(foundApproveUrl); Assert.Equal(EOrderStatus.Created, createdOrder.Status); } diff --git a/tests/PayPal.Sdk.Checkout.Test/Orders/OrdersPatchTest.cs b/tests/PayPal.Sdk.Checkout.Test/Orders/OrdersPatchTest.cs index c2798c5a..1f5f978e 100644 --- a/tests/PayPal.Sdk.Checkout.Test/Orders/OrdersPatchTest.cs +++ b/tests/PayPal.Sdk.Checkout.Test/Orders/OrdersPatchTest.cs @@ -14,15 +14,15 @@ public class OrdersPatchTest { private IReadOnlyCollection BuildRequestBody() { - return new StringPatch[] - { + return + [ new() { Op = "add", Path = "/purchase_units/@reference_id=='test_ref_id1'/description", - Value = "added_description" - } - }; + Value = "added_description", + }, + ]; } [Fact] diff --git a/tests/PayPal.Sdk.Checkout.Test/Orders/OrdersValidateTest.cs b/tests/PayPal.Sdk.Checkout.Test/Orders/OrdersValidateTest.cs index a996be60..d100de7b 100644 --- a/tests/PayPal.Sdk.Checkout.Test/Orders/OrdersValidateTest.cs +++ b/tests/PayPal.Sdk.Checkout.Test/Orders/OrdersValidateTest.cs @@ -34,7 +34,7 @@ public async Task TestOrdersValidateRequest() { Card = new Card(), Token = new Token(), - } + }, }); } ); diff --git a/tests/PayPal.Sdk.Checkout.Test/PayPal.Sdk.Checkout.Test.csproj b/tests/PayPal.Sdk.Checkout.Test/PayPal.Sdk.Checkout.Test.csproj index 92b87f92..c8b21ddb 100644 --- a/tests/PayPal.Sdk.Checkout.Test/PayPal.Sdk.Checkout.Test.csproj +++ b/tests/PayPal.Sdk.Checkout.Test/PayPal.Sdk.Checkout.Test.csproj @@ -1,7 +1,7 @@ - net8.0 + net8.0 12.0 enable false @@ -13,6 +13,7 @@ +