Skip to content

Commit

Permalink
fix: add unit test to verify correct content disposal behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
nozzlegear committed Jan 17, 2025
1 parent fff02a7 commit ba4d653
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 1 deletion.
73 changes: 72 additions & 1 deletion ShopifySharp.Tests/Services/ShopifyServiceTests.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,32 @@
#nullable enable
using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using FakeItEasy;
using FluentAssertions;
using JetBrains.Annotations;
using ShopifySharp.Infrastructure;
using ShopifySharp.Infrastructure.Policies.ExponentialRetry;
using ShopifySharp.Tests.TestClasses;
using Xunit;

namespace ShopifySharp.Tests.Services;

[Trait("Category", "ShopifyService")]
[Trait("Category", "ShopifyService"), Trait("Category", "DotNetFramework")]
[TestSubject(typeof(ShopifyService))]
public class ShopifyServiceTests
{
public static HttpMethod[] MakeHttpMethodList() => [HttpMethod.Get, HttpMethod.Post, HttpMethod.Put, HttpMethod.Delete, HttpMethod.Head];

public static Func<IRequestExecutionPolicy>[] MakeFakedExecutionPoliciesList() =>
[
() => A.Fake<IRequestExecutionPolicy>(x => x.Wrapping(new DefaultRequestExecutionPolicy())),
() => A.Fake<IRequestExecutionPolicy>(x => x.Wrapping(new RetryExecutionPolicy())),
() => A.Fake<IRequestExecutionPolicy>(x => x.Wrapping(new LeakyBucketExecutionPolicy())),
() => A.Fake<IRequestExecutionPolicy>(x => x.Wrapping(new ExponentialRetryPolicy(ExponentialRetryPolicyOptions.Default())))
];

#region PrepareRequest(string path) and BuildRequestUri

[Fact]
Expand All @@ -27,4 +44,58 @@ public void BuildRequestUri_ShouldReturnOverridenUri()
}

#endregion

#region internal ExecuteRequestCoreAsync

[Theory]
[CombinatorialData]
public async Task Internal_ExecuteRequestCoreAsync_WhenRunningTheExecutionPolicy_ShouldNotDisposeTheBaseRequestMessageContent(
[CombinatorialMemberData(nameof(MakeHttpMethodList))] HttpMethod httpMethod,
[CombinatorialMemberData(nameof(MakeFakedExecutionPoliciesList))] Func<IRequestExecutionPolicy> makePolicy
)
{
// Setup
var sut = new TestShopifyServiceWithExposedExecuteRequestCoreAsync();
var handler = A.Fake<HttpMessageHandler>();
var content = A.Fake<HttpContent>(x => x.Wrapping(new StringContent("""{"foo":"bar"}""")));
var policy = makePolicy();

sut.SetExecutionPolicy(policy);
sut.SetHttpClient(new HttpClient(handler));

var callToHandler = A.CallTo(handler)
.WithReturnType<Task<HttpResponseMessage>>()
.Where(call => call.Method.Name == "SendAsync");
var callToPolicy = A.CallTo(policy)
.WithReturnType<Task<RequestResult<string>>>()
.Where(call => call.Method.Name == "Run");
var callToDisposeContent = A.CallTo(content)
.WithVoidReturnType()
.Where(call => call.Method.Name == "Dispose");

callToHandler.ReturnsLazily(() => new HttpResponseMessage
{
Content = new JsonContent(new { products = true }),
StatusCode = HttpStatusCode.OK
});

// Act
var act = async () => await sut.ExecuteRequestCoreAsync(
new RequestUri(new Uri("https://example.com")),
httpMethod,
content,
[],
null);

// Assert
var result = await act.Should().NotThrowAsync();

result.Subject.Result.Should().Be("""{"products":true}""");

callToPolicy.MustHaveHappenedOnceExactly();
callToHandler.MustHaveHappenedOnceExactly();
callToDisposeContent.MustHaveHappenedOnceExactly();
}

#endregion
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Collections.Generic;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using ShopifySharp.Infrastructure;

namespace ShopifySharp.Tests.TestClasses;

public class TestShopifyServiceWithExposedExecuteRequestCoreAsync()
: ShopifyService("some-shop-domain", "some-access-token")
{
public new Task<RequestResult<string>> ExecuteRequestCoreAsync(
RequestUri uri,
HttpMethod method,
HttpContent content,
Dictionary<string, string> headers,
int? graphqlQueryCost,
CancellationToken cancellationToken = default
) => base.ExecuteRequestCoreAsync(uri, method, content, headers, graphqlQueryCost, cancellationToken);
}

0 comments on commit ba4d653

Please sign in to comment.