//
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
//
namespace MUnique.OpenMU.ChatServer.Tests;
using Microsoft.Extensions.Logging.Abstractions;
using Moq;
using MUnique.OpenMU.ChatServer;
using MUnique.OpenMU.Interfaces;
///
/// Unit tests for the .
///
[TestFixture]
public class ChatRoomTests
{
private const string ChatServerHost = "";
///
/// Tests if a new room returns the specified room id, which was given to the constructor.
///
[Test]
public void RoomId()
{
const ushort roomId = 4711;
var room = new ChatRoom(roomId, new NullLogger());
Assert.That(room.RoomId, Is.EqualTo(roomId));
}
///
/// Tries to register a client with a different room id. This should fail with an .
///
[Test]
public void RegisterClientWithDifferentRoomId()
{
const ushort roomId = 4711;
var room = new ChatRoom(roomId, new NullLogger());
var clientId = room.GetNextClientIndex();
var authenticationInfo = new ChatServerAuthenticationInfo(clientId, roomId - 1, "Bob", ChatServerHost, "123456789");
Assert.Throws(() => room.RegisterClient(authenticationInfo));
}
///
/// Tries to register a client with a correct room id.
///
[Test]
public void RegisterClientWithCorrectRoomId()
{
const ushort roomId = 4711;
var room = new ChatRoom(roomId, new NullLogger());
var clientId = room.GetNextClientIndex();
var authenticationInfo = new ChatServerAuthenticationInfo(clientId, roomId, "Bob", ChatServerHost, "123456789");
Assert.DoesNotThrow(() => room.RegisterClient(authenticationInfo));
}
///
/// Tries to join a null client. This should fail with an .
///
[Test]
public async ValueTask TryJoinNullClientAsync()
{
const ushort roomId = 4711;
var room = new ChatRoom(roomId, new NullLogger());
var clientId = room.GetNextClientIndex();
var authenticationInfo = new ChatServerAuthenticationInfo(clientId, roomId, "Bob", ChatServerHost, "123456789");
room.RegisterClient(authenticationInfo);
Assert.That(async () => await room.TryJoinAsync(null!), Throws.TypeOf());
}
///
/// Tries to join the room with an unauthenticated client. This should fail.
///
[Test]
public async ValueTask TryJoinWithUnauthenticatedClientAsync()
{
const ushort roomId = 4711;
var room = new ChatRoom(roomId, new NullLogger());
var clientId = room.GetNextClientIndex();
var authenticationInfo = new ChatServerAuthenticationInfo(clientId, roomId, "Bob", ChatServerHost, "123456789");
room.RegisterClient(authenticationInfo);
var chatClient = new Mock();
Assert.That(await room.TryJoinAsync(chatClient.Object).ConfigureAwait(false), Is.False);
}
///
/// Tries to join the room with a client with a wrong authentication token. This should fail.
///
[Test]
public async ValueTask TryJoinWithAuthenticatedClientButWrongTokenAsync()
{
const ushort roomId = 4711;
var room = new ChatRoom(roomId, new NullLogger());
var clientId = room.GetNextClientIndex();
var authenticationInfo = new ChatServerAuthenticationInfo(clientId, roomId, "Bob", ChatServerHost, "123456789");
room.RegisterClient(authenticationInfo);
var chatClient = new Mock();
chatClient.Setup(c => c.AuthenticationToken).Returns("987654321");
Assert.That(await room.TryJoinAsync(chatClient.Object).ConfigureAwait(false), Is.False);
}
///
/// Tries to join the room with an authenticated client. This should be successful.
///
[Test]
public async ValueTask TryJoinWithAuthenticatedClientAsync()
{
const ushort roomId = 4711;
var room = new ChatRoom(roomId, new NullLogger());
var clientId = room.GetNextClientIndex();
var authenticationInfo = new ChatServerAuthenticationInfo(clientId, roomId, "Bob", ChatServerHost, "123456789");
room.RegisterClient(authenticationInfo);
var chatClient = new Mock();
chatClient.Setup(c => c.AuthenticationToken).Returns(authenticationInfo.AuthenticationToken);
Assert.That(await room.TryJoinAsync(chatClient.Object).ConfigureAwait(false), Is.True);
}
///
/// Tests if is called after a client successfully joined a room.
///
[Test]
public async ValueTask ChatRoomClientListSentAsync()
{
const ushort roomId = 4711;
var room = new ChatRoom(roomId, new NullLogger());
var clientId = room.GetNextClientIndex();
var authenticationInfo = new ChatServerAuthenticationInfo(clientId, roomId, "Bob", ChatServerHost, "123456789");
room.RegisterClient(authenticationInfo);
var chatClient = new Mock();
chatClient.Setup(c => c.AuthenticationToken).Returns(authenticationInfo.AuthenticationToken);
await room.TryJoinAsync(chatClient.Object).ConfigureAwait(false);
chatClient.Verify(c => c.SendChatRoomClientListAsync(room.ConnectedClients), Times.Once);
}
///
/// Tests if returns the successfully authenticated and joined client.
///
[Test]
public async ValueTask ConnectedClientsAsync()
{
const ushort roomId = 4711;
var room = new ChatRoom(roomId, new NullLogger());
var clientId = room.GetNextClientIndex();
var authenticationInfo = new ChatServerAuthenticationInfo(clientId, roomId, "Bob", ChatServerHost, "123456789");
room.RegisterClient(authenticationInfo);
var chatClient = new Mock();
chatClient.Setup(c => c.AuthenticationToken).Returns(authenticationInfo.AuthenticationToken);
await room.TryJoinAsync(chatClient.Object).ConfigureAwait(false);
Assert.That(room.ConnectedClients, Has.Count.EqualTo(1));
Assert.That(room.ConnectedClients, Contains.Item(chatClient.Object));
}
///
/// Tests if is called as soon as another client joined the room.
///
[Test]
public async ValueTask SendJoinedMessageAsync()
{
const ushort roomId = 4711;
var room = new ChatRoom(roomId, new NullLogger());
var clientId0 = room.GetNextClientIndex();
var clientId1 = room.GetNextClientIndex();
var authenticationInfo0 = new ChatServerAuthenticationInfo(clientId0, roomId, "Alice", ChatServerHost, "99999");
var authenticationInfo1 = new ChatServerAuthenticationInfo(clientId1, roomId, "Bob", ChatServerHost, "123456789");
room.RegisterClient(authenticationInfo0);
room.RegisterClient(authenticationInfo1);
var chatClient0 = new Mock();
chatClient0.SetupAllProperties();
chatClient0.Setup(c => c.AuthenticationToken).Returns(authenticationInfo0.AuthenticationToken);
var chatClient1 = new Mock();
chatClient1.SetupAllProperties();
chatClient1.Setup(c => c.AuthenticationToken).Returns(authenticationInfo1.AuthenticationToken);
await room.TryJoinAsync(chatClient0.Object).ConfigureAwait(false);
await room.TryJoinAsync(chatClient1.Object).ConfigureAwait(false);
chatClient0.Verify(c => c.SendChatRoomClientUpdateAsync(clientId1, authenticationInfo1.ClientName, ChatRoomClientUpdateType.Joined), Times.Once);
}
///
/// Tests if is called as soon as another client left the room.
///
[Test]
public async ValueTask SendLeftMessageAsync()
{
const ushort roomId = 4711;
var room = new ChatRoom(roomId, new NullLogger());
var clientId0 = room.GetNextClientIndex();
var clientId1 = room.GetNextClientIndex();
var authenticationInfo0 = new ChatServerAuthenticationInfo(clientId0, roomId, "Alice", ChatServerHost, "99999");
var authenticationInfo1 = new ChatServerAuthenticationInfo(clientId1, roomId, "Bob", ChatServerHost, "123456789");
room.RegisterClient(authenticationInfo0);
room.RegisterClient(authenticationInfo1);
var chatClient0 = new Mock();
chatClient0.SetupAllProperties();
chatClient0.Setup(c => c.AuthenticationToken).Returns(authenticationInfo0.AuthenticationToken);
var chatClient1 = new Mock();
chatClient1.SetupAllProperties();
chatClient1.Setup(c => c.AuthenticationToken).Returns(authenticationInfo1.AuthenticationToken);
await room.TryJoinAsync(chatClient0.Object).ConfigureAwait(false);
await room.TryJoinAsync(chatClient1.Object).ConfigureAwait(false);
await room.LeaveAsync(chatClient0.Object).ConfigureAwait(false);
chatClient1.Verify(c => c.SendChatRoomClientUpdateAsync(clientId0, authenticationInfo0.ClientName, ChatRoomClientUpdateType.Left), Times.Once);
}
///
/// Tests if is called as soon as a message is sent through the room.
///
[Test]
public async ValueTask SendMessageAsync()
{
const ushort roomId = 4711;
const string chatMessage = "foobar1234567890";
var room = new ChatRoom(roomId, new NullLogger());
var clientId0 = room.GetNextClientIndex();
var clientId1 = room.GetNextClientIndex();
var authenticationInfo0 = new ChatServerAuthenticationInfo(clientId0, roomId, "Alice", ChatServerHost, "99999");
var authenticationInfo1 = new ChatServerAuthenticationInfo(clientId1, roomId, "Bob", ChatServerHost, "123456789");
room.RegisterClient(authenticationInfo0);
room.RegisterClient(authenticationInfo1);
var chatClient0 = new Mock();
chatClient0.Setup(c => c.AuthenticationToken).Returns(authenticationInfo0.AuthenticationToken);
var chatClient1 = new Mock();
chatClient1.Setup(c => c.AuthenticationToken).Returns(authenticationInfo1.AuthenticationToken);
await room.TryJoinAsync(chatClient0.Object).ConfigureAwait(false);
await room.TryJoinAsync(chatClient1.Object).ConfigureAwait(false);
await room.SendMessageAsync(clientId1, chatMessage).ConfigureAwait(false);
chatClient0.Verify(c => c.SendMessageAsync(clientId1, chatMessage), Times.Once);
chatClient1.Verify(c => c.SendMessageAsync(clientId1, chatMessage), Times.Once);
}
///
/// Tests if is fired as soon as all connected clients left the room.
///
[Test]
public async ValueTask RoomClosedEventAsync()
{
const ushort roomId = 4711;
var room = new ChatRoom(roomId, new NullLogger());
var clientId0 = room.GetNextClientIndex();
var clientId1 = room.GetNextClientIndex();
var authenticationInfo0 = new ChatServerAuthenticationInfo(clientId0, roomId, "Alice", ChatServerHost, "99999");
var authenticationInfo1 = new ChatServerAuthenticationInfo(clientId1, roomId, "Bob", ChatServerHost, "123456789");
room.RegisterClient(authenticationInfo0);
room.RegisterClient(authenticationInfo1);
var chatClient0 = new Mock();
chatClient0.Setup(c => c.AuthenticationToken).Returns(authenticationInfo0.AuthenticationToken);
var chatClient1 = new Mock();
chatClient1.Setup(c => c.AuthenticationToken).Returns(authenticationInfo1.AuthenticationToken);
var eventCalled = false;
room.RoomClosed += (sender, e) => eventCalled = true;
await room.TryJoinAsync(chatClient0.Object).ConfigureAwait(false);
await room.TryJoinAsync(chatClient1.Object).ConfigureAwait(false);
await room.LeaveAsync(chatClient0.Object).ConfigureAwait(false);
await room.LeaveAsync(chatClient1.Object).ConfigureAwait(false);
Assert.That(eventCalled, Is.True);
}
}