diff --git a/Runtime/Integrations/Local/LocalLobby.cs b/Runtime/Integrations/Local/LocalLobby.cs index 9896cf7..91acf61 100644 --- a/Runtime/Integrations/Local/LocalLobby.cs +++ b/Runtime/Integrations/Local/LocalLobby.cs @@ -44,6 +44,7 @@ public static LocalLobbyView Create(ulong id, int capacity, ulong ownerId = 0, LocalLobby(ulong id, int capacity, ulong ownerId, double packetLossPercent, Random packetLossRng) { Id = id; + OwnerId = ownerId; Capacity = capacity; _packetLossRng = packetLossRng; _connectedViews = new Dictionary(); @@ -72,7 +73,10 @@ public LocalLobbyView CreateView(AccountHandle id) { public void Delete() => Dispose(); internal void Connect(LocalLobbyView view) { - var handle = new AccountHandle(view.Id); + if (_connectedViews.Count >= Capacity) { + throw new InvalidOperationException("Cannot join a lobby that is already full"); + } + var handle = new AccountHandle(view.UserId); if (_connectedViews.ContainsKey(handle)) return; _metadata.AddMember(handle); _connectedViews[handle] = view; @@ -82,7 +86,7 @@ internal void Connect(LocalLobbyView view) { } internal void Disconnect(LocalLobbyView view) { - var handle = new AccountHandle(view.Id); + var handle = new AccountHandle(view.UserId); if (!_connectedViews.ContainsKey(handle)) return; _metadata.RemoveMember(handle); _connectedViews.Remove(handle); diff --git a/Runtime/Integrations/Local/LocalLobbyView.cs b/Runtime/Integrations/Local/LocalLobbyView.cs index fb2bbf5..f7e6481 100644 --- a/Runtime/Integrations/Local/LocalLobbyView.cs +++ b/Runtime/Integrations/Local/LocalLobbyView.cs @@ -23,7 +23,7 @@ public sealed class LocalLobbyView : Lobby { /// public LocalLobby BaseLobby { get; } - public override ulong Id { get; } + public override ulong Id => BaseLobby.Id; public override ulong UserId { get; } public override ulong OwnerId => BaseLobby.OwnerId; public override LobbyType Type => BaseLobby.Type; @@ -46,11 +46,11 @@ internal LocalLobbyView(ulong userId, LocalLobby lobby) : base() { public override IReadOnlyDictionary GetAllMetadata() => BaseLobby.GetAllMetadata(); internal override string GetMemberMetadata(AccountHandle handle, string key) => - throw new NotSupportedException(); + BaseLobby.GetMemberMetadata(handle, key); internal override void SetMemberMetadata(AccountHandle handle, string key, string value) => - throw new NotSupportedException(); + BaseLobby.SetMemberMetadata(handle, key, value); internal override void DeleteMemberMetadata(AccountHandle handle, string key) => - throw new NotSupportedException(); + BaseLobby.DeleteMemberMetadata(handle, key); public override void SendLobbyMessage(FixedBuffer message) { BaseLobby.SendLobbyMessage(new AccountHandle(UserId), message); diff --git a/Tests.meta b/Tests.meta new file mode 100644 index 0000000..c77853e --- /dev/null +++ b/Tests.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0125ee031972b0d45b9bae7721ab37df +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Runtime.meta b/Tests/Runtime.meta new file mode 100644 index 0000000..78a3647 --- /dev/null +++ b/Tests/Runtime.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 95c016b34bc872b4da242fca9d2c700b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Runtime/LocalLobbyTests.cs b/Tests/Runtime/LocalLobbyTests.cs new file mode 100644 index 0000000..13ec0ee --- /dev/null +++ b/Tests/Runtime/LocalLobbyTests.cs @@ -0,0 +1,172 @@ +using System.Collections; +using System.Collections.Generic; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; + +namespace HouraiTeahouse.Networking { + +public class LocalLobbyTests { + + [Test] + public void LocalLobby_Create() { + const ulong id = 69; + const ulong ownerId = 400; + const int capacity = 4; + var lobbyView = LocalLobby.Create(id, capacity, ownerId); + Assert.AreEqual(id, lobbyView.Id, "Lobby ID must be the same"); + Assert.AreEqual(ownerId, lobbyView.OwnerId, "Lobby view ID must be the same"); + Assert.AreEqual(ownerId, lobbyView.UserId, "Lobby view user ID must be the same"); + Assert.AreEqual(1, lobbyView.MemberCount, "Lobby view user ID must be the same"); + Assert.AreEqual(capacity, lobbyView.Capacity, "Lobby view capacity must be the same"); + } + + [Test] + public void LocalLobby_CreateViewDoesNotTriggerEvents() { + const ulong id = 69; + const ulong ownerId = 400; + const int capacity = 4; + var lobbyView = LocalLobby.Create(id, capacity, ownerId); + lobbyView.OnMemberJoin += (member) => Assert.Fail("OnMemberJoin should not be called"); + lobbyView.OnMemberLeave += (member) => Assert.Fail("OnMemberLeave should not be called"); + lobbyView.BaseLobby.CreateView(450); + } + + [Test] + public void LocalLobby_JoinTriggersOnMemberJoin() { + const ulong id = 69; + const ulong ownerId = 400; + const int capacity = 4; + var lobbyView = LocalLobby.Create(id, capacity, ownerId); + var triggered = false; + lobbyView.OnMemberJoin += (member) => triggered = true; + lobbyView.OnMemberLeave += (member) => Assert.Fail("OnMemberLeave should not be called"); + var remote = lobbyView.BaseLobby.CreateView(450); + remote.Join().Wait(); + Assert.IsTrue(triggered); + } + + [Test] + public void LocalLobby_LeaveTriggersOnMemberLeave() { + const ulong id = 69; + const ulong ownerId = 400; + const int capacity = 4; + var lobbyView = LocalLobby.Create(id, capacity, ownerId); + var triggered = false; + lobbyView.OnMemberLeave += (member) => triggered = true; + var remote = lobbyView.BaseLobby.CreateView(450); + remote.Join().Wait(); + remote.Leave(); + Assert.IsTrue(triggered); + } + + [Test] + public void LocalLobby_SetMetadataUpdatesEveryone() { + const ulong id = 69; + const ulong ownerId = 400; + const int capacity = 4; + const string key = "key"; + const string value = "value"; + var lobbyView = LocalLobby.Create(id, capacity, ownerId); + var triggered = false; + lobbyView.OnUpdated += () => triggered = true; + var remote = lobbyView.BaseLobby.CreateView(450); + remote.Join().Wait(); + lobbyView.SetMetadata(key, value); + Assert.AreEqual(value, remote.GetMetadata(key)); + Assert.IsTrue(triggered); + } + + [Test] + public void LocalLobby_SetMetadataDoesntUpdate() { + const ulong id = 69; + const ulong ownerId = 400; + const int capacity = 4; + const string key = "key"; + const string value = "value"; + var lobbyView = LocalLobby.Create(id, capacity, ownerId); + var triggered = false; + var remote = lobbyView.BaseLobby.CreateView(450); + remote.Join().Wait(); + lobbyView.SetMetadata(key, value); + lobbyView.OnUpdated += () => triggered = true; + lobbyView.SetMetadata(key, value); + Assert.AreEqual(value, remote.GetMetadata(key)); + Assert.IsFalse(triggered); + } + + [Test] + public void LocalLobby_DeleteMetadataUpdatesEveryone() { + const ulong id = 69; + const ulong ownerId = 400; + const int capacity = 4; + const string key = "key"; + const string value = "value"; + var lobbyView = LocalLobby.Create(id, capacity, ownerId); + var triggered = false; + lobbyView.OnUpdated += () => triggered = true; + var remote = lobbyView.BaseLobby.CreateView(450); + remote.Join().Wait(); + lobbyView.SetMetadata(key, value); + lobbyView.DeleteMetadata(key); + Assert.AreEqual(string.Empty, remote.GetMetadata(key)); + Assert.IsTrue(triggered); + } + + [Test] + public void LocalLobby_DeleteMetadataDoesntUpdate() { + const ulong id = 69; + const ulong ownerId = 400; + const int capacity = 4; + const string key = "key"; + const string value = "value"; + var lobbyView = LocalLobby.Create(id, capacity, ownerId); + var triggered = false; + lobbyView.OnUpdated += () => triggered = true; + var remote = lobbyView.BaseLobby.CreateView(450); + remote.Join().Wait(); + lobbyView.DeleteMetadata(key); + Assert.AreEqual(string.Empty, remote.GetMetadata(key)); + Assert.IsFalse(triggered); + } + + [Test] + public void LocalLobby_SetMemberMetadataUpdatesEveryone() { + const ulong id = 69; + const ulong ownerId = 400; + const int capacity = 4; + const string key = "key"; + const string value = "value"; + var lobbyView = LocalLobby.Create(id, capacity, ownerId); + ulong updatedId = 0; + lobbyView.OnMemberUpdated+= (mem) => updatedId = mem.Id; + var remote = lobbyView.BaseLobby.CreateView(450); + remote.Join().Wait(); + var member = lobbyView.Members.Get(remote.UserId); + member.SetMetadata(key, value); + Assert.AreEqual(value, remote.Members.Get(remote.UserId).GetMetadata(key)); + Assert.AreEqual(updatedId, remote.UserId); + } + + [Test] + public void LocalLobby_DeleteMemberMetadataUpdatesEveryone() { + const ulong id = 69; + const ulong ownerId = 400; + const int capacity = 4; + const string key = "key"; + const string value = "value"; + var lobbyView = LocalLobby.Create(id, capacity, ownerId); + ulong updatedId = 0; + lobbyView.OnMemberUpdated+= (mem) => updatedId = mem.Id; + var remote = lobbyView.BaseLobby.CreateView(450); + remote.Join().Wait(); + var member = lobbyView.Members.Get(remote.UserId); + member.SetMetadata(key, value); + member.DeleteMetadata(key); + Assert.AreEqual(string.Empty, remote.Members.Get(remote.UserId).GetMetadata(key)); + Assert.AreEqual(updatedId, remote.UserId); + } + +} + +} diff --git a/Tests/Runtime/LocalLobbyTests.cs.meta b/Tests/Runtime/LocalLobbyTests.cs.meta new file mode 100644 index 0000000..2c19e17 --- /dev/null +++ b/Tests/Runtime/LocalLobbyTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6a5c6fb3add717a4cae51c59c66d0812 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Runtime/com.houraiteahouse.networking.Editor.Tests.asmdef b/Tests/Runtime/com.houraiteahouse.networking.Editor.Tests.asmdef new file mode 100644 index 0000000..1cfd97b --- /dev/null +++ b/Tests/Runtime/com.houraiteahouse.networking.Editor.Tests.asmdef @@ -0,0 +1,17 @@ +{ + "name": "com.houraiteahouse.networking.EditorTests", + "references": [ + "GUID:4487c07f4904b9441a8796ba81d3a533" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Tests/Runtime/com.houraiteahouse.networking.Editor.Tests.asmdef.meta b/Tests/Runtime/com.houraiteahouse.networking.Editor.Tests.asmdef.meta new file mode 100644 index 0000000..3bef436 --- /dev/null +++ b/Tests/Runtime/com.houraiteahouse.networking.Editor.Tests.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 713d27f223818ef4ca8a101587a20f6c +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: