// Copyright (c) The Geekeey Authors // SPDX-License-Identifier: EUPL-1.2 using Microsoft.Extensions.DependencyInjection; namespace Geekeey.Request.Dispatcher.Tests; internal sealed class StreamBehaviourTests { [Test] public async Task I_can_execute_the_closed_behaviour() { var sc = new ServiceCollection(); sc.AddSingleton(); sc.AddRequestDispatcher(builder => builder .Add(typeof(StreamTestHandler)) .Add(typeof(StreamTestBehavior))); var provider = sc.BuildServiceProvider(); var dispatcher = provider.GetRequiredService(); var tracker = provider.GetRequiredService(); var request = new StreamTestRequest { Value = "Hello" }; var results = await dispatcher.DispatchAsync(request).ToListAsync(); await Assert.That(results).IsEquivalentTo(["Hello-Handled-0", "Hello-Handled-1"]); await Assert.That(tracker.Executed).IsTrue(); } [Test] public async Task I_can_execute_the_open_behaviour() { var sc = new ServiceCollection(); sc.AddSingleton(); sc.AddRequestDispatcher(builder => builder .Add(typeof(StreamTestHandler)) .Add(typeof(StreamOpenBehavior<,>))); var provider = sc.BuildServiceProvider(); var dispatcher = provider.GetRequiredService(); var tracker = provider.GetRequiredService(); var request = new StreamTestRequest { Value = "Hello" }; var results = await dispatcher.DispatchAsync(request).ToListAsync(); await Assert.That(results).IsEquivalentTo(["Hello-Handled-0", "Hello-Handled-1"]); await Assert.That(tracker.Executed).IsTrue(); } [Test] public async Task I_can_chain_the_behaviours_in_order() { var sc = new ServiceCollection(); sc.AddSingleton(); sc.AddRequestDispatcher(builder => builder .Add(typeof(StreamTestHandler)) .Add(typeof(StreamChainedBehaviour1)) .Add(typeof(StreamChainedBehaviour2))); var provider = sc.BuildServiceProvider(); var dispatcher = provider.GetRequiredService(); var tracker = provider.GetRequiredService(); var request = new StreamTestRequest { Value = "Hello" }; await dispatcher.DispatchAsync(request).ToListAsync(); 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_order_behaviours_explicitly_by_order_property() { var sc = new ServiceCollection(); sc.AddSingleton(); sc.AddRequestDispatcher(builder => builder .Add(typeof(StreamTestHandler)) .AddBehavior(2) .AddBehavior(1)); var provider = sc.BuildServiceProvider(); var dispatcher = provider.GetRequiredService(); var tracker = provider.GetRequiredService(); var request = new StreamTestRequest { Value = "Hello" }; await dispatcher.DispatchAsync(request).ToListAsync(); // Registered A (order 2) then B (order 1) via AddBehavior; explicit order overrides discovery order. await Assert.That(tracker.Log).IsEquivalentTo(["OrderedB", "OrderedA"]); } [Test] public async Task I_can_work_with_a_generic_wrapper_request_and_the_open_behaviour() { var sc = new ServiceCollection(); sc.AddSingleton(); sc.AddRequestDispatcher(builder => builder .Add(typeof(StreamTestWrapperHandler<>)) .Add(typeof(StreamWrapperBehavior<>))); var provider = sc.BuildServiceProvider(); var dispatcher = provider.GetRequiredService(); var tracker = provider.GetRequiredService(); var request = new StreamTestWrapperRequest { Item = 42 }; var results = await dispatcher.DispatchAsync(request).ToListAsync(); await Assert.That(results).IsEquivalentTo(["Handled-42-0", "Handled-42-1"]); 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(); sc.AddRequestDispatcher(builder => builder .Add(typeof(StreamTestHandler)) .Add(typeof(StreamOrderingOpenBehavior<,>)) .Add(typeof(StreamOrderingClosedBehavior))); var provider = sc.BuildServiceProvider(); var dispatcher = provider.GetRequiredService(); var tracker = provider.GetRequiredService(); var request = new StreamTestRequest { Value = "Order" }; await dispatcher.DispatchAsync(request).ToListAsync(); var log = tracker.Log.ToList(); await Assert.That(log).Contains("Open"); await Assert.That(log).Contains("Closed"); } } // Moved to _fixtures