Skip to content

Commit 19f01ec

Browse files
authored
Tests (#32)
* - add tests for ServiceEndpointWithStreamingResponse endpoint types - add unit tests for ModEndpoints.RemoteServices package * - add RemoteServices integration tests - code cleanup * - remove Clear method from ServiceChannelRegistry in RemoteServices package - organize tests accrodingly * - remove successful test cases from DefaultServiceChannel unit tests, leave it to integration tests - remove integrals visible to directive from ModEndpoints.RemoteServices project since it's no longer needed * - remove unused code * - update sample project dependencies to latest * - update readme files
1 parent 14c8174 commit 19f01ec

File tree

17 files changed

+785
-7
lines changed

17 files changed

+785
-7
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ For more examples, refer to the following:
252252
- `BusinessResultEndpoint` samples are in [Stores](./samples/ShowcaseWebApi/Features/Stores) subfolder,
253253
- `ServiceEndpoint` samples are in [StoresWithServiceEndpoint](./samples/ShowcaseWebApi/Features/StoresWithServiceEndpoint) subfolder.
254254

255-
[ServiceEndpointClient](./samples/ServiceEndpointClient) project demonstrates how to consume ServiceEndpoints.
255+
[ServiceEndpointClient](./samples/ServiceEndpointClient) project demonstrates a client application consuming remote ServiceEndpoints.
256256

257257
[WeatherForecastWebApi](./samples/WeatherForecastWebApi) project demonstrates how GetWeatherForecast Minimal API in ASP.NET Core Web API project template can be written using MinimalEndpoints. Also demostrates API documentation with Scalar and OpenAPI.
258258

samples/ShowcaseWebApi/ShowcaseWebApi.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<ItemGroup>
88
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="9.0.5" />
9-
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.1" />
9+
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.2" />
1010
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="12.0.0" />
1111
<PackageReference Include="Asp.Versioning.Http" Version="8.1.0" />
1212
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.1.0" />

samples/WeatherForecastWebApi/WeatherForecastWebApi.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
<ItemGroup>
1010
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.5" />
11-
<PackageReference Include="Scalar.AspNetCore" Version="2.3.1" />
11+
<PackageReference Include="Scalar.AspNetCore" Version="2.4.7" />
1212
</ItemGroup>
1313

1414
<ItemGroup>

src/ModEndpoints.Core/assets/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Also contains base classes for endpoints implemented in ModEndpoints project.
66

77
## ✨ Features
88

9-
- **REPR Pattern Implementation**: Organizes Minimal APIs into Request, Endpoint, Processor, and Response components.
9+
- **REPR Pattern Implementation**: Organizes Minimal APIs into Request, Endpoint and Response components.
1010
- **Seamless Integration**: Fully compatible with ASP.NET Core Minimal APIs, supporting configurations, parameter binding, authentication, OpenAPI tooling, filters, and more.
1111
- **Auto-Discovery and Registration**: Automatically discovers and registers endpoints.
1212
- **FluentValidation Support**: Built-in validation using FluentValidation; requests are automatically validated if a validator is registered.

src/ModEndpoints.RemoteServices/ModEndpoints.RemoteServices.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,5 @@
2727

2828
<ItemGroup>
2929
<ProjectReference Include="..\ModEndpoints.RemoteServices.Core\ModEndpoints.RemoteServices.Core.csproj" />
30-
</ItemGroup>
31-
30+
</ItemGroup>
3231
</Project>

src/ModEndpoints/assets/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ WebResultEndpoints, BusinessResultEndpoints, and ServiceEndpoints structure ASP.
44

55
## ✨ Features
66

7-
- **REPR Pattern Implementation**: Organizes Minimal APIs into Request, Endpoint, Processor, and Response components.
7+
- **REPR Pattern Implementation**: Organizes Minimal APIs into Request, Endpoint and Response components.
88
- **Seamless Integration**: Fully compatible with ASP.NET Core Minimal APIs, supporting configurations, parameter binding, authentication, OpenAPI tooling, filters, and more.
99
- **Auto-Discovery and Registration**: Automatically discovers and registers endpoints.
1010
- **FluentValidation Support**: Built-in validation using FluentValidation; requests are automatically validated if a validator is registered.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using System.Runtime.CompilerServices;
2+
using FluentValidation;
3+
using ModEndpoints.Core;
4+
using ModEndpoints.RemoteServices;
5+
using ModEndpoints.RemoteServices.Core;
6+
using ModEndpoints.TestServer.Features.StoresWithServiceEndpoint.Configuration;
7+
8+
namespace ModEndpoints.TestServer.Features.StoresWithServiceEndpoint;
9+
10+
public record FilterAndStreamStoreListRequest(string Name)
11+
: IServiceRequestWithStreamingResponse<FilterAndStreamStoreListResponse>;
12+
13+
public record FilterAndStreamStoreListResponse(
14+
Guid Id,
15+
string Name);
16+
17+
internal class FilterAndStreamStoreListRequestValidator : AbstractValidator<FilterAndStreamStoreListRequest>
18+
{
19+
public FilterAndStreamStoreListRequestValidator()
20+
{
21+
RuleFor(x => x.Name).NotEmpty();
22+
}
23+
}
24+
25+
[MapToGroup<StoresWithServiceEndpointRouteGroup>()]
26+
internal class FilterAndStreamStoreList
27+
: ServiceEndpointWithStreamingResponse<FilterAndStreamStoreListRequest, FilterAndStreamStoreListResponse>
28+
{
29+
protected override async IAsyncEnumerable<StreamingResponseItem<FilterAndStreamStoreListResponse>> HandleAsync(
30+
FilterAndStreamStoreListRequest req,
31+
[EnumeratorCancellation] CancellationToken ct)
32+
{
33+
List<FilterAndStreamStoreListResponse> stores =
34+
[
35+
new FilterAndStreamStoreListResponse(
36+
Id: Guid.NewGuid(),
37+
Name: "Name 1"),
38+
new FilterAndStreamStoreListResponse(
39+
Id: Guid.NewGuid(),
40+
Name: "Name 2")
41+
];
42+
43+
foreach (var store in stores.Where(c => c.Name == req.Name))
44+
{
45+
yield return new StreamingResponseItem<FilterAndStreamStoreListResponse>(store);
46+
await Task.Delay(1000, ct); // Simulate async work
47+
}
48+
}
49+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.Runtime.CompilerServices;
2+
using FluentValidation;
3+
using ModEndpoints.Core;
4+
using ModEndpoints.RemoteServices;
5+
using ModEndpoints.RemoteServices.Core;
6+
using ModEndpoints.TestServer.Features.StoresWithServiceEndpoint.Configuration;
7+
using ModResults;
8+
9+
namespace ModEndpoints.TestServer.Features.StoresWithServiceEndpoint;
10+
11+
public record StreamStoreStatusListRequest(string Name) : IServiceRequestWithStreamingResponse;
12+
13+
internal class StreamStoreStatusListRequestValidator
14+
: AbstractValidator<StreamStoreStatusListRequest>
15+
{
16+
public StreamStoreStatusListRequestValidator()
17+
{
18+
RuleFor(x => x.Name).NotEmpty();
19+
}
20+
}
21+
22+
[MapToGroup<StoresWithServiceEndpointRouteGroup>()]
23+
internal class StreamStoreStatusList
24+
: ServiceEndpointWithStreamingResponse<StreamStoreStatusListRequest>
25+
{
26+
protected override async IAsyncEnumerable<StreamingResponseItem> HandleAsync(
27+
StreamStoreStatusListRequest req,
28+
[EnumeratorCancellation] CancellationToken ct)
29+
{
30+
for (int i = 0; i < 2; i++)
31+
{
32+
yield return new StreamingResponseItem(Result.Ok());
33+
await Task.Delay(1000, ct); // Simulate async work
34+
}
35+
}
36+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System.Runtime.CompilerServices;
2+
3+
namespace ModEndpoints.Tests;
4+
5+
internal static class HttpClientHelpers
6+
{
7+
internal static HttpClientHandler GetHandler(this HttpClient source)
8+
{
9+
return Unsafe.As<HttpClientHandler>(get_handler(source))
10+
;
11+
}
12+
13+
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_handler")]
14+
private extern static ref HttpMessageHandler get_handler(HttpMessageInvoker obj);
15+
}

tests/ModEndpoints.Tests/ModEndpoints.Tests.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
</PackageReference>
1717
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.16" />
1818
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.0" />
19+
<PackageReference Include="NSubstitute" Version="5.3.0" />
20+
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
1921
<PackageReference Include="xunit" Version="2.9.3" />
2022
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.0">
2123
<PrivateAssets>all</PrivateAssets>

0 commit comments

Comments
 (0)