// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using System.Net;
using Microsoft.Teams.Api;
using Microsoft.Teams.Api.Activities;
using Microsoft.Teams.Api.Auth;
using Microsoft.Teams.Apps.Events;
using Microsoft.Teams.Apps.Plugins;
using Microsoft.Teams.Apps.Testing.Events;
namespace Microsoft.Teams.Apps.Testing.Plugins;
///
/// a plugin used to test any App implementation
///
[Plugin(Name = "test")]
public partial class TestPlugin : ISenderPlugin
{
public event EventFunction Events;
protected Action? OnInitHandler { get; set; }
protected Action? OnStartHandler { get; set; }
protected Action? OnErrorHandler { get; set; }
protected Action? OnActivityHandler { get; set; }
protected Action? OnActivityResponseHandler { get; set; }
protected Action? OnActivitySentHandler { get; set; }
public TestPlugin WithInit(Action handler)
{
OnInitHandler = handler;
return this;
}
public TestPlugin WithError(Action handler)
{
OnErrorHandler = handler;
return this;
}
public TestPlugin WithActivity(Action handler)
{
OnActivityHandler = handler;
return this;
}
public TestPlugin WithActivityResponse(Action handler)
{
OnActivityResponseHandler = handler;
return this;
}
public TestPlugin WithActivitySent(Action handler)
{
OnActivitySentHandler = handler;
return this;
}
public Task OnInit(App app, CancellationToken cancellationToken = default)
{
if (OnInitHandler is not null)
{
OnInitHandler(app);
}
return Task.CompletedTask;
}
public Task OnStart(App app, CancellationToken cancellationToken = default)
{
if (OnStartHandler is not null)
{
OnStartHandler(app);
}
return Task.CompletedTask;
}
public Task OnError(App app, IPlugin plugin, ErrorEvent @event, CancellationToken cancellationToken = default)
{
if (OnErrorHandler is not null)
{
OnErrorHandler(app, plugin, @event);
}
return Task.CompletedTask;
}
public Task OnActivity(App app, ISenderPlugin sender, ActivityEvent @event, CancellationToken cancellationToken = default)
{
if (OnActivityHandler is not null)
{
OnActivityHandler(app, sender, @event);
}
return Task.CompletedTask;
}
public Task OnActivityResponse(App app, ISenderPlugin sender, ActivityResponseEvent @event, CancellationToken cancellationToken = default)
{
if (OnActivityResponseHandler is not null)
{
OnActivityResponseHandler(app, sender, @event);
}
return Task.CompletedTask;
}
public Task OnActivitySent(App app, ISenderPlugin sender, ActivitySentEvent @event, CancellationToken cancellationToken = default)
{
if (OnActivitySentHandler is not null)
{
OnActivitySentHandler(app, sender, @event);
}
return Task.CompletedTask;
}
public Task Send(IActivity activity, ConversationReference reference, CancellationToken cancellationToken = default)
{
return Send(activity, reference, cancellationToken);
}
public Task Send(TActivity activity, ConversationReference reference, CancellationToken cancellationToken = default) where TActivity : IActivity
{
#pragma warning disable ExperimentalTeamsTargeted
if (activity.Recipient?.IsTargeted == true && reference.Conversation.Type?.IsPersonal == true)
{
throw new InvalidOperationException(
"Targeted messages are not supported in personal (1:1) chats.");
}
#pragma warning restore ExperimentalTeamsTargeted
return Task.FromResult(activity);
}
public IStreamer CreateStream(ConversationReference reference, CancellationToken cancellationToken = default)
{
return new Stream();
}
public async Task Do(IToken token, IActivity activity, IDictionary? extra = null, CancellationToken cancellationToken = default)
{
return await Do(new()
{
Token = token,
Activity = activity,
Extra = extra
}, cancellationToken).ConfigureAwait(false);
}
public async Task Do(ActivityEvent @event, CancellationToken cancellationToken = default)
{
try
{
if (@event.Activity is MessageActivity message)
{
await Events(
this,
"message",
new TestMessageEvent() { Message = message.Text },
cancellationToken
).ConfigureAwait(false);
}
var @out = await Events(
this,
EventType.Activity,
@event,
cancellationToken
).ConfigureAwait(false);
var res = (Response?)@out;
if (res is null)
{
throw new Exception("expected activity response");
}
return res;
}
catch (Exception ex)
{
await Events(
this,
EventType.Error,
new ErrorEvent() { Exception = ex },
cancellationToken
).ConfigureAwait(false);
return new(HttpStatusCode.InternalServerError, ex.ToString());
}
}
}