mirror of https://github.com/abpframework/abp.git
committed by
GitHub
3 changed files with 184 additions and 12 deletions
@ -0,0 +1,157 @@ |
|||||
|
using System; |
||||
|
using System.IO; |
||||
|
using System.Net; |
||||
|
using System.Net.Http; |
||||
|
using System.Text; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.DependencyInjection.Extensions; |
||||
|
using Shouldly; |
||||
|
using Volo.Abp.AspNetCore.TestBase; |
||||
|
using Volo.Abp.Http.Client; |
||||
|
using Volo.Abp.Http.Client.Proxying; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp.Http.DynamicProxying; |
||||
|
|
||||
|
public class ClientProxyResponseDisposal_Tests : AbpHttpClientTestBase |
||||
|
{ |
||||
|
private readonly IRegularTestController _controller; |
||||
|
private readonly StubProxyHttpClientFactory _factory; |
||||
|
|
||||
|
public ClientProxyResponseDisposal_Tests() |
||||
|
{ |
||||
|
_controller = ServiceProvider.GetRequiredService<IRegularTestController>(); |
||||
|
_factory = (StubProxyHttpClientFactory)ServiceProvider.GetRequiredService<IProxyHttpClientFactory>(); |
||||
|
} |
||||
|
|
||||
|
protected override void ConfigureServices(IServiceCollection services) |
||||
|
{ |
||||
|
services.Replace(ServiceDescriptor.Singleton<IProxyHttpClientFactory, StubProxyHttpClientFactory>()); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task Non_Abp_Error_Response_Should_Dispose_HttpContent() |
||||
|
{ |
||||
|
var content = new TrackingHttpContent("Bad Gateway from upstream"); |
||||
|
_factory.SetStubResponse(() => new HttpResponseMessage(HttpStatusCode.BadGateway) |
||||
|
{ |
||||
|
Content = content |
||||
|
}); |
||||
|
|
||||
|
var exception = await Assert.ThrowsAsync<AbpRemoteCallException>( |
||||
|
() => _controller.IncrementValueAsync(1)); |
||||
|
|
||||
|
exception.HttpStatusCode.ShouldBe((int)HttpStatusCode.BadGateway); |
||||
|
content.Disposed.ShouldBeTrue(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task Successful_Response_With_Json_Return_Should_Dispose_HttpContent() |
||||
|
{ |
||||
|
var content = new TrackingHttpContent("42"); |
||||
|
_factory.SetStubResponse(() => new HttpResponseMessage(HttpStatusCode.OK) |
||||
|
{ |
||||
|
Content = content |
||||
|
}); |
||||
|
|
||||
|
var result = await _controller.IncrementValueAsync(0); |
||||
|
|
||||
|
result.ShouldBe(42); |
||||
|
content.Disposed.ShouldBeTrue(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task Successful_Response_With_Void_Return_Should_Dispose_HttpContent() |
||||
|
{ |
||||
|
var content = new TrackingHttpContent(string.Empty); |
||||
|
_factory.SetStubResponse(() => new HttpResponseMessage(HttpStatusCode.NoContent) |
||||
|
{ |
||||
|
Content = content |
||||
|
}); |
||||
|
|
||||
|
await _controller.GetException1Async(); |
||||
|
|
||||
|
content.Disposed.ShouldBeTrue(); |
||||
|
} |
||||
|
|
||||
|
class StubProxyHttpClientFactory : IProxyHttpClientFactory |
||||
|
{ |
||||
|
private readonly ITestServerAccessor _testServerAccessor; |
||||
|
|
||||
|
private int _count; |
||||
|
private Func<HttpResponseMessage> _responseFactory; |
||||
|
|
||||
|
public StubProxyHttpClientFactory(ITestServerAccessor testServerAccessor) |
||||
|
{ |
||||
|
_testServerAccessor = testServerAccessor; |
||||
|
} |
||||
|
|
||||
|
public void SetStubResponse(Func<HttpResponseMessage> responseFactory) |
||||
|
{ |
||||
|
_responseFactory = responseFactory; |
||||
|
} |
||||
|
|
||||
|
public HttpClient Create(string name) => Create(); |
||||
|
|
||||
|
public HttpClient Create() |
||||
|
{ |
||||
|
if (_count++ == 0) |
||||
|
{ |
||||
|
return _testServerAccessor.Server.CreateClient(); |
||||
|
} |
||||
|
|
||||
|
return new HttpClient(new StubHttpMessageHandler(() => |
||||
|
_responseFactory?.Invoke() |
||||
|
?? throw new InvalidOperationException("Stub response is not configured."))) |
||||
|
{ |
||||
|
BaseAddress = new Uri("http://localhost/") |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
class StubHttpMessageHandler : HttpMessageHandler |
||||
|
{ |
||||
|
private readonly Func<HttpResponseMessage> _responseFactory; |
||||
|
|
||||
|
public StubHttpMessageHandler(Func<HttpResponseMessage> responseFactory) |
||||
|
{ |
||||
|
_responseFactory = responseFactory; |
||||
|
} |
||||
|
|
||||
|
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) |
||||
|
{ |
||||
|
return Task.FromResult(_responseFactory()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
class TrackingHttpContent : HttpContent |
||||
|
{ |
||||
|
private readonly byte[] _data; |
||||
|
|
||||
|
public bool Disposed { get; private set; } |
||||
|
|
||||
|
public TrackingHttpContent(string text) |
||||
|
{ |
||||
|
_data = Encoding.UTF8.GetBytes(text); |
||||
|
} |
||||
|
|
||||
|
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) |
||||
|
{ |
||||
|
return stream.WriteAsync(_data, 0, _data.Length); |
||||
|
} |
||||
|
|
||||
|
protected override bool TryComputeLength(out long length) |
||||
|
{ |
||||
|
length = _data.Length; |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
protected override void Dispose(bool disposing) |
||||
|
{ |
||||
|
Disposed = true; |
||||
|
base.Dispose(disposing); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue