193 lines
8.0 KiB
C#
193 lines
8.0 KiB
C#
using Luna.Channels.Abstractions;
|
|
using Luna.Channels.Tests.Stubs;
|
|
using Luna.Core.Abstractions;
|
|
using Luna.Shared;
|
|
using Moq;
|
|
|
|
namespace Luna.Channels.Tests;
|
|
|
|
[TestFixture]
|
|
[Category("Unit")]
|
|
public class IntegrationTests
|
|
{
|
|
private Mock<ISessionManager> sessionManagerMock = null!;
|
|
private Mock<IChannel> channelMock = null!;
|
|
private ChannelManagerStub manager = null!;
|
|
|
|
[SetUp]
|
|
public void SetUp()
|
|
{
|
|
sessionManagerMock = new Mock<ISessionManager>();
|
|
channelMock = new Mock<IChannel>();
|
|
channelMock.Setup(c => c.ChannelId).Returns("test-ch-1");
|
|
channelMock.Setup(c => c.ChannelType).Returns("test");
|
|
channelMock.Setup(c => c.SendStreamingMessageAsync(
|
|
It.IsAny<IAsyncEnumerable<ChatStreamUpdate>>(),
|
|
It.IsAny<CancellationToken>())).Returns(Task.CompletedTask);
|
|
manager = new ChannelManagerStub(sessionManagerMock.Object);
|
|
}
|
|
|
|
private static async IAsyncEnumerable<ChatStreamUpdate> BuildStream(params ChatStreamUpdate[] updates)
|
|
{
|
|
foreach (var u in updates)
|
|
{
|
|
yield return u;
|
|
await Task.Yield();
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public async Task MessageReceived_RoutesToSessionManager_WithCorrectContent()
|
|
{
|
|
var message = new ChannelMessage(
|
|
Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "user-1", "User One", "Hello Luna!", DateTimeOffset.UtcNow);
|
|
|
|
sessionManagerMock
|
|
.Setup(s => s.RouteMessagesAsync(
|
|
message.Content,
|
|
message.ConversationId,
|
|
It.IsAny<string>(),
|
|
It.IsAny<CancellationToken>()))
|
|
.Returns(BuildStream(new ChatStreamUpdate(ChatStreamUpdateType.Text, "Hi!", null, false)));
|
|
|
|
manager.RegisterChannel(new CliChannelStub { ChannelId = "test-1" });
|
|
|
|
var args = new ChannelMessageReceivedEventArgs { Message = message, Channel = channelMock.Object };
|
|
channelMock.Raise(c => c.MessageReceived += null, channelMock.Object, args);
|
|
|
|
await Task.Delay(50);
|
|
|
|
sessionManagerMock.Verify(s => s.RouteMessagesAsync(
|
|
message.Content,
|
|
message.ConversationId,
|
|
It.IsAny<string>(),
|
|
It.IsAny<CancellationToken>()), Times.Once);
|
|
}
|
|
|
|
[Test]
|
|
public async Task MessageReceived_PipesSessionResponseToChannel_SendStreamingMessageAsync()
|
|
{
|
|
var message = new ChannelMessage(
|
|
Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "user-2", "User Two", "What time is it?", DateTimeOffset.UtcNow);
|
|
|
|
var responseStream = BuildStream(
|
|
new ChatStreamUpdate(ChatStreamUpdateType.Text, "It's ", null, false),
|
|
new ChatStreamUpdate(ChatStreamUpdateType.Text, "noon.", null, false),
|
|
new ChatStreamUpdate(ChatStreamUpdateType.Complete, null, null, true));
|
|
|
|
sessionManagerMock
|
|
.Setup(s => s.RouteMessagesAsync(
|
|
It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<CancellationToken>()))
|
|
.Returns(responseStream);
|
|
|
|
manager.RegisterChannel(new CliChannelStub { ChannelId = "test-1" });
|
|
|
|
var args = new ChannelMessageReceivedEventArgs { Message = message, Channel = channelMock.Object };
|
|
channelMock.Raise(c => c.MessageReceived += null, channelMock.Object, args);
|
|
|
|
await Task.Delay(50);
|
|
|
|
channelMock.Verify(c => c.SendStreamingMessageAsync(
|
|
It.IsAny<IAsyncEnumerable<ChatStreamUpdate>>(),
|
|
It.IsAny<CancellationToken>()), Times.Once);
|
|
}
|
|
|
|
[Test]
|
|
public async Task MessageReceived_WhenIsHandled_True_DoesNotRouteToSessionManager()
|
|
{
|
|
var message = new ChannelMessage(
|
|
Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "user-3", "User Three", "/start", DateTimeOffset.UtcNow);
|
|
|
|
manager.RegisterChannel(new CliChannelStub { ChannelId = "test-1" });
|
|
|
|
var args = new ChannelMessageReceivedEventArgs { Message = message, Channel = channelMock.Object, IsHandled = true };
|
|
channelMock.Raise(c => c.MessageReceived += null, channelMock.Object, args);
|
|
|
|
await Task.Delay(50);
|
|
|
|
sessionManagerMock.Verify(s => s.RouteMessagesAsync(
|
|
It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<CancellationToken>()),
|
|
Times.Never);
|
|
}
|
|
|
|
[Test]
|
|
public async Task TwoChannels_ReceiveMessagesIndependently_BothRoutedToSessionManager()
|
|
{
|
|
var channel2Mock = new Mock<IChannel>();
|
|
channel2Mock.Setup(c => c.ChannelId).Returns("test-ch-2");
|
|
channel2Mock.Setup(c => c.ChannelType).Returns("test");
|
|
channel2Mock.Setup(c => c.SendStreamingMessageAsync(
|
|
It.IsAny<IAsyncEnumerable<ChatStreamUpdate>>(), It.IsAny<CancellationToken>()))
|
|
.Returns(Task.CompletedTask);
|
|
|
|
sessionManagerMock
|
|
.Setup(s => s.RouteMessagesAsync(
|
|
It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<CancellationToken>()))
|
|
.Returns(BuildStream(new ChatStreamUpdate(ChatStreamUpdateType.Text, "ok", null, true)));
|
|
|
|
manager.RegisterChannel(new CliChannelStub { ChannelId = "test-1" });
|
|
manager.RegisterChannel(channel2Mock.Object);
|
|
|
|
var msg1 = new ChannelMessage(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "u1", "U1", "Msg1", DateTimeOffset.UtcNow);
|
|
var msg2 = new ChannelMessage(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "u2", "U2", "Msg2", DateTimeOffset.UtcNow);
|
|
|
|
channelMock.Raise(c => c.MessageReceived += null, channelMock.Object,
|
|
new ChannelMessageReceivedEventArgs { Message = msg1, Channel = channelMock.Object });
|
|
channel2Mock.Raise(c => c.MessageReceived += null, channel2Mock.Object,
|
|
new ChannelMessageReceivedEventArgs { Message = msg2, Channel = channel2Mock.Object });
|
|
|
|
await Task.Delay(100);
|
|
|
|
sessionManagerMock.Verify(s => s.RouteMessagesAsync(
|
|
It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<CancellationToken>()),
|
|
Times.Exactly(2));
|
|
}
|
|
|
|
[Test]
|
|
public async Task SessionManager_RouteMessagesAsync_ReceivesCancellationToken()
|
|
{
|
|
using var cts = new CancellationTokenSource();
|
|
var message = new ChannelMessage(
|
|
Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "user-4", "User Four", "Cancel me", DateTimeOffset.UtcNow);
|
|
|
|
sessionManagerMock
|
|
.Setup(s => s.RouteMessagesAsync(
|
|
It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), cts.Token))
|
|
.Returns(BuildStream(new ChatStreamUpdate(ChatStreamUpdateType.Text, "x", null, true)));
|
|
|
|
manager.RegisterChannel(new CliChannelStub { ChannelId = "test-1" });
|
|
|
|
var args = new ChannelMessageReceivedEventArgs { Message = message, Channel = channelMock.Object };
|
|
await channelMock.RaiseAsync(c => c.MessageReceived += null, channelMock.Object, args);
|
|
|
|
await Task.Delay(50, cts.Token);
|
|
|
|
sessionManagerMock.Verify(s => s.RouteMessagesAsync(
|
|
message.Content,
|
|
message.ConversationId,
|
|
It.IsAny<string>(),
|
|
It.IsAny<CancellationToken>()), Times.Once);
|
|
}
|
|
|
|
[Test]
|
|
public async Task SessionManager_Throws_ChannelRemainsActive_NotDisconnected()
|
|
{
|
|
var message = new ChannelMessage(
|
|
Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "user-5", "User Five", "Boom", DateTimeOffset.UtcNow);
|
|
|
|
sessionManagerMock
|
|
.Setup(s => s.RouteMessagesAsync(
|
|
It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<CancellationToken>()))
|
|
.Throws(new InvalidOperationException("Simulated routing failure"));
|
|
|
|
manager.RegisterChannel(new CliChannelStub { ChannelId = "test-1" });
|
|
|
|
Assert.DoesNotThrowAsync(async () =>
|
|
{
|
|
var args = new ChannelMessageReceivedEventArgs { Message = message, Channel = channelMock.Object };
|
|
await channelMock.RaiseAsync(c => c.MessageReceived += null, channelMock.Object, args);
|
|
await Task.Delay(50);
|
|
});
|
|
}
|
|
}
|