// Copyright (c) Microsoft. All rights reserved. using System; using System.Threading.Tasks; using Microsoft.Agents.Workflows.Execution; using Microsoft.Agents.Workflows.Reflection; using Moq; namespace Microsoft.Agents.Workflows.UnitTests; public class BaseTestExecutor : ReflectingExecutor where TActual : ReflectingExecutor { protected void OnInvokedHandler() { this.InvokedHandler = true; } public bool InvokedHandler { get; private set; } = false; } public class DefaultHandler : BaseTestExecutor, IMessageHandler { public ValueTask HandleAsync(object message, IWorkflowContext context) { this.OnInvokedHandler(); return this.Handler(message, context); } public Func Handler { get; set; } = (message, context) => default; } public class TypedHandler : BaseTestExecutor>, IMessageHandler { public ValueTask HandleAsync(TInput message, IWorkflowContext context) { this.OnInvokedHandler(); return this.Handler(message, context); } public Func Handler { get; set; } = (message, context) => default; } public class TypedHandlerWithOutput : BaseTestExecutor>, IMessageHandler { public ValueTask HandleAsync(TInput message, IWorkflowContext context) { this.OnInvokedHandler(); return this.Handler(message, context); } public Func> Handler { get; set; } = (message, context) => default; } public class RoutingReflectionTests { private async ValueTask RunTestReflectAndRouteMessageAsync(BaseTestExecutor executor, TInput? input = default) where TInput : new() where TE : ReflectingExecutor { MessageRouter router = executor.Router; Assert.NotNull(router); input ??= new(); Assert.True(router.CanHandle(input.GetType())); Assert.True(router.CanHandle(input)); CallResult? result = await router.RouteMessageAsync(input, Mock.Of()); Assert.True(executor.InvokedHandler); return result; } [Fact] public async Task Test_ReflectAndExecute_DefaultHandlerAsync() { DefaultHandler executor = new(); CallResult? result = await this.RunTestReflectAndRouteMessageAsync(executor); Assert.NotNull(result); Assert.True(result.IsSuccess); Assert.True(result.IsVoid); } [Fact] public async Task Test_ReflectAndExecute_HandlerReturnsVoidAsync() { TypedHandler executor = new(); CallResult? result = await this.RunTestReflectAndRouteMessageAsync>(executor, 3); Assert.NotNull(result); Assert.True(result.IsSuccess); Assert.True(result.IsVoid); } [Fact] public async Task Test_ReflectAndExecute_HandlerReturnsValueAsync() { TypedHandlerWithOutput executor = new() { Handler = (message, context) => { return new ValueTask($"{message}"); } }; const string Expected = "3"; CallResult? result = await this.RunTestReflectAndRouteMessageAsync>(executor, int.Parse(Expected)); Assert.NotNull(result); Assert.True(result.IsSuccess); Assert.False(result.IsVoid); Assert.Equal(Expected, result.Result); } }