From 05cdbf98d783268b9fd015687f0742c9f33ca524 Mon Sep 17 00:00:00 2001 From: ShellWen Chen Date: Sat, 6 Apr 2024 11:20:17 +0000 Subject: [PATCH] refactor: migrate `NetworkPacket` to Kotlin --- .../BluetoothBackend/BluetoothLink.kt | 2 +- src/org/kde/kdeconnect/DeviceInfo.kt | 4 +- src/org/kde/kdeconnect/NetworkPacket.java | 332 ------------------ src/org/kde/kdeconnect/NetworkPacket.kt | 291 +++++++++++++++ .../org/kde/kdeconnect/NetworkPacketTest.java | 93 ----- tests/org/kde/kdeconnect/NetworkPacketTest.kt | 86 +++++ 6 files changed, 380 insertions(+), 428 deletions(-) delete mode 100644 src/org/kde/kdeconnect/NetworkPacket.java create mode 100644 src/org/kde/kdeconnect/NetworkPacket.kt delete mode 100644 tests/org/kde/kdeconnect/NetworkPacketTest.java create mode 100644 tests/org/kde/kdeconnect/NetworkPacketTest.kt diff --git a/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothLink.kt b/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothLink.kt index 765296aa..3162945e 100644 --- a/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothLink.kt +++ b/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothLink.kt @@ -144,7 +144,7 @@ class BluetoothLink(context: Context?, connection: ConnectionMultiplexer, input: val buffer = ByteArray(BUFFER_LENGTH) var bytesRead: Int var progress: Long = 0 - val stream = np.payload.inputStream + val stream = np.payload!!.inputStream!! while (stream.read(buffer).also { bytesRead = it } != -1) { progress += bytesRead.toLong() payloadStream.write(buffer, 0, bytesRead) diff --git a/src/org/kde/kdeconnect/DeviceInfo.kt b/src/org/kde/kdeconnect/DeviceInfo.kt index 59e26d6d..63687c7e 100644 --- a/src/org/kde/kdeconnect/DeviceInfo.kt +++ b/src/org/kde/kdeconnect/DeviceInfo.kt @@ -60,8 +60,8 @@ class DeviceInfo( np.set("deviceName", name) np.set("protocolVersion", protocolVersion) np.set("deviceType", type.toString()) - np.set("incomingCapabilities", incomingCapabilities) - np.set("outgoingCapabilities", outgoingCapabilities) + np.set("incomingCapabilities", incomingCapabilities!!) + np.set("outgoingCapabilities", outgoingCapabilities!!) } companion object { diff --git a/src/org/kde/kdeconnect/NetworkPacket.java b/src/org/kde/kdeconnect/NetworkPacket.java deleted file mode 100644 index 5c75a8e6..00000000 --- a/src/org/kde/kdeconnect/NetworkPacket.java +++ /dev/null @@ -1,332 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2014 Albert Vaca Cintora - * - * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL -*/ - -package org.kde.kdeconnect; - -import org.apache.commons.io.IOUtils; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.Socket; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -public class NetworkPacket { - - public final static String PACKET_TYPE_IDENTITY = "kdeconnect.identity"; - public final static String PACKET_TYPE_PAIR = "kdeconnect.pair"; - - public final static int PACKET_REPLACEID_MOUSEMOVE = 0; - public final static int PACKET_REPLACEID_PRESENTERPOINTER = 1; - - public static Set protocolPacketTypes = new HashSet() {{ - add(PACKET_TYPE_IDENTITY); - add(PACKET_TYPE_PAIR); - }}; - - private long mId; - String mType; - private JSONObject mBody; - private Payload mPayload; - private JSONObject mPayloadTransferInfo; - private volatile boolean canceled; - - private NetworkPacket() { - - } - - public NetworkPacket(String type) { - mId = System.currentTimeMillis(); - mType = type; - mBody = new JSONObject(); - mPayload = null; - mPayloadTransferInfo = new JSONObject(); - } - - public boolean isCanceled() { return canceled; } - public void cancel() { canceled = true; } - - public String getType() { - return mType; - } - - public long getId() { - return mId; - } - - //Most commons getters and setters defined for convenience - public String getString(String key) { - return mBody.optString(key, ""); - } - - public String getString(String key, String defaultValue) { - return mBody.optString(key, defaultValue); - } - - public void set(String key, String value) { - if (value == null) return; - try { - mBody.put(key, value); - } catch (Exception ignored) { - } - } - - public int getInt(String key) { - return mBody.optInt(key, -1); - } - - public int getInt(String key, int defaultValue) { - return mBody.optInt(key, defaultValue); - } - - public void set(String key, int value) { - try { - mBody.put(key, value); - } catch (Exception ignored) { - } - } - - public long getLong(String key) { - return mBody.optLong(key, -1); - } - - public long getLong(String key, long defaultValue) { - return mBody.optLong(key, defaultValue); - } - - public void set(String key, long value) { - try { - mBody.put(key, value); - } catch (Exception ignored) { - } - } - - public boolean getBoolean(String key) { - return mBody.optBoolean(key, false); - } - - public boolean getBoolean(String key, boolean defaultValue) { - return mBody.optBoolean(key, defaultValue); - } - - public void set(String key, boolean value) { - try { - mBody.put(key, value); - } catch (Exception ignored) { - } - } - - public double getDouble(String key) { - return mBody.optDouble(key, Double.NaN); - } - - public double getDouble(String key, double defaultValue) { - return mBody.optDouble(key, defaultValue); - } - - public void set(String key, double value) { - try { - mBody.put(key, value); - } catch (Exception ignored) { - } - } - - public JSONArray getJSONArray(String key) { - return mBody.optJSONArray(key); - } - - public void set(String key, JSONArray value) { - try { - mBody.put(key, value); - } catch (Exception ignored) { - } - } - - public JSONObject getJSONObject(String key) { - return mBody.optJSONObject(key); - } - - public void set(String key, JSONObject value) { - try { - mBody.put(key, value); - } catch (JSONException ignored) { - } - } - - public Set getStringSet(String key) { - JSONArray jsonArray = mBody.optJSONArray(key); - if (jsonArray == null) return null; - Set list = new HashSet<>(); - int length = jsonArray.length(); - for (int i = 0; i < length; i++) { - try { - String str = jsonArray.getString(i); - list.add(str); - } catch (Exception ignored) { - } - } - return list; - } - - public Set getStringSet(String key, Set defaultValue) { - if (mBody.has(key)) return getStringSet(key); - else return defaultValue; - } - - public void set(String key, Set value) { - try { - JSONArray jsonArray = new JSONArray(); - for (String str : value) { - jsonArray.put(str); - } - mBody.put(key, jsonArray); - } catch (Exception ignored) { - } - } - - public List getStringList(String key) { - JSONArray jsonArray = mBody.optJSONArray(key); - if (jsonArray == null) return null; - List list = new ArrayList<>(); - int length = jsonArray.length(); - for (int i = 0; i < length; i++) { - try { - String str = jsonArray.getString(i); - list.add(str); - } catch (Exception ignored) { - } - } - return list; - } - - public List getStringList(String key, List defaultValue) { - if (mBody.has(key)) return getStringList(key); - else return defaultValue; - } - - public void set(String key, List value) { - try { - JSONArray jsonArray = new JSONArray(); - for (String str : value) { - jsonArray.put(str); - } - mBody.put(key, jsonArray); - } catch (Exception ignored) { - } - } - - public boolean has(String key) { - return mBody.has(key); - } - - public String serialize() throws JSONException { - JSONObject jo = new JSONObject(); - jo.put("id", mId); - jo.put("type", mType); - jo.put("body", mBody); - if (hasPayload()) { - jo.put("payloadSize", mPayload.payloadSize); - jo.put("payloadTransferInfo", mPayloadTransferInfo); - } - //QJSon does not escape slashes, but Java JSONObject does. Converting to QJson format. - return jo.toString().replace("\\/", "/") + "\n"; - } - - static public NetworkPacket unserialize(String s) throws JSONException { - - NetworkPacket np = new NetworkPacket(); - JSONObject jo = new JSONObject(s); - np.mId = jo.getLong("id"); - np.mType = jo.getString("type"); - np.mBody = jo.getJSONObject("body"); - if (jo.has("payloadSize")) { - np.mPayloadTransferInfo = jo.getJSONObject("payloadTransferInfo"); - np.mPayload = new Payload(jo.getLong("payloadSize")); - } else { - np.mPayloadTransferInfo = new JSONObject(); - np.mPayload = new Payload(0); - } - return np; - } - - public void setPayload(Payload payload) { mPayload = payload; } - - public Payload getPayload() { - return mPayload; - } - - public long getPayloadSize() { - return mPayload == null ? 0 : mPayload.payloadSize; - } - - public boolean hasPayload() { - return (mPayload != null && mPayload.payloadSize != 0); - } - - public boolean hasPayloadTransferInfo() { - return (mPayloadTransferInfo.length() > 0); - } - - public JSONObject getPayloadTransferInfo() { - return mPayloadTransferInfo; - } - - public void setPayloadTransferInfo(JSONObject payloadTransferInfo) { - mPayloadTransferInfo = payloadTransferInfo; - } - - public static class Payload { - private final InputStream inputStream; - private final Socket inputSocket; - private final long payloadSize; - - public Payload(long payloadSize) { - this((InputStream)null, payloadSize); - } - - public Payload(byte[] data) { - this(new ByteArrayInputStream(data), data.length); - } - - /** - * NOTE: Do not use this to set an SSLSockets InputStream as the payload, use Payload(Socket, long) instead because of this bug - */ - public Payload(InputStream inputStream, long payloadSize) { - this.inputSocket = null; - this.inputStream = inputStream; - this.payloadSize = payloadSize; - } - - public Payload(Socket inputSocket, long payloadSize) throws IOException { - this.inputSocket = inputSocket; - this.inputStream = inputSocket.getInputStream(); - this.payloadSize = payloadSize; - } - - /** - * NOTE: Do not close the InputStream directly call Payload.close() instead, this is because of this bug - */ - public InputStream getInputStream() { return inputStream; } - long getPayloadSize() { return payloadSize; } - - public void close() { - //TODO: If socket only close socket if that also closes the streams that is - try { - IOUtils.close(inputStream); - } catch(IOException ignored) {} - - try { - IOUtils.close(inputSocket); - } catch (IOException ignored) {} - } - } -} diff --git a/src/org/kde/kdeconnect/NetworkPacket.kt b/src/org/kde/kdeconnect/NetworkPacket.kt new file mode 100644 index 00000000..f52dd3b6 --- /dev/null +++ b/src/org/kde/kdeconnect/NetworkPacket.kt @@ -0,0 +1,291 @@ +/* + * SPDX-FileCopyrightText: 2014 Albert Vaca Cintora + * + * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL +*/ +package org.kde.kdeconnect + +import org.json.JSONArray +import org.json.JSONException +import org.json.JSONObject +import java.io.ByteArrayInputStream +import java.io.IOException +import java.io.InputStream +import java.net.Socket +import kotlin.concurrent.Volatile + +data class NetworkPacket( + val id: Long, + val type: String, + val mBody: JSONObject, + var payload: Payload?, + var payloadTransferInfo: JSONObject, +) { + constructor(type: String) : this( + id = System.currentTimeMillis(), + type = type, + mBody = JSONObject(), + payload = null, + payloadTransferInfo = JSONObject() + ) + + @Volatile + var isCanceled: Boolean = false + private set + + fun cancel() { + isCanceled = true + } + + // Most commons getters and setters defined for convenience + fun getString(key: String): String { + return mBody.optString(key, "") + } + + fun getString(key: String, defaultValue: String): String { + return mBody.optString(key, defaultValue) + } + + operator fun set(key: String, value: String?) { + if (value == null) return + try { + mBody.put(key, value) + } catch (ignored: Exception) { + } + } + + fun getInt(key: String): Int { + return mBody.optInt(key, -1) + } + + fun getInt(key: String, defaultValue: Int): Int { + return mBody.optInt(key, defaultValue) + } + + operator fun set(key: String, value: Int) { + try { + mBody.put(key, value) + } catch (ignored: Exception) { + } + } + + fun getLong(key: String): Long { + return mBody.optLong(key, -1) + } + + fun getLong(key: String, defaultValue: Long): Long { + return mBody.optLong(key, defaultValue) + } + + operator fun set(key: String, value: Long) { + try { + mBody.put(key, value) + } catch (ignored: Exception) { + } + } + + fun getBoolean(key: String): Boolean { + return mBody.optBoolean(key, false) + } + + fun getBoolean(key: String, defaultValue: Boolean): Boolean { + return mBody.optBoolean(key, defaultValue) + } + + operator fun set(key: String, value: Boolean) { + try { + mBody.put(key, value) + } catch (ignored: Exception) { + } + } + + fun getDouble(key: String): Double { + return mBody.optDouble(key, Double.NaN) + } + + fun getDouble(key: String, defaultValue: Double): Double { + return mBody.optDouble(key, defaultValue) + } + + operator fun set(key: String, value: Double) { + try { + mBody.put(key, value) + } catch (ignored: Exception) { + } + } + + fun getJSONArray(key: String): JSONArray? { + return mBody.optJSONArray(key) + } + + operator fun set(key: String, value: JSONArray?) { + try { + mBody.put(key, value) + } catch (ignored: Exception) { + } + } + + fun getJSONObject(key: String): JSONObject? { + return mBody.optJSONObject(key) + } + + operator fun set(key: String, value: JSONObject?) { + try { + mBody.put(key, value) + } catch (ignored: JSONException) { + } + } + + fun getStringSet(key: String): Set? { + val jsonArray = mBody.optJSONArray(key) ?: return null + val list: MutableSet = HashSet() + val length = jsonArray.length() + for (i in 0 until length) { + try { + val str = jsonArray.getString(i) + list.add(str) + } catch (ignored: Exception) { + } + } + return list + } + + fun getStringSet(key: String, defaultValue: Set?): Set? { + return if (mBody.has(key)) getStringSet(key) + else defaultValue + } + + operator fun set(key: String, value: Set) { + try { + val jsonArray = JSONArray() + for (str in value) { + jsonArray.put(str) + } + mBody.put(key, jsonArray) + } catch (ignored: Exception) { + } + } + + fun getStringList(key: String): List? { + val jsonArray = mBody.optJSONArray(key) ?: return null + val list: MutableList = ArrayList() + val length = jsonArray.length() + for (i in 0 until length) { + try { + val str = jsonArray.getString(i) + list.add(str) + } catch (ignored: Exception) { + } + } + return list + } + + fun getStringList(key: String, defaultValue: List?): List? { + return if (mBody.has(key)) getStringList(key) + else defaultValue + } + + operator fun set(key: String, value: List) { + try { + val jsonArray = JSONArray() + for (str in value) { + jsonArray.put(str) + } + mBody.put(key, jsonArray) + } catch (ignored: Exception) { + } + } + + fun has(key: String): Boolean { + return mBody.has(key) + } + + @Throws(JSONException::class) + fun serialize(): String { + val jo = JSONObject() + jo.put("id", id) + jo.put("type", type) + jo.put("body", mBody) + if (hasPayload()) { + jo.put("payloadSize", payload!!.payloadSize) + jo.put("payloadTransferInfo", payloadTransferInfo) + } + // QJSon does not escape slashes, but Java JSONObject does. Converting to QJson format. + return jo.toString().replace("\\/", "/") + "\n" + } + + val payloadSize: Long + get() = payload?.payloadSize ?: 0 + + fun hasPayload(): Boolean { + val payload = payload + return payload != null && payload.payloadSize != 0L + } + + fun hasPayloadTransferInfo(): Boolean { + return payloadTransferInfo.length() > 0 + } + + class Payload { + /** + * **NOTE: Do not close the InputStream directly call Payload.close() instead, this is because of this [bug](https://issuetracker.google.com/issues/37018094)** + */ + val inputStream: InputStream? + private val inputSocket: Socket? + val payloadSize: Long + + constructor(payloadSize: Long) : this(null, payloadSize) + + constructor(data: ByteArray) : this(ByteArrayInputStream(data), data.size.toLong()) + + /** + * **NOTE: Do not use this to set an SSLSockets InputStream as the payload, use Payload(Socket, long) instead because of this [bug](https://issuetracker.google.com/issues/37018094)** + */ + constructor(inputStream: InputStream?, payloadSize: Long) { + this.inputSocket = null + this.inputStream = inputStream + this.payloadSize = payloadSize + } + + constructor(inputSocket: Socket, payloadSize: Long) { + this.inputSocket = inputSocket + this.inputStream = inputSocket.getInputStream() + this.payloadSize = payloadSize + } + + fun close() { + // TODO: If socket only close socket if that also closes the streams that is + try { + inputStream?.close() + } catch (ignored: IOException) { + } + + try { + inputSocket?.close() + } catch (ignored: IOException) { + } + } + } + + companion object { + const val PACKET_TYPE_IDENTITY: String = "kdeconnect.identity" + const val PACKET_TYPE_PAIR: String = "kdeconnect.pair" + + const val PACKET_REPLACEID_MOUSEMOVE: Int = 0 + const val PACKET_REPLACEID_PRESENTERPOINTER: Int = 1 + + @JvmStatic + @Throws(JSONException::class) + fun unserialize(s: String): NetworkPacket { + val jo = JSONObject(s) + val id = jo.getLong("id") + val type = jo.getString("type") + val mBody = jo.getJSONObject("body") + + val hasPayload = jo.has("payloadSize") + val payloadTransferInfo = if (hasPayload) jo.getJSONObject("payloadTransferInfo") else JSONObject() + val payload = if (hasPayload) Payload(jo.getLong("payloadSize")) else null + return NetworkPacket(id, type, mBody, payload, payloadTransferInfo) + } + } +} diff --git a/tests/org/kde/kdeconnect/NetworkPacketTest.java b/tests/org/kde/kdeconnect/NetworkPacketTest.java deleted file mode 100644 index 458cef72..00000000 --- a/tests/org/kde/kdeconnect/NetworkPacketTest.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015 Vineet Garg - * - * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL -*/ - -package org.kde.kdeconnect; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; - -import android.util.Log; - -import org.json.JSONException; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.kde.kdeconnect.Helpers.DeviceHelper; -import org.mockito.Mockito; -import org.mockito.internal.util.collections.Sets; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; - -import java.security.cert.Certificate; - -@RunWith(PowerMockRunner.class) -@PrepareForTest({DeviceHelper.class, Log.class}) -public class NetworkPacketTest { - - @Before - public void setUp() { - PowerMockito.mockStatic(DeviceHelper.class); - PowerMockito.when(DeviceHelper.getDeviceId(any())).thenReturn("123"); - PowerMockito.when(DeviceHelper.getDeviceType(any())).thenReturn(DeviceType.PHONE); - - PowerMockito.mockStatic(Log.class); - } - - @Test - public void testNetworkPacket() throws JSONException { - NetworkPacket np = new NetworkPacket("com.test"); - - np.set("hello", "hola"); - assertEquals(np.getString("hello", "bye"), "hola"); - - np.set("hello", ""); - assertEquals(np.getString("hello", "bye"), ""); - - assertEquals(np.getString("hi", "bye"), "bye"); - - np.set("foo", "bar"); - String serialized = np.serialize(); - NetworkPacket np2 = NetworkPacket.unserialize(serialized); - - assertEquals(np.getLong("id"), np2.getLong("id")); - assertEquals(np.getString("type"), np2.getString("type")); - assertEquals(np.getJSONArray("body"), np2.getJSONArray("body")); - - String json = "{\"id\":123,\"type\":\"test\",\"body\":{\"testing\":true}}"; - np2 = NetworkPacket.unserialize(json); - assertEquals(np2.getId(), 123); - assertTrue(np2.getBoolean("testing")); - assertFalse(np2.getBoolean("not_testing")); - assertTrue(np2.getBoolean("not_testing", true)); - - } - - @Test - public void testIdentity() { - Certificate cert = Mockito.mock(Certificate.class); - - DeviceInfo deviceInfo = new DeviceInfo("myid", cert, "myname", DeviceType.TV, 12, Sets.newSet("ASDFG"), Sets.newSet("QWERTY")); - - NetworkPacket np = deviceInfo.toIdentityPacket(); - - assertEquals(np.getInt("protocolVersion"), 12); - - DeviceInfo parsed = DeviceInfo.fromIdentityPacketAndCert(np, cert); - - assertEquals(parsed.name, deviceInfo.name); - assertEquals(parsed.id, deviceInfo.id); - assertEquals(parsed.type, deviceInfo.type); - assertEquals(parsed.protocolVersion, deviceInfo.protocolVersion); - assertEquals(parsed.incomingCapabilities, deviceInfo.incomingCapabilities); - assertEquals(parsed.outgoingCapabilities, deviceInfo.outgoingCapabilities); - - - } - -} diff --git a/tests/org/kde/kdeconnect/NetworkPacketTest.kt b/tests/org/kde/kdeconnect/NetworkPacketTest.kt new file mode 100644 index 00000000..3688a14e --- /dev/null +++ b/tests/org/kde/kdeconnect/NetworkPacketTest.kt @@ -0,0 +1,86 @@ +/* + * SPDX-FileCopyrightText: 2015 Vineet Garg + * + * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL +*/ +package org.kde.kdeconnect + +import android.util.Log +import org.json.JSONException +import org.junit.Assert +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.kde.kdeconnect.DeviceInfo.Companion.fromIdentityPacketAndCert +import org.kde.kdeconnect.Helpers.DeviceHelper +import org.kde.kdeconnect.NetworkPacket.Companion.unserialize +import org.mockito.ArgumentMatchers +import org.mockito.Mockito +import org.mockito.internal.util.collections.Sets +import org.powermock.api.mockito.PowerMockito +import org.powermock.core.classloader.annotations.PrepareForTest +import org.powermock.modules.junit4.PowerMockRunner +import java.security.cert.Certificate + +@RunWith(PowerMockRunner::class) +@PrepareForTest(DeviceHelper::class, Log::class) +class NetworkPacketTest { + @Before + fun setUp() { + PowerMockito.mockStatic(DeviceHelper::class.java) + PowerMockito.`when`(DeviceHelper.getDeviceId(ArgumentMatchers.any())).thenReturn("123") + PowerMockito.`when`(DeviceHelper.getDeviceType(ArgumentMatchers.any())).thenReturn(DeviceType.PHONE) + + PowerMockito.mockStatic(Log::class.java) + } + + @Test + @Throws(JSONException::class) + fun testNetworkPacket() { + val np = NetworkPacket("com.test") + + np["hello"] = "hola" + Assert.assertEquals(np.getString("hello", "bye"), "hola") + + np["hello"] = "" + Assert.assertEquals(np.getString("hello", "bye"), "") + + Assert.assertEquals(np.getString("hi", "bye"), "bye") + + np["foo"] = "bar" + val serialized = np.serialize() + var np2 = unserialize(serialized) + + Assert.assertEquals(np.getLong("id"), np2.getLong("id")) + Assert.assertEquals(np.getString("type"), np2.getString("type")) + Assert.assertEquals(np.getJSONArray("body"), np2.getJSONArray("body")) + + val json = "{\"id\":123,\"type\":\"test\",\"body\":{\"testing\":true}}" + np2 = unserialize(json) + Assert.assertEquals(np2.id, 123) + Assert.assertTrue(np2.getBoolean("testing")) + Assert.assertFalse(np2.getBoolean("not_testing")) + Assert.assertTrue(np2.getBoolean("not_testing", true)) + } + + @Test + fun testIdentity() { + val cert = Mockito.mock(Certificate::class.java) + + val deviceInfo = + DeviceInfo("myid", cert, "myname", DeviceType.TV, 12, Sets.newSet("ASDFG"), Sets.newSet("QWERTY")) + + val np = deviceInfo.toIdentityPacket() + + Assert.assertEquals(np.getInt("protocolVersion").toLong(), 12) + + val parsed = fromIdentityPacketAndCert(np, cert) + + Assert.assertEquals(parsed.name, deviceInfo.name) + Assert.assertEquals(parsed.id, deviceInfo.id) + Assert.assertEquals(parsed.type, deviceInfo.type) + Assert.assertEquals(parsed.protocolVersion.toLong(), deviceInfo.protocolVersion.toLong()) + Assert.assertEquals(parsed.incomingCapabilities, deviceInfo.incomingCapabilities) + Assert.assertEquals(parsed.outgoingCapabilities, deviceInfo.outgoingCapabilities) + } +}