From 3c4b2fd9d85c8295febebb609a0883d60c3be6b8 Mon Sep 17 00:00:00 2001 From: vis2k Date: Fri, 6 Mar 2020 10:33:53 +0100 Subject: [PATCH] NetworkBehaviourTests: SendTargetRPCInternal --- .../Tests/Editor/NetworkBehaviourTests.cs | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/Assets/Mirror/Tests/Editor/NetworkBehaviourTests.cs b/Assets/Mirror/Tests/Editor/NetworkBehaviourTests.cs index 91040472a..e66c04a34 100644 --- a/Assets/Mirror/Tests/Editor/NetworkBehaviourTests.cs +++ b/Assets/Mirror/Tests/Editor/NetworkBehaviourTests.cs @@ -53,6 +53,26 @@ public void CallSendRPCInternal() } } + // we need to inherit from networkbehaviour to test protected functions + public class NetworkBehaviourSendTargetRPCInternalComponent : NetworkBehaviour + { + // counter to make sure that it's called exactly once + public int called; + + // weaver generates this from [Command] + // but for tests we need to add it manually + public static void TargetRPCGenerated(NetworkBehaviour comp, NetworkReader reader) + { + ++((NetworkBehaviourSendTargetRPCInternalComponent)comp).called; + } + + // SendCommandInternal is protected. let's expose it so we can test it. + public void CallSendTargetRPCInternal(NetworkConnection conn) + { + SendTargetRPCInternal(conn, GetType(), nameof(TargetRPCGenerated), new NetworkWriter(), 0); + } + } + public class NetworkBehaviourTests { GameObject gameObject; @@ -352,6 +372,99 @@ public void SendRPCInternal() Transport.activeTransport = null; GameObject.DestroyImmediate(transportGO); } + + [Test] + public void SendTargetRPCInternal() + { + // add rpc component + NetworkBehaviourSendTargetRPCInternalComponent comp = gameObject.AddComponent(); + Assert.That(comp.called, Is.EqualTo(0)); + + // transport is needed by server and client. + // it needs to be on a gameobject because client.connect enables it, + // which throws a NRE if not on a gameobject + GameObject transportGO = new GameObject(); + Transport.activeTransport = transportGO.AddComponent(); + + // calling rpc before server is active shouldn't work + LogAssert.Expect(LogType.Error, "TargetRPC Function " + nameof(NetworkBehaviourSendTargetRPCInternalComponent.TargetRPCGenerated) + " called on client."); + comp.CallSendTargetRPCInternal(null); + Assert.That(comp.called, Is.EqualTo(0)); + + // we need to start a server and connect a client in order to be + // able to send commands + // message handlers + NetworkServer.RegisterHandler((conn, msg) => {}, false); + NetworkServer.RegisterHandler((conn, msg) => {}, false); + NetworkServer.RegisterHandler((conn, msg) => {}, false); + NetworkServer.RegisterHandler((conn, msg) => {}, false); + NetworkServer.Listen(1); + Assert.That(NetworkServer.active, Is.True); + + // connect host client + NetworkClient.ConnectHost(); + Assert.That(NetworkClient.active, Is.True); + + // get the host connection which already has client->server and + // server->client set up + ULocalConnectionToServer connectionToServer = (ULocalConnectionToServer)NetworkClient.connection; + + // set host connection as ready and authenticated + connectionToServer.isReady = true; + connectionToServer.isAuthenticated = true; + connectionToServer.connectionToClient.isReady = true; + connectionToServer.connectionToClient.isAuthenticated = true; + connectionToServer.connectionToClient.identity = identity; + + // calling rpc before isServer is true shouldn't work + LogAssert.Expect(LogType.Warning, "TargetRpc " + nameof(NetworkBehaviourSendTargetRPCInternalComponent.TargetRPCGenerated) + " called on un-spawned object: " + gameObject.name); + comp.CallSendTargetRPCInternal(null); + Assert.That(comp.called, Is.EqualTo(0)); + + // we need an observer because sendrpc sends to ready observers + identity.OnStartServer(); // creates observers + identity.observers[connectionToServer.connectionToClient.connectionId] = connectionToServer.connectionToClient; + + identity.netId = 42; + + // calling rpc on connectionToServer shouldn't work + LogAssert.Expect(LogType.Error, "TargetRPC Function " + nameof(NetworkBehaviourSendTargetRPCInternalComponent.TargetRPCGenerated) + " called on connection to server"); + comp.CallSendTargetRPCInternal(new NetworkConnectionToServer()); + Assert.That(comp.called, Is.EqualTo(0)); + + // set proper connection to client + identity.connectionToClient = connectionToServer.connectionToClient; + + // isServer needs to be true, otherwise we can't call rpcs + Assert.That(comp.isServer, Is.True); + + // register the command delegate, otherwise it's not found + NetworkBehaviour.RegisterRpcDelegate(typeof(NetworkBehaviourSendTargetRPCInternalComponent), + nameof(NetworkBehaviourSendTargetRPCInternalComponent.TargetRPCGenerated), + NetworkBehaviourSendTargetRPCInternalComponent.TargetRPCGenerated); + + // identity needs to be in spawned dict, otherwise rpc handler + // won't find it + NetworkIdentity.spawned[identity.netId] = identity; + + // call rpc + comp.CallSendTargetRPCInternal(null); + + // update client's connection so that pending messages are processed + connectionToServer.Update(); + + // rpc should have been called now + Assert.That(comp.called, Is.EqualTo(1)); + + // clean up + NetworkBehaviour.ClearDelegates(); + ClientScene.Shutdown(); // clear clientscene.readyconnection + NetworkServer.RemoveLocalConnection(); + NetworkClient.Shutdown(); + NetworkServer.Shutdown(); + Transport.activeTransport = null; + GameObject.DestroyImmediate(transportGO); + } } // we need to inherit from networkbehaviour to test protected functions