GetCookies-Methode hinzugefügt. Test für http-Dienst hinzugefügt

This commit is contained in:
Developer 02 2024-06-26 16:57:30 +02:00
parent 8d38e883df
commit d84ef820f1
6 changed files with 142 additions and 5 deletions

View File

@ -1,9 +1,13 @@
namespace DigitalData.Core.Abstractions.Client
using System.Net;
namespace DigitalData.Core.Abstractions.Client
{
public interface IBaseHttpClientService
{
public string Uri { get; init; }
public CookieCollection GetCookies(string route = "");
Task<HttpResponseMessage> FetchAsync(
string route = "",
HttpMethod? method = null,

View File

@ -8,7 +8,7 @@ namespace DigitalData.Core.Client
public class BaseHttpClientService : IBaseHttpClientService
{
protected readonly HttpClient _client;
protected readonly CookieContainer _cookies;
protected readonly CookieContainer _cookies;
[StringSyntax("Uri")]
public string Uri { get; init; }
@ -20,6 +20,8 @@ namespace DigitalData.Core.Client
Uri = clientOptions.Value.Uri;
}
public CookieCollection GetCookies(string route = "") => _cookies.GetCookies(uri: new Uri(Uri + route));
public async Task<HttpResponseMessage> FetchAsync(
string route = "",
HttpMethod? method = null,

View File

@ -17,7 +17,7 @@ namespace DigitalData.Core.Client
return services;
}
public static IServiceCollection AddHttpClientService<TClientOptions>(this IServiceCollection services, Action<TClientOptions>? clientOptions = null, bool setAsDefault = false)
public static IServiceCollection AddHttpClientService<TClientOptions>(this IServiceCollection services, Action<TClientOptions>? clientOptions = null, bool setAsDefaultBase = false)
where TClientOptions : HttpClientOptions, new()
{
services.TryAddSingleton<HttpClient>();
@ -25,7 +25,7 @@ namespace DigitalData.Core.Client
services.AddSingleton<IHttpClientService<TClientOptions>, HttpClientService<TClientOptions>>();
services.Configure(clientOptions ?? (_ => { }));
if (setAsDefault)
if (setAsDefaultBase)
services.AddSingleton<IBaseHttpClientService, HttpClientService<TClientOptions>>();
return services;

View File

@ -0,0 +1,127 @@
using DigitalData.Core.Client;
using Microsoft.Extensions.Options;
using Moq;
using Moq.Protected;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace DigitalData.Core.Tests
{
[TestFixture]
public class BaseHttpClientServiceTests
{
private Mock<HttpMessageHandler> _messageHandlerMock;
private HttpClient _httpClient;
private CookieContainer _cookieContainer;
private Mock<IOptions<HttpClientOptions>> _optionsMock;
private BaseHttpClientService _service;
[SetUp]
public void SetUp()
{
_messageHandlerMock = new Mock<HttpMessageHandler>(MockBehavior.Strict);
_httpClient = new HttpClient(_messageHandlerMock.Object);
_cookieContainer = new CookieContainer();
_optionsMock = new Mock<IOptions<HttpClientOptions>>();
_optionsMock.Setup(o => o.Value).Returns(new HttpClientOptions { Uri = "https://example.com" });
_service = new BaseHttpClientService(_httpClient, _cookieContainer, _optionsMock.Object);
}
[Test]
public void GetCookies_ShouldReturnCookies()
{
// Arrange
var uri = new Uri("https://example.com/test");
_cookieContainer.Add(uri, new Cookie("test", "value"));
// Act
var cookies = _service.GetCookies("/test");
// Assert
Assert.AreEqual(1, cookies.Count);
Assert.AreEqual("test", cookies[0].Name);
Assert.AreEqual("value", cookies[0].Value);
}
[Test]
public async Task FetchAsync_ShouldSendRequestWithMethodAndBody()
{
// Arrange
var responseMessage = new HttpResponseMessage(HttpStatusCode.OK);
_messageHandlerMock
.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>()
)
.ReturnsAsync(responseMessage);
var bodyContent = new StringContent("test body");
// Act
var response = await _service.FetchAsync("/test", HttpMethod.Post, body: bodyContent);
// Assert
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
_messageHandlerMock.Protected().Verify(
"SendAsync",
Times.Once(),
ItExpr.Is<HttpRequestMessage>(req =>
req.Method == HttpMethod.Post &&
req.RequestUri == new Uri("https://example.com/test") &&
req.Content == bodyContent),
ItExpr.IsAny<CancellationToken>()
);
}
[Test]
public async Task FetchAsync_ShouldSendRequestWithForm()
{
// Arrange
var responseMessage = new HttpResponseMessage(HttpStatusCode.OK);
_messageHandlerMock
.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>()
)
.ReturnsAsync(responseMessage);
var formData = new Dictionary<string, string> { { "key", "value" } };
// Act
var response = await _service.FetchAsync("/test", HttpMethod.Post, form: formData);
// Assert
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
_messageHandlerMock.Protected().Verify(
"SendAsync",
Times.Once(),
ItExpr.Is<HttpRequestMessage>(req =>
req.Method == HttpMethod.Post &&
req.RequestUri == new Uri("https://example.com/test") &&
req.Content.Headers.ContentType.MediaType == "application/x-www-form-urlencoded"),
ItExpr.IsAny<CancellationToken>()
);
}
[Test]
public async Task FetchAsync_ShouldThrowException_WhenBothBodyAndFormAreSet()
{
// Arrange
var bodyContent = new StringContent("test body");
var formData = new Dictionary<string, string> { { "key", "value" } };
// Act & Assert
Assert.ThrowsAsync<InvalidOperationException>(() => _service.FetchAsync("/test", HttpMethod.Post, body: bodyContent, form: formData));
}
}
}

View File

@ -20,8 +20,12 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DigitalData.Core.Abstractions\DigitalData.Core.Abstractions.csproj" />
<ProjectReference Include="..\DigitalData.Core.API\DigitalData.Core.API.csproj" />
<ProjectReference Include="..\DigitalData.Core.Application\DigitalData.Core.Application.csproj" />
<ProjectReference Include="..\DigitalData.Core.Client\DigitalData.Core.Client.csproj" />
<ProjectReference Include="..\DigitalData.Core.DTO\DigitalData.Core.DTO.csproj" />
<ProjectReference Include="..\DigitalData.Core.Infrastructure\DigitalData.Core.Infrastructure.csproj" />
</ItemGroup>
</Project>

View File

@ -19,9 +19,9 @@
<Import Project="$(NuGetPackageRoot)microsoft.testplatform.testhost\17.3.2\build\netcoreapp2.1\Microsoft.TestPlatform.TestHost.props" Condition="Exists('$(NuGetPackageRoot)microsoft.testplatform.testhost\17.3.2\build\netcoreapp2.1\Microsoft.TestPlatform.TestHost.props')" />
<Import Project="$(NuGetPackageRoot)microsoft.codecoverage\17.3.2\build\netstandard1.0\Microsoft.CodeCoverage.props" Condition="Exists('$(NuGetPackageRoot)microsoft.codecoverage\17.3.2\build\netstandard1.0\Microsoft.CodeCoverage.props')" />
<Import Project="$(NuGetPackageRoot)microsoft.net.test.sdk\17.3.2\build\netcoreapp2.1\Microsoft.NET.Test.Sdk.props" Condition="Exists('$(NuGetPackageRoot)microsoft.net.test.sdk\17.3.2\build\netcoreapp2.1\Microsoft.NET.Test.Sdk.props')" />
<Import Project="$(NuGetPackageRoot)microsoft.entityframeworkcore\7.0.16\buildTransitive\net6.0\Microsoft.EntityFrameworkCore.props" Condition="Exists('$(NuGetPackageRoot)microsoft.entityframeworkcore\7.0.16\buildTransitive\net6.0\Microsoft.EntityFrameworkCore.props')" />
</ImportGroup>
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<PkgNUnit_Analyzers Condition=" '$(PkgNUnit_Analyzers)' == '' ">C:\Users\tekh\.nuget\packages\nunit.analyzers\3.5.0</PkgNUnit_Analyzers>
<PkgNewtonsoft_Json Condition=" '$(PkgNewtonsoft_Json)' == '' ">C:\Users\tekh\.nuget\packages\newtonsoft.json\9.0.1</PkgNewtonsoft_Json>
</PropertyGroup>
</Project>