Some checks failed
default / dotnet-default-workflow (push) Failing after 1m52s
Add a simple in memory dispatcher for scalar requests and stream request.
206 lines
No EOL
7.1 KiB
C#
206 lines
No EOL
7.1 KiB
C#
// Copyright (c) The Geekeey Authors
|
|
// SPDX-License-Identifier: EUPL-1.2
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
namespace Geekeey.Request.Tests;
|
|
|
|
internal sealed class ScalarBehaviourTests
|
|
{
|
|
[Test]
|
|
public async Task I_can_execute_the_closed_behaviour()
|
|
{
|
|
var sc = new ServiceCollection();
|
|
sc.AddSingleton<ScalarTestTracker>();
|
|
sc.AddRequestDispatcher(builder => builder
|
|
.Add(typeof(ScalarTestHandler))
|
|
.Add(typeof(ScalarTestBehavior)));
|
|
var provider = sc.BuildServiceProvider();
|
|
var dispatcher = provider.GetRequiredService<IRequestDispatcher>();
|
|
var tracker = provider.GetRequiredService<ScalarTestTracker>();
|
|
|
|
var request = new ScalarTestRequest { Value = "Hello" };
|
|
var result = await dispatcher.DispatchAsync(request);
|
|
|
|
await Assert.That(result).IsEquivalentTo("Hello-Handled");
|
|
await Assert.That(tracker.Executed).IsTrue();
|
|
}
|
|
|
|
[Test]
|
|
public async Task I_can_execute_the_open_behaviour()
|
|
{
|
|
var sc = new ServiceCollection();
|
|
sc.AddSingleton<ScalarTestTracker>();
|
|
sc.AddRequestDispatcher(builder => builder
|
|
.Add(typeof(ScalarTestHandler))
|
|
.Add(typeof(ScalarOpenBehavior<,>)));
|
|
var provider = sc.BuildServiceProvider();
|
|
var dispatcher = provider.GetRequiredService<IRequestDispatcher>();
|
|
var tracker = provider.GetRequiredService<ScalarTestTracker>();
|
|
|
|
var request = new ScalarTestRequest { Value = "Hello" };
|
|
var result = await dispatcher.DispatchAsync(request);
|
|
|
|
await Assert.That(result).IsEquivalentTo("Hello-Handled");
|
|
await Assert.That(tracker.Executed).IsTrue();
|
|
}
|
|
|
|
[Test]
|
|
public async Task I_can_chain_the_behaviours_in_order()
|
|
{
|
|
var sc = new ServiceCollection();
|
|
sc.AddSingleton<ScalarTestTracker>();
|
|
sc.AddRequestDispatcher(builder => builder
|
|
.Add(typeof(ScalarTestHandler))
|
|
.Add(typeof(ScalarChainedBehaviour1))
|
|
.Add(typeof(ScalarChainedBehaviour2)));
|
|
var provider = sc.BuildServiceProvider();
|
|
var dispatcher = provider.GetRequiredService<IRequestDispatcher>();
|
|
var tracker = provider.GetRequiredService<ScalarTestTracker>();
|
|
|
|
var request = new ScalarTestRequest { Value = "Hello" };
|
|
await dispatcher.DispatchAsync(request);
|
|
|
|
// They are discovered in the order they appear in the assembly.
|
|
// In this file: ChainedBehaviour1, ChainedBehaviour2
|
|
await Assert.That(tracker.Log).Count().IsEqualTo(2);
|
|
await Assert.That(tracker.Log[0]).IsEquivalentTo("Behaviour1");
|
|
await Assert.That(tracker.Log[1]).IsEquivalentTo("Behaviour2");
|
|
}
|
|
|
|
[Test]
|
|
public async Task I_can_work_with_a_generic_wrapper_request_and_the_open_behaviour()
|
|
{
|
|
var sc = new ServiceCollection();
|
|
sc.AddSingleton<ScalarTestTracker>();
|
|
sc.AddRequestDispatcher(builder => builder
|
|
.Add(typeof(ScalarTestWrapperHandler<>))
|
|
.Add(typeof(ScalarWrapperBehavior<>)));
|
|
var provider = sc.BuildServiceProvider();
|
|
var dispatcher = provider.GetRequiredService<IRequestDispatcher>();
|
|
var tracker = provider.GetRequiredService<ScalarTestTracker>();
|
|
|
|
var request = new ScalarTestWrapperRequest<int> { Item = 42 };
|
|
var result = await dispatcher.DispatchAsync(request);
|
|
|
|
await Assert.That(result).IsEquivalentTo("Handled-42");
|
|
await Assert.That(tracker.Executed).IsTrue();
|
|
}
|
|
|
|
[Test]
|
|
public async Task I_can_maintain_the_ordering_between_open_and_closed_behaviours()
|
|
{
|
|
var sc = new ServiceCollection();
|
|
sc.AddSingleton<ScalarTestTracker>();
|
|
sc.AddRequestDispatcher(builder => builder
|
|
.Add(typeof(ScalarTestHandler))
|
|
.Add(typeof(ScalarOrderingOpenBehavior<,>))
|
|
.Add(typeof(ScalarOrderingClosedBehavior)));
|
|
var provider = sc.BuildServiceProvider();
|
|
var dispatcher = provider.GetRequiredService<IRequestDispatcher>();
|
|
var tracker = provider.GetRequiredService<ScalarTestTracker>();
|
|
|
|
var request = new ScalarTestRequest { Value = "Order" };
|
|
await dispatcher.DispatchAsync(request);
|
|
|
|
await Assert.That(tracker.Log).Contains("OrderingOpen");
|
|
await Assert.That(tracker.Log).Contains("OrderingClosed");
|
|
}
|
|
}
|
|
|
|
public class ScalarTestTracker
|
|
{
|
|
public List<string> Log { get; } = [];
|
|
public bool Executed { get; set; }
|
|
}
|
|
|
|
public class ScalarOrderingOpenBehavior<TRequest, TOutput>(ScalarTestTracker tracker) : IScalarRequestBehavior<TRequest, TOutput>
|
|
where TRequest : IScalarRequest<TOutput>
|
|
{
|
|
public Task<TOutput> HandleAsync(TRequest request, ScalarHandlerDelegate<TOutput> next, CancellationToken cancellationToken)
|
|
{
|
|
tracker.Log.Add("OrderingOpen");
|
|
return next(request, cancellationToken);
|
|
}
|
|
}
|
|
|
|
public class ScalarOrderingClosedBehavior(ScalarTestTracker tracker) : IScalarRequestBehavior<ScalarTestRequest, string>
|
|
{
|
|
public Task<string> HandleAsync(ScalarTestRequest request, ScalarHandlerDelegate<string> next, CancellationToken cancellationToken)
|
|
{
|
|
tracker.Log.Add("OrderingClosed");
|
|
return next(request, cancellationToken);
|
|
}
|
|
}
|
|
|
|
public class ScalarTestRequest : IScalarRequest<string>
|
|
{
|
|
public string Value { get; set; } = string.Empty;
|
|
}
|
|
|
|
public class ScalarTestHandler : IScalarRequestHandler<ScalarTestRequest, string>
|
|
{
|
|
public Task<string> HandleAsync(ScalarTestRequest request, CancellationToken cancellationToken)
|
|
{
|
|
return Task.FromResult($"{request.Value}-Handled");
|
|
}
|
|
}
|
|
|
|
public class ScalarTestBehavior(ScalarTestTracker tracker) : IScalarRequestBehavior<ScalarTestRequest, string>
|
|
{
|
|
public async Task<string> HandleAsync(ScalarTestRequest request, ScalarHandlerDelegate<string> next, CancellationToken cancellationToken)
|
|
{
|
|
tracker.Executed = true;
|
|
return await next(request, cancellationToken);
|
|
}
|
|
}
|
|
|
|
public class ScalarOpenBehavior<TRequest, TResponse>(ScalarTestTracker tracker) : IScalarRequestBehavior<TRequest, TResponse>
|
|
where TRequest : IScalarRequest<TResponse>
|
|
{
|
|
public async Task<TResponse> HandleAsync(TRequest request, ScalarHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
|
|
{
|
|
tracker.Executed = true;
|
|
return await next(request, cancellationToken);
|
|
}
|
|
}
|
|
|
|
public class ScalarChainedBehaviour1(ScalarTestTracker tracker) : IScalarRequestBehavior<ScalarTestRequest, string>
|
|
{
|
|
public async Task<string> HandleAsync(ScalarTestRequest request, ScalarHandlerDelegate<string> next, CancellationToken cancellationToken)
|
|
{
|
|
tracker.Log.Add("Behaviour1");
|
|
return await next(request, cancellationToken);
|
|
}
|
|
}
|
|
|
|
public class ScalarChainedBehaviour2(ScalarTestTracker tracker) : IScalarRequestBehavior<ScalarTestRequest, string>
|
|
{
|
|
public async Task<string> HandleAsync(ScalarTestRequest request, ScalarHandlerDelegate<string> next, CancellationToken cancellationToken)
|
|
{
|
|
tracker.Log.Add("Behaviour2");
|
|
return await next(request, cancellationToken);
|
|
}
|
|
}
|
|
|
|
public class ScalarTestWrapperRequest<T> : IScalarRequest<string>
|
|
{
|
|
public T Item { get; set; } = default!;
|
|
}
|
|
|
|
public class ScalarTestWrapperHandler<T> : IScalarRequestHandler<ScalarTestWrapperRequest<T>, string>
|
|
{
|
|
public Task<string> HandleAsync(ScalarTestWrapperRequest<T> request, CancellationToken cancellationToken)
|
|
{
|
|
return Task.FromResult($"Handled-{request.Item}");
|
|
}
|
|
}
|
|
|
|
public class ScalarWrapperBehavior<T>(ScalarTestTracker tracker) : IScalarRequestBehavior<ScalarTestWrapperRequest<T>, string>
|
|
{
|
|
public async Task<string> HandleAsync(ScalarTestWrapperRequest<T> request, ScalarHandlerDelegate<string> next, CancellationToken cancellationToken)
|
|
{
|
|
tracker.Executed = true;
|
|
return await next(request, cancellationToken);
|
|
}
|
|
} |