diff --git a/src/main/java/in/dragonbra/javasteam/steam/handlers/steamgameserver/LogOnDetails.kt b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamgameserver/LogOnDetails.kt index c866e7a5..22ff38b7 100644 --- a/src/main/java/in/dragonbra/javasteam/steam/handlers/steamgameserver/LogOnDetails.kt +++ b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamgameserver/LogOnDetails.kt @@ -6,4 +6,4 @@ package `in`.dragonbra.javasteam.steam.handlers.steamgameserver * @param token Gets or sets the authentication token used to log in as a game server. * @param appID Gets or sets the AppID this gameserver will serve. */ -data class LogOnDetails(var token: String?, var appID: Int) +data class LogOnDetails(var token: String, var appID: Int) diff --git a/src/main/java/in/dragonbra/javasteam/steam/handlers/steamgameserver/SteamGameServer.kt b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamgameserver/SteamGameServer.kt index 40760c45..f9b802bc 100644 --- a/src/main/java/in/dragonbra/javasteam/steam/handlers/steamgameserver/SteamGameServer.kt +++ b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamgameserver/SteamGameServer.kt @@ -18,10 +18,13 @@ import `in`.dragonbra.javasteam.steam.handlers.steamgameserver.callback.TicketAu import `in`.dragonbra.javasteam.steam.handlers.steamuser.callback.LoggedOnCallback import `in`.dragonbra.javasteam.steam.steamclient.callbackmgr.CallbackMsg import `in`.dragonbra.javasteam.steam.steamclient.callbacks.DisconnectedCallback +import `in`.dragonbra.javasteam.types.AsyncJobSingle import `in`.dragonbra.javasteam.types.SteamID import `in`.dragonbra.javasteam.util.HardwareUtils import `in`.dragonbra.javasteam.util.NetHelpers +import `in`.dragonbra.javasteam.util.NetHelpers.obfuscatePrivateIP import `in`.dragonbra.javasteam.util.Utils +import `in`.dragonbra.javasteam.util.obfuscatePrivateIP import java.net.Inet6Address /** @@ -34,26 +37,27 @@ class SteamGameServer : ClientMsgHandler() { * Logs onto the Steam network as a persistent game server. * The client should already have been connected at this point. * Results are return in a [LoggedOnCallback]. - * * @param details The details to use for logging on. + * @return The Job ID of the request. This can be used to fine the appropriate [LoggedOnCallback] + * @throws IllegalArgumentException token is not set within [details]. */ - fun logOn(details: LogOnDetails) { - require(!details.token.isNullOrEmpty()) { "LogOn requires a game server token to be set in 'details'." } + @Throws(IllegalArgumentException::class) + fun logOn(details: LogOnDetails): AsyncJobSingle { + require(!details.token.isBlank()) { "LogOn requires a game server token to be set in 'details'." } + + val logon = ClientMsgProtobuf(CMsgClientLogon::class.java, EMsg.ClientLogonGameServer) if (!client.isConnected) { - LoggedOnCallback(EResult.NoConnection).also(client::postCallback) - return + client.postCallback(LoggedOnCallback(EResult.NoConnection, logon.sourceJobID)) + return AsyncJobSingle(client, logon.sourceJobID) } - val logon = ClientMsgProtobuf(CMsgClientLogon::class.java, EMsg.ClientLogonGameServer) - val gsId = SteamID(0, 0, client.universe, EAccountType.GameServer) logon.protoHeader.clientSessionid = 0 logon.protoHeader.steamid = gsId.convertToUInt64() - val localIp: CMsgIPAddress = NetHelpers.getMsgIPAddress(client.localIP!!) - logon.body.obfuscatedPrivateIp = NetHelpers.obfuscatePrivateIP(localIp) + logon.body.obfuscatedPrivateIp = NetHelpers.getMsgIPAddress(client.localIP!!).obfuscatePrivateIP() logon.body.protocolVersion = MsgClientLogon.CurrentProtocol @@ -64,6 +68,8 @@ class SteamGameServer : ClientMsgHandler() { logon.body.gameServerToken = details.token client.send(logon) + + return AsyncJobSingle(client, logon.sourceJobID) } /** @@ -72,23 +78,23 @@ class SteamGameServer : ClientMsgHandler() { * Results are return in a [LoggedOnCallback]. * * @param appId The AppID served by this game server, or 0 for the default. + * @return The Job ID of the request. This can be used to fine the appropriate [LoggedOnCallback] */ @JvmOverloads - fun logOnAnonymous(appId: Int = 0) { + fun logOnAnonymous(appId: Int = 0): AsyncJobSingle { + val logon = ClientMsgProtobuf(CMsgClientLogon::class.java, EMsg.ClientLogonGameServer) + if (!client.isConnected) { - client.postCallback(LoggedOnCallback(EResult.NoConnection)) - return + client.postCallback(LoggedOnCallback(EResult.NoConnection, logon.sourceJobID)) + return AsyncJobSingle(client, logon.sourceJobID) } - val logon = ClientMsgProtobuf(CMsgClientLogon::class.java, EMsg.ClientLogonGameServer) - val gsId = SteamID(0, 0, client.universe, EAccountType.AnonGameServer) logon.protoHeader.clientSessionid = 0 logon.protoHeader.steamid = gsId.convertToUInt64() - val localIp: CMsgIPAddress = NetHelpers.getMsgIPAddress(client.localIP!!) - logon.body.obfuscatedPrivateIp = NetHelpers.obfuscatePrivateIP(localIp) + logon.body.obfuscatedPrivateIp = NetHelpers.getMsgIPAddress(client.localIP!!).obfuscatePrivateIP() logon.body.protocolVersion = MsgClientLogon.CurrentProtocol @@ -97,6 +103,8 @@ class SteamGameServer : ClientMsgHandler() { logon.body.machineId = ByteString.copyFrom(HardwareUtils.getMachineID()) client.send(logon) + + return AsyncJobSingle(client, logon.sourceJobID) } /** diff --git a/src/main/java/in/dragonbra/javasteam/steam/handlers/steamuser/SteamUser.kt b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamuser/SteamUser.kt index 3bdb414d..fbe37795 100644 --- a/src/main/java/in/dragonbra/javasteam/steam/handlers/steamuser/SteamUser.kt +++ b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamuser/SteamUser.kt @@ -26,6 +26,7 @@ import `in`.dragonbra.javasteam.steam.handlers.steamuser.callback.WalletInfoCall import `in`.dragonbra.javasteam.steam.handlers.steamuser.callback.WebAPIUserNonceCallback import `in`.dragonbra.javasteam.steam.steamclient.callbackmgr.CallbackMsg import `in`.dragonbra.javasteam.steam.steamclient.callbacks.DisconnectedCallback +import `in`.dragonbra.javasteam.types.AsyncJobSingle import `in`.dragonbra.javasteam.types.SteamID import `in`.dragonbra.javasteam.util.HardwareUtils import `in`.dragonbra.javasteam.util.JavaSteamAddition @@ -55,21 +56,23 @@ class SteamUser : ClientMsgHandler() { * Logs the client into the Steam3 network. * The client should already have been connected at this point. * Results are returned in a [LoggedOnCallback]. - * * @param details The details to use for logging on. + * @return The Job ID of the request. This can be used to find the appropriate [LoggedOnCallback]/ + * @throws IllegalArgumentException Username or password are not set within [details]. */ - fun logOn(details: LogOnDetails) { + @Throws(IllegalArgumentException::class) + fun logOn(details: LogOnDetails): AsyncJobSingle { if (details.username.isEmpty() || (details.password.isNullOrEmpty() && details.accessToken.isNullOrEmpty())) { throw IllegalArgumentException("LogOn requires a username and password or access token to be set in 'details'.") } + val logon = ClientMsgProtobuf(CMsgClientLogon::class.java, EMsg.ClientLogon) + if (!client.isConnected) { - client.postCallback(LoggedOnCallback(EResult.NoConnection)) - return + client.postCallback(LoggedOnCallback(EResult.NoConnection, logon.sourceJobID)) + return AsyncJobSingle(client, logon.sourceJobID) } - val logon = ClientMsgProtobuf(CMsgClientLogon::class.java, EMsg.ClientLogon) - val steamID = SteamID(details.accountID, details.accountInstance, client.universe, EAccountType.Individual) if (details.loginID != null) { @@ -141,24 +144,26 @@ class SteamUser : ClientMsgHandler() { } client.send(logon) + + return AsyncJobSingle(client, logon.sourceJobID) } /** * Logs the client into the Steam3 network as an anonymous user. * The client should already have been connected at this point. * Results are returned in a [LoggedOnCallback]. - * * @param details The details to use for logging on. + * @return The Job ID of the request. This can be used to find the appropriate [LoggedOnCallback] */ @JvmOverloads - fun logOnAnonymous(details: AnonymousLogOnDetails = AnonymousLogOnDetails()) { + fun logOnAnonymous(details: AnonymousLogOnDetails = AnonymousLogOnDetails()): AsyncJobSingle { + val logon = ClientMsgProtobuf(CMsgClientLogon::class.java, EMsg.ClientLogon) + if (!client.isConnected) { - client.postCallback(LoggedOnCallback(EResult.NoConnection)) - return + client.postCallback(LoggedOnCallback(EResult.NoConnection, logon.sourceJobID)) + return AsyncJobSingle(client, logon.sourceJobID) } - val logon = ClientMsgProtobuf(CMsgClientLogon::class.java, EMsg.ClientLogon) - val auId = SteamID(0, 0, client.universe, EAccountType.AnonUser) logon.protoHeader.clientSessionid = 0 @@ -172,6 +177,8 @@ class SteamUser : ClientMsgHandler() { logon.body.machineId = ByteString.copyFrom(HardwareUtils.getMachineID()) client.send(logon) + + return AsyncJobSingle(client, logon.sourceJobID) } /** diff --git a/src/main/java/in/dragonbra/javasteam/steam/handlers/steamuser/callback/LoggedOffCallback.kt b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamuser/callback/LoggedOffCallback.kt index 25527cf6..5eac8344 100644 --- a/src/main/java/in/dragonbra/javasteam/steam/handlers/steamuser/callback/LoggedOffCallback.kt +++ b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamuser/callback/LoggedOffCallback.kt @@ -24,9 +24,11 @@ class LoggedOffCallback(packetMsg: IPacketMsg) : CallbackMsg() { SteammessagesClientserverLogin.CMsgClientLoggedOff::class.java, packetMsg ) + jobID = loggedOff.targetJobID result = EResult.from(loggedOff.body.eresult) } else { val loggedOff = ClientMsg(MsgClientLoggedOff::class.java, packetMsg) + jobID = loggedOff.targetJobID result = loggedOff.body.result } } diff --git a/src/main/java/in/dragonbra/javasteam/steam/handlers/steamuser/callback/LoggedOnCallback.kt b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamuser/callback/LoggedOnCallback.kt index bfe64be7..9f2bfe19 100644 --- a/src/main/java/in/dragonbra/javasteam/steam/handlers/steamuser/callback/LoggedOnCallback.kt +++ b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamuser/callback/LoggedOnCallback.kt @@ -12,6 +12,7 @@ import `in`.dragonbra.javasteam.protobufs.steamclient.SteammessagesParentalObjec import `in`.dragonbra.javasteam.steam.handlers.steamuser.LogOnDetails import `in`.dragonbra.javasteam.steam.handlers.steamuser.SteamUser import `in`.dragonbra.javasteam.steam.steamclient.callbackmgr.CallbackMsg +import `in`.dragonbra.javasteam.types.JobID import `in`.dragonbra.javasteam.types.SteamID import `in`.dragonbra.javasteam.util.NetHelpers import `in`.dragonbra.javasteam.util.log.LogManager @@ -161,6 +162,7 @@ class LoggedOnCallback : CallbackMsg { ) val resp = loginResp.body + jobID = loginResp.targetJobID result = EResult.from(resp.eresult) extendedResult = EResult.from(resp.eresultExtended) @@ -203,14 +205,16 @@ class LoggedOnCallback : CallbackMsg { clientInstanceId = resp.clientInstanceId } - constructor(result: EResult) { + constructor(result: EResult, jobID: JobID) { this.result = result + this.jobID = jobID } private fun handleNonProtoLogon(packetMsg: IPacketMsg) { val loginResp = ClientMsg(MsgClientLogOnResponse::class.java, packetMsg) val resp = loginResp.body + jobID = loginResp.targetJobID result = resp.result outOfGameSecsPerHeartbeat = resp.outOfGameHeartbeatRateSec diff --git a/src/main/java/in/dragonbra/javasteam/steam/steamclient/SteamClient.kt b/src/main/java/in/dragonbra/javasteam/steam/steamclient/SteamClient.kt index 31a2db15..cd8f4d91 100644 --- a/src/main/java/in/dragonbra/javasteam/steam/steamclient/SteamClient.kt +++ b/src/main/java/in/dragonbra/javasteam/steam/steamclient/SteamClient.kt @@ -27,6 +27,7 @@ import `in`.dragonbra.javasteam.steam.steamclient.callbacks.DisconnectedCallback import `in`.dragonbra.javasteam.steam.steamclient.configuration.SteamConfiguration import `in`.dragonbra.javasteam.types.AsyncJob import `in`.dragonbra.javasteam.types.JobID +import `in`.dragonbra.javasteam.util.JavaSteamAddition import `in`.dragonbra.javasteam.util.log.LogManager import `in`.dragonbra.javasteam.util.log.Logger import kotlinx.coroutines.CoroutineScope @@ -152,7 +153,6 @@ class SteamClient @JvmOverloads constructor( /** * Returns a registered handler. - * * @param type The type of the handler to cast to. Must derive from ClientMsgHandler. * @param T The type of the handler to cast to. Must derive from ClientMsgHandler. * @return A registered handler on success, or null if the handler could not be found. @@ -163,11 +163,32 @@ class SteamClient @JvmOverloads constructor( /** * Kotlin Helper: * Returns a registered handler. - * * @param T The type of the handler to cast to. Must derive from ClientMsgHandler. * @return A registered handler on success, or null if the handler could not be found. */ + @JavaSteamAddition inline fun getHandler(): T? = getHandler(T::class.java) + + /** + * Returns a registered handler, throwing if not found. + * @param type The type of the handler to cast to. Must derive from ClientMsgHandler. + * @return A registered handler. + * @throws IllegalArgumentException No handler of type [T] is registered. + */ + @Throws(IllegalArgumentException::class) + fun getRequiredHandler(type: Class): T = + getHandler(type) ?: throw IllegalArgumentException("No handler found for type ${type.name}") + + /** + * Kotlin Helper: + * Returns a registered handler, throwing if not found. + * @param T The type of the handler to cast to. Must derive from ClientMsgHandler. + * @return A registered handler. + * @throws IllegalArgumentException No handler of type [T] is registered. + */ + @JavaSteamAddition + @Throws(IllegalArgumentException::class) + inline fun getRequiredHandler() = getRequiredHandler(T::class.java) //endregion //region Callbacks diff --git a/src/main/java/in/dragonbra/javasteam/util/NetHelpers.kt b/src/main/java/in/dragonbra/javasteam/util/NetHelpers.kt index 21a4bc99..caa8894b 100644 --- a/src/main/java/in/dragonbra/javasteam/util/NetHelpers.kt +++ b/src/main/java/in/dragonbra/javasteam/util/NetHelpers.kt @@ -12,6 +12,8 @@ import java.net.Socket import java.net.UnknownHostException import java.nio.ByteBuffer +fun CMsgIPAddress.obfuscatePrivateIP() = NetHelpers.obfuscatePrivateIP(this) + /** * @author lngtr * @since 2018-02-22 diff --git a/src/test/java/in/dragonbra/javasteam/steam/handlers/HandlerTestBase.java b/src/test/java/in/dragonbra/javasteam/steam/handlers/HandlerTestBase.java index ff1eeccb..5b282009 100644 --- a/src/test/java/in/dragonbra/javasteam/steam/handlers/HandlerTestBase.java +++ b/src/test/java/in/dragonbra/javasteam/steam/handlers/HandlerTestBase.java @@ -70,6 +70,12 @@ protected C verifyCallback() { return (C) callback; } + protected CallbackMsg getCallback() { + ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(CallbackMsg.class); + verify(steamClient, atLeast(1)).postCallback(callbackCaptor.capture()); + return callbackCaptor.getValue(); + } + protected IPacketMsg getPacket(EMsg msgType, boolean isProto) { return CMClient.getPacketMsg(TestPackets.getPacket(msgType, isProto)); } diff --git a/src/test/java/in/dragonbra/javasteam/steam/handlers/steamgameserver/SteamGameServerTest.java b/src/test/java/in/dragonbra/javasteam/steam/handlers/steamgameserver/SteamGameServerTest.java new file mode 100644 index 00000000..fce82c78 --- /dev/null +++ b/src/test/java/in/dragonbra/javasteam/steam/handlers/steamgameserver/SteamGameServerTest.java @@ -0,0 +1,57 @@ +package in.dragonbra.javasteam.steam.handlers.steamgameserver; + +import in.dragonbra.javasteam.enums.EResult; +import in.dragonbra.javasteam.steam.handlers.HandlerTestBase; +import in.dragonbra.javasteam.steam.handlers.steamuser.callback.LoggedOnCallback; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; + +/** + * @author Lossy + * @since 2026-3-22 + */ +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) +public class SteamGameServerTest extends HandlerTestBase { + + @Override + protected SteamGameServer createHandler() { + return new SteamGameServer(); + } + + @Test + public void logOnPostsLoggedOnCallbackWhenNoConnection() { + Mockito.when(steamClient.isConnected()).thenReturn(false); + + var details = new LogOnDetails("SuperSecretToken", 0); + var asyncJob = handler.logOn(details); + + var callback = getCallback(); + Assertions.assertNotNull(callback); + Assertions.assertEquals(LoggedOnCallback.class, callback.getClass()); + + var loc = (LoggedOnCallback) callback; + Assertions.assertEquals(EResult.NoConnection, loc.getResult()); + Assertions.assertEquals(asyncJob.getJobID(), loc.getJobID()); + } + + @Test + public void logOnAnonymousPostsLoggedOnCallbackWhenNoConnection() { + Mockito.when(steamClient.isConnected()).thenReturn(false); + + var asyncJob = handler.logOnAnonymous(); + + var callback = getCallback(); + Assertions.assertNotNull(callback); + Assertions.assertEquals(LoggedOnCallback.class, callback.getClass()); + + var loc = (LoggedOnCallback) callback; + Assertions.assertEquals(EResult.NoConnection, loc.getResult()); + Assertions.assertEquals(asyncJob.getJobID(), loc.getJobID()); + } +} diff --git a/src/test/java/in/dragonbra/javasteam/steam/handlers/steamuser/SteamUserTest.java b/src/test/java/in/dragonbra/javasteam/steam/handlers/steamuser/SteamUserTest.java index 11937d94..9e9a5f65 100644 --- a/src/test/java/in/dragonbra/javasteam/steam/handlers/steamuser/SteamUserTest.java +++ b/src/test/java/in/dragonbra/javasteam/steam/handlers/steamuser/SteamUserTest.java @@ -15,15 +15,13 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; +import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; import java.util.Date; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; - /** * @author lngtr * @since 2018-03-24 @@ -37,6 +35,82 @@ protected SteamUser createHandler() { return new SteamUser(); } + @Test + public void logOnPostsLoggedOnCallbackWhenNoConnection() { + Mockito.when(steamClient.isConnected()).thenReturn(false); + + var details = new LogOnDetails(); + details.setUsername("iamauser"); + details.setPassword("lamepassword"); + var asyncJob = handler.logOn(details); + + var callback = getCallback(); + Assertions.assertNotNull(callback); + Assertions.assertEquals(LoggedOnCallback.class, callback.getClass()); + + var loc = (LoggedOnCallback) callback; + Assertions.assertEquals(EResult.NoConnection, loc.getResult()); + Assertions.assertEquals(asyncJob.getJobID(), loc.getJobID()); + } + + @Test + public void logOnThrowsExceptionIfDetailsNotProvided() { + Assertions.assertThrows(IllegalArgumentException.class, () -> handler.logOn(new LogOnDetails())); + } + + @Test + public void logOnThrowsExceptionIfUsernameNotProvided_OnlyPassword() { + var details = new LogOnDetails(); + details.setPassword("def"); + Assertions.assertThrows(IllegalArgumentException.class, () -> handler.logOn(details)); + } + + @Test + public void logOnThrowsExceptionIfUsernameNotProvided_OnlyAccessToken() { + var details = new LogOnDetails(); + details.setAccessToken("def"); + Assertions.assertThrows(IllegalArgumentException.class, () -> handler.logOn(details)); + } + + @Test + public void logOnThrowsExceptionIfPasswordAndAccessTokenNotProvided() { + var details = new LogOnDetails(); + details.setUsername("abc"); + Assertions.assertThrows(IllegalArgumentException.class, () -> handler.logOn(details)); + } + + @Test + public void logOnDoesNotThrowExceptionIfUserNameAndPasswordProvided() { + var details = new LogOnDetails(); + details.setUsername("abc"); + details.setPassword("def"); + Assertions.assertDoesNotThrow(() -> handler.logOn(details)); + } + + @Test + public void logOnDoesNotThrowExceptionIfUserNameAndAccessTokenProvided() { + var details = new LogOnDetails(); + details.setUsername("abc"); + details.setPassword("def"); + details.setShouldRememberPassword(true); + Assertions.assertDoesNotThrow(() -> handler.logOn(details)); + } + + @Test + public void logOnAnonymousPostsLoggedOnCallbackWhenNoConnection() { + Mockito.when(steamClient.isConnected()).thenReturn(false); + + var asyncJob = handler.logOnAnonymous(); + + var callback = getCallback(); + Assertions.assertNotNull(callback); + Assertions.assertEquals(LoggedOnCallback.class, callback.getClass()); + + var loc = (LoggedOnCallback) callback; + Assertions.assertEquals(EResult.NoConnection, loc.getResult()); + Assertions.assertEquals(asyncJob.getJobID(), loc.getJobID()); + } + @Test public void logOn() { LogOnDetails details = new LogOnDetails(); @@ -47,14 +121,14 @@ public void logOn() { ClientMsgProtobuf msg = verifySend(EMsg.ClientLogon); - assertEquals("testusername", msg.getBody().getAccountName()); - assertEquals("testpassword", msg.getBody().getPassword()); + Assertions.assertEquals("testusername", msg.getBody().getAccountName()); + Assertions.assertEquals("testpassword", msg.getBody().getPassword()); } @Test public void logOnNotConnected() { - reset(steamClient); - when(steamClient.isConnected()).thenReturn(false); + Mockito.reset(steamClient); + Mockito.when(steamClient.isConnected()).thenReturn(false); LogOnDetails details = new LogOnDetails(); details.setUsername("testusername"); @@ -64,12 +138,12 @@ public void logOnNotConnected() { LoggedOnCallback callback = verifyCallback(); - assertEquals(EResult.NoConnection, callback.getResult()); + Assertions.assertEquals(EResult.NoConnection, callback.getResult()); } @Test public void logOnNoDetails() { - assertThrows(IllegalArgumentException.class, () -> { + Assertions.assertThrows(IllegalArgumentException.class, () -> { LogOnDetails details = new LogOnDetails(); handler.logOn(details); }); @@ -80,35 +154,35 @@ public void logOnAnonymous() { handler.logOnAnonymous(); ArgumentCaptor msgCaptor = ArgumentCaptor.forClass(IClientMsg.class); - verify(steamClient).send(msgCaptor.capture()); + Mockito.verify(steamClient).send(msgCaptor.capture()); ClientMsgProtobuf msg = verifySend(EMsg.ClientLogon); SteamID id = new SteamID(msg.getProtoHeader().getSteamid()); - assertEquals(EAccountType.AnonUser, id.getAccountType()); + Assertions.assertEquals(EAccountType.AnonUser, id.getAccountType()); } @Test public void logOnAnonymousNotConnected() { - reset(steamClient); - when(steamClient.isConnected()).thenReturn(false); + Mockito.reset(steamClient); + Mockito.when(steamClient.isConnected()).thenReturn(false); handler.logOnAnonymous(); LoggedOnCallback callback = verifyCallback(); - assertEquals(EResult.NoConnection, callback.getResult()); + Assertions.assertEquals(EResult.NoConnection, callback.getResult()); } @Test public void logOff() { handler.logOff(); - verify(steamClient).setExpectDisconnection(true); + Mockito.verify(steamClient).setExpectDisconnection(true); ClientMsgProtobuf msg = verifySend(EMsg.ClientLogOff); - assertNotNull(msg); + Assertions.assertNotNull(msg); } @Test @@ -119,7 +193,7 @@ public void handleLogonResponse() { LoggedOnCallback callback = verifyCallback(); - assertEquals(EResult.OK, callback.getResult()); + Assertions.assertEquals(EResult.OK, callback.getResult()); } @Test @@ -130,7 +204,7 @@ public void handleLogonResponseNonProto() { LoggedOnCallback callback = verifyCallback(); - assertEquals(EResult.OK, callback.getResult()); + Assertions.assertEquals(EResult.OK, callback.getResult()); } @Test @@ -141,7 +215,7 @@ public void handleLogOffResponse() { LoggedOffCallback callback = verifyCallback(); - assertEquals(EResult.OK, callback.getResult()); + Assertions.assertEquals(EResult.OK, callback.getResult()); } @Test @@ -152,7 +226,7 @@ public void handleLogOffResponseNonProto() { LoggedOffCallback callback = verifyCallback(); - assertEquals(EResult.OK, callback.getResult()); + Assertions.assertEquals(EResult.OK, callback.getResult()); } @Test @@ -163,7 +237,7 @@ public void handleSessionToken() { SessionTokenCallback callback = verifyCallback(); - assertEquals(123, callback.getSessionToken()); + Assertions.assertEquals(123, callback.getSessionToken()); } @Test @@ -174,8 +248,8 @@ public void handleAccountInfo() { AccountInfoCallback callback = verifyCallback(); - assertEquals("XX", callback.getCountry()); - assertEquals("testpersonaname", callback.getPersonaName()); + Assertions.assertEquals("XX", callback.getCountry()); + Assertions.assertEquals("testpersonaname", callback.getPersonaName()); } @Test @@ -186,10 +260,10 @@ public void handleWalletInfo() { WalletInfoCallback callback = verifyCallback(); - assertFalse(callback.isHasWallet()); - assertEquals(0, callback.getBalance()); - assertEquals(ECurrencyCode.Invalid, callback.getCurrency()); - assertEquals(0L, callback.getLongBalance()); + Assertions.assertFalse(callback.isHasWallet()); + Assertions.assertEquals(0, callback.getBalance()); + Assertions.assertEquals(ECurrencyCode.Invalid, callback.getCurrency()); + Assertions.assertEquals(0L, callback.getLongBalance()); } @Test @@ -200,8 +274,8 @@ public void handleWebAPIUserNonce() { WebAPIUserNonceCallback callback = verifyCallback(); - assertEquals(EResult.OK, callback.getResult()); - assertEquals("testnonce", callback.getNonce()); + Assertions.assertEquals(EResult.OK, callback.getResult()); + Assertions.assertEquals("testnonce", callback.getNonce()); } @Test @@ -212,8 +286,8 @@ public void handleMarketingMessageUpdate() { MarketingMessageCallback callback = verifyCallback(); - assertEquals(new Date(1521763200000L), callback.getUpdateTime()); - assertEquals(7, callback.getMessages().size()); + Assertions.assertEquals(new Date(1521763200000L), callback.getUpdateTime()); + Assertions.assertEquals(7, callback.getMessages().size()); } @Test diff --git a/src/test/java/in/dragonbra/javasteam/steam/steamclient/SteamClientTest.java b/src/test/java/in/dragonbra/javasteam/steam/steamclient/SteamClientTest.java index 59bac2f1..f6050409 100644 --- a/src/test/java/in/dragonbra/javasteam/steam/steamclient/SteamClientTest.java +++ b/src/test/java/in/dragonbra/javasteam/steam/steamclient/SteamClientTest.java @@ -3,7 +3,9 @@ import in.dragonbra.javasteam.base.IPacketMsg; import in.dragonbra.javasteam.steam.handlers.ClientMsgHandler; import in.dragonbra.javasteam.steam.handlers.steamapps.SteamApps; +import in.dragonbra.javasteam.steam.handlers.steamauthticket.SteamAuthTicket; import in.dragonbra.javasteam.steam.handlers.steamcloud.SteamCloud; +import in.dragonbra.javasteam.steam.handlers.steamcontent.SteamContent; import in.dragonbra.javasteam.steam.handlers.steamfriends.SteamFriends; import in.dragonbra.javasteam.steam.handlers.steamgamecoordinator.SteamGameCoordinator; import in.dragonbra.javasteam.steam.handlers.steamgameserver.SteamGameServer; @@ -55,11 +57,12 @@ public void handlersCountCheck() { @Test public void constructorSetsInitialHandlers() { - Assertions.assertNotNull(client.getHandler(SteamFriends.class)); Assertions.assertNotNull(client.getHandler(SteamUser.class)); + Assertions.assertNotNull(client.getHandler(SteamFriends.class)); Assertions.assertNotNull(client.getHandler(SteamApps.class)); Assertions.assertNotNull(client.getHandler(SteamGameCoordinator.class)); Assertions.assertNotNull(client.getHandler(SteamGameServer.class)); + Assertions.assertNotNull(client.getHandler(SteamUserStats.class)); Assertions.assertNotNull(client.getHandler(SteamMasterServer.class)); Assertions.assertNotNull(client.getHandler(SteamCloud.class)); Assertions.assertNotNull(client.getHandler(SteamWorkshop.class)); @@ -67,8 +70,9 @@ public void constructorSetsInitialHandlers() { Assertions.assertNotNull(client.getHandler(SteamScreenshots.class)); Assertions.assertNotNull(client.getHandler(SteamMatchmaking.class)); Assertions.assertNotNull(client.getHandler(SteamNetworking.class)); + Assertions.assertNotNull(client.getHandler(SteamContent.class)); + Assertions.assertNotNull(client.getHandler(SteamAuthTicket.class)); Assertions.assertNotNull(client.getHandler(SteamNotifications.class)); - Assertions.assertNotNull(client.getHandler(SteamUserStats.class)); } @Test @@ -99,6 +103,39 @@ public void removeHandlerRemovesHandlerByInstance() { Assertions.assertNull(client.getHandler(TestMsgHandler.class)); } + @Test + public void addHandlerThrowsOnDuplicateHandler() { + var steamClient = new SteamClient(); + steamClient.addHandler(new TestMsgHandler()); + + Assertions.assertThrows(IllegalArgumentException.class, () -> steamClient.addHandler(new TestMsgHandler())); + } + + @Test + public void removeHandlerByTypeDoesNothingWhenNotRegistered() { + var steamClient = new SteamClient(); + Assertions.assertNull(client.getHandler(TestMsgHandler.class)); + + steamClient.removeHandler(TestMsgHandler.class); + Assertions.assertNull(client.getHandler(TestMsgHandler.class)); + } + + @Test + public void getRequiredHandlerReturnsHandler() { + var steamClient = new SteamClient(); + var handler = steamClient.getRequiredHandler(SteamUser.class); + + Assertions.assertNotNull(handler); + Assertions.assertEquals(SteamUser.class, handler.getClass()); + } + + @Test + public void getRequiredHandlerThrowsWhenNotRegistered() { + var steamClient = new SteamClient(); + + Assertions.assertThrows(IllegalArgumentException.class, () -> steamClient.getRequiredHandler(TestMsgHandler.class)); + } + @Test public void getNextJobIDSetsProcessIDToZero() { var jobID = client.getNextJobID();