From ee844d769e80b3b3a6fb55b08302c2dd46d4e8bb Mon Sep 17 00:00:00 2001 From: Mauro Servienti Date: Fri, 13 Feb 2026 08:56:48 +0100 Subject: [PATCH] Add a test to validate generic event handlers work with contract-less composition handlers and composition over controllers --- ...on_over_controllers_get_with_2_handlers.cs | 68 ++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/src/ServiceComposer.AspNetCore.Tests/CompositionHandlers/When_using_composition_over_controllers_get_with_2_handlers.cs b/src/ServiceComposer.AspNetCore.Tests/CompositionHandlers/When_using_composition_over_controllers_get_with_2_handlers.cs index 41dc61ba..128ea31f 100644 --- a/src/ServiceComposer.AspNetCore.Tests/CompositionHandlers/When_using_composition_over_controllers_get_with_2_handlers.cs +++ b/src/ServiceComposer.AspNetCore.Tests/CompositionHandlers/When_using_composition_over_controllers_get_with_2_handlers.cs @@ -29,6 +29,12 @@ public class Model { [FromRoute]public int id { get; set; } } + + public record AnEvent + { + + } + public class CaseInsensitiveRouteTestGetIntegerCompositionHandler(IHttpContextAccessor httpContextAccessor) { [HttpGet("/api/compositionovercontrollerusingcompositionhandlers/{id}")] @@ -58,8 +64,20 @@ public class TestGetStringCompositionHandler(IHttpContextAccessor httpContextAcc [HttpGet("/api/CompositionOverControllerUsingCompositionHandlers/{id}")] public Task Handle() { - var vm = httpContextAccessor.HttpContext.Request.GetComposedResponseModel(); + var request = httpContextAccessor.HttpContext!.Request; + var vm = request.GetComposedResponseModel(); vm.AString = "sample"; + + return request.GetCompositionContext().RaiseEvent(new AnEvent()); + } + } + + public class AnEventSubscriber : ICompositionEventsHandler + { + public Task Handle(AnEvent @event, HttpRequest request) + { + var vm = request.GetComposedResponseModel(); + vm.HandledAnEvent = true; return Task.CompletedTask; } } @@ -109,6 +127,54 @@ public async Task Returns_expected_response() Assert.Equal("sample", responseObj?.SelectToken("AString")?.Value()); Assert.Equal(1, responseObj?.SelectToken("ANumber")?.Value()); } + + [Fact] + public async Task Returns_expected_response_handling_anEvent() + { + // Arrange + var client = new SelfContainedWebApplicationFactoryWithWebHost + ( + configureServices: services => + { + services.AddViewModelComposition(options => + { + options.AssemblyScanner.Disable(); + options.RegisterCompositionHandler(); + options.RegisterCompositionHandler(); + options.RegisterCompositionHandler(); + options.RegisterCompositionHandler(); + options.RegisterCompositionHandler(); + options.EnableCompositionOverControllers(); + }); + services.AddHttpContextAccessor(); + services.AddRouting(); + services.AddControllers() + .AddNewtonsoftJson(); + }, + configure: app => + { + app.UseRouting(); + app.UseEndpoints(builder => + { + builder.MapControllers(); + builder.MapCompositionHandlers(); + }); + } + ).CreateClient(); + + // Act + var response = await client.GetAsync("/api/compositionovercontrollerusingcompositionhandlers/1"); + + // Assert + Assert.True(response.IsSuccessStatusCode); + + var responseString = await response.Content.ReadAsStringAsync(); + var responseObj = JObject.Parse(responseString); + + Assert.True(responseObj.SelectToken("HandledAnEvent")?.Value()); + Assert.Equal("sample", responseObj?.SelectToken("AString")?.Value()); + Assert.Equal(1, responseObj?.SelectToken("ANumber")?.Value()); + } [Fact] public async Task Returns_expected_response_with_case_insensitive_routes()