2
0
mirror of https://github.com/KDE/kdeconnect-android synced 2025-08-30 13:47:41 +00:00

Migrate DeviceTest to Kotlin

This commit is contained in:
TPJ Schikhof 2024-09-02 10:29:16 +00:00 committed by Albert Vaca Cintora
parent 9037647281
commit 7ebac70d47
2 changed files with 269 additions and 253 deletions

View File

@ -1,253 +0,0 @@
/*
* SPDX-FileCopyrightText: 2015 Vineet Garg <grg.vineet@gmail.com>
*
* 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.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import android.app.NotificationManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Base64;
import androidx.core.content.ContextCompat;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.kde.kdeconnect.Backends.LanBackend.LanLink;
import org.kde.kdeconnect.Backends.LanBackend.LanLinkProvider;
import org.kde.kdeconnect.Helpers.DeviceHelper;
import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper;
import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.util.Arrays;
import java.util.HashSet;
public class DeviceTest {
private Context context;
MockedStatic<Base64> mockBase64;
MockedStatic<PreferenceManager> preferenceManager;
MockedStatic<ContextCompat> contextCompat;
@After
public void tearDown() {
mockBase64.close();
preferenceManager.close();
contextCompat.close();
}
// Creating a paired device before each test case
@Before
public void setUp() {
// Save new test device in settings
String deviceId = "testDevice";
String name = "Test Device";
String encodedCertificate = "MIIDVzCCAj+gAwIBAgIBCjANBgkqhkiG9w0BAQUFADBVMS8wLQYDVQQDDCZfZGExNzlhOTFfZjA2\n" +
"NF80NzhlX2JlOGNfMTkzNWQ3NTQ0ZDU0XzEMMAoGA1UECgwDS0RFMRQwEgYDVQQLDAtLZGUgY29u\n" +
"bmVjdDAeFw0xNTA2MDMxMzE0MzhaFw0yNTA2MDMxMzE0MzhaMFUxLzAtBgNVBAMMJl9kYTE3OWE5\n" +
"MV9mMDY0XzQ3OGVfYmU4Y18xOTM1ZDc1NDRkNTRfMQwwCgYDVQQKDANLREUxFDASBgNVBAsMC0tk\n" +
"ZSBjb25uZWN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzH9GxS1lctpwYdSGAoPH\n" +
"ws+MnVaL0PVDCuzrpxzXc+bChR87xofhQIesLPLZEcmUJ1MlEJ6jx4W+gVhvY2tUN7SoiKKbnq8s\n" +
"WjI5ovs5yML3C1zPbOSJAdK613FcdkK+UGd/9dQk54gIozinC58iyTAChVVpB3pAF38EPxwKkuo2\n" +
"qTzwk24d6PRxz1skkzwEphUQQzGboyHsAlJHN1MzM2/yFGB4l8iUua2d3ETyfy/xFEh/SwtGtXE5\n" +
"KLz4cpb0fxjeYQZVruBKxzE07kgDO3zOhmP3LJ/KSPHWYImd1DWmpY9iDvoXr6+V7FAnRloaEIyg\n" +
"7WwdlSCpo3TXVuIjLwIDAQABozIwMDAdBgNVHQ4EFgQUwmbHo8YbiR463GRKSLL3eIKyvDkwDwYD\n" +
"VR0TAQH/BAUwAwIBADANBgkqhkiG9w0BAQUFAAOCAQEAydijH3rbnvpBDB/30w2PCGMT7O0N/XYM\n" +
"wBtUidqa4NFumJrNrccx5Ehp4UP66BfP61HW8h2U/EekYfOsZyyWd4KnsDD6ycR8h/WvpK3BC2cn\n" +
"I299wbqCEZmk5ZFFaEIDHdLAdgMCuxJkAzy9mMrWEa05Soxi2/ZXdrU9nXo5dzuPGYlirVPDHl7r\n" +
"/urBxD6HVX3ObQJRJ7r/nAWyUVdX3/biJaDRsydftOpGU6Gi5c1JK4MWIz8Bsjh6mEjCsVatbPPl\n" +
"yygGiJbDZfAvN2XoaVEBii2GDDCWfaFwPVPYlNTvjkUkMP8YThlMsiJ8Q4693XoLOL94GpNlCfUg\n" +
"7n+KOQ==";
this.context = Mockito.mock(Context.class);
mockBase64 = Mockito.mockStatic(Base64.class);
mockBase64.when(() -> Base64.encodeToString(any(byte[].class), anyInt())).thenAnswer(invocation -> java.util.Base64.getMimeEncoder().encodeToString((byte[]) invocation.getArguments()[0]));
mockBase64.when(() -> Base64.decode(anyString(), anyInt())).thenAnswer(invocation -> java.util.Base64.getMimeDecoder().decode((String) invocation.getArguments()[0]));
//Store device information needed to create a Device object in a future
MockSharedPreference deviceSettings = new MockSharedPreference();
SharedPreferences.Editor editor = deviceSettings.edit();
editor.putString("deviceName", name);
editor.putString("deviceType", DeviceType.PHONE.toString());
editor.putString("certificate", encodedCertificate);
editor.apply();
Mockito.when(context.getSharedPreferences(eq(deviceId), eq(Context.MODE_PRIVATE))).thenReturn(deviceSettings);
//Store the device as trusted
MockSharedPreference trustedSettings = new MockSharedPreference();
trustedSettings.edit().putBoolean(deviceId, true).apply();
Mockito.when(context.getSharedPreferences(eq("trusted_devices"), eq(Context.MODE_PRIVATE))).thenReturn(trustedSettings);
//Store an untrusted device
MockSharedPreference untrustedSettings = new MockSharedPreference();
Mockito.when(context.getSharedPreferences(eq("unpairedTestDevice"), eq(Context.MODE_PRIVATE))).thenReturn(untrustedSettings);
//Default shared prefs, including our own private key
preferenceManager = Mockito.mockStatic(PreferenceManager.class);
MockSharedPreference defaultSettings = new MockSharedPreference();
preferenceManager.when(() -> PreferenceManager.getDefaultSharedPreferences(any(Context.class))).thenReturn(defaultSettings);
RsaHelper.initialiseRsaKeys(context);
contextCompat = Mockito.mockStatic(ContextCompat.class);
contextCompat.when(() -> ContextCompat.getSystemService(context, NotificationManager.class)).thenReturn(Mockito.mock(NotificationManager.class));
}
@Test
public void testDeviceInfoToIdentityPacket() throws CertificateException {
String deviceId = "testDevice";
SharedPreferences settings = context.getSharedPreferences(deviceId, Context.MODE_PRIVATE);
DeviceInfo di = DeviceInfo.loadFromSettings(context, deviceId, settings);
di.protocolVersion = DeviceHelper.ProtocolVersion;
di.incomingCapabilities = new HashSet<>(Arrays.asList("kdeconnect.plugin1State", "kdeconnect.plugin2State"));
di.outgoingCapabilities = new HashSet<>(Arrays.asList("kdeconnect.plugin1State.request", "kdeconnect.plugin2State.request"));
NetworkPacket np = di.toIdentityPacket();
assertEquals(di.id, np.getString("deviceId"));
assertEquals(di.name, np.getString("deviceName"));
assertEquals(di.protocolVersion, np.getInt("protocolVersion"));
assertEquals(di.type.toString(), np.getString("deviceType"));
assertEquals(di.incomingCapabilities, np.getStringSet("incomingCapabilities"));
assertEquals(di.outgoingCapabilities, np.getStringSet("outgoingCapabilities"));
}
@Test
public void testIsValidIdentityPacket() {
NetworkPacket np = new NetworkPacket(NetworkPacket.PACKET_TYPE_IDENTITY);
assertFalse(DeviceInfo.Companion.isValidIdentityPacket(np));
String validName = "MyDevice";
String validId = "123";
np.set("deviceName", validName);
np.set("deviceId", validId);
assertTrue(DeviceInfo.Companion.isValidIdentityPacket(np));
np.set("deviceName", " ");
assertFalse(DeviceInfo.Companion.isValidIdentityPacket(np));
np.set("deviceName", "<><><><><><><><><>"); // Only invalid characters
assertFalse(DeviceInfo.Companion.isValidIdentityPacket(np));
np.set("deviceName", validName);
np.set("deviceId", " ");
assertFalse(DeviceInfo.Companion.isValidIdentityPacket(np));
}
@Test
public void testDeviceType() {
assertEquals(DeviceType.PHONE, DeviceType.fromString(DeviceType.PHONE.toString()));
assertEquals(DeviceType.TABLET, DeviceType.fromString(DeviceType.TABLET.toString()));
assertEquals(DeviceType.DESKTOP, DeviceType.fromString(DeviceType.DESKTOP.toString()));
assertEquals(DeviceType.LAPTOP, DeviceType.fromString(DeviceType.LAPTOP.toString()));
assertEquals(DeviceType.TV, DeviceType.fromString(DeviceType.TV.toString()));
assertEquals(DeviceType.DESKTOP, DeviceType.fromString("invalid"));
}
// Basic paired device testing
@Test
public void testDevice() throws CertificateException {
Device device = new Device(context, "testDevice");
assertEquals(device.getDeviceId(), "testDevice");
assertEquals(device.getDeviceType(), DeviceType.PHONE);
assertEquals(device.getName(), "Test Device");
assertTrue(device.isPaired());
assertNotNull(device.getDeviceInfo().certificate);
}
@Test
public void testPairingDone() throws CertificateException {
NetworkPacket fakeNetworkPacket = new NetworkPacket(NetworkPacket.PACKET_TYPE_IDENTITY);
String deviceId = "unpairedTestDevice";
fakeNetworkPacket.set("deviceId", deviceId);
fakeNetworkPacket.set("deviceName", "Unpaired Test Device");
fakeNetworkPacket.set("protocolVersion", DeviceHelper.ProtocolVersion);
fakeNetworkPacket.set("deviceType", DeviceType.PHONE.toString());
String certificateString =
"MIIDVzCCAj+gAwIBAgIBCjANBgkqhkiG9w0BAQUFADBVMS8wLQYDVQQDDCZfZGExNzlhOTFfZjA2\n" +
"NF80NzhlX2JlOGNfMTkzNWQ3NTQ0ZDU0XzEMMAoGA1UECgwDS0RFMRQwEgYDVQQLDAtLZGUgY29u\n" +
"bmVjdDAeFw0xNTA2MDMxMzE0MzhaFw0yNTA2MDMxMzE0MzhaMFUxLzAtBgNVBAMMJl9kYTE3OWE5\n" +
"MV9mMDY0XzQ3OGVfYmU4Y18xOTM1ZDc1NDRkNTRfMQwwCgYDVQQKDANLREUxFDASBgNVBAsMC0tk\n" +
"ZSBjb25uZWN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzH9GxS1lctpwYdSGAoPH\n" +
"ws+MnVaL0PVDCuzrpxzXc+bChR87xofhQIesLPLZEcmUJ1MlEJ6jx4W+gVhvY2tUN7SoiKKbnq8s\n" +
"WjI5ovs5yML3C1zPbOSJAdK613FcdkK+UGd/9dQk54gIozinC58iyTAChVVpB3pAF38EPxwKkuo2\n" +
"qTzwk24d6PRxz1skkzwEphUQQzGboyHsAlJHN1MzM2/yFGB4l8iUua2d3ETyfy/xFEh/SwtGtXE5\n" +
"KLz4cpb0fxjeYQZVruBKxzE07kgDO3zOhmP3LJ/KSPHWYImd1DWmpY9iDvoXr6+V7FAnRloaEIyg\n" +
"7WwdlSCpo3TXVuIjLwIDAQABozIwMDAdBgNVHQ4EFgQUwmbHo8YbiR463GRKSLL3eIKyvDkwDwYD\n" +
"VR0TAQH/BAUwAwIBADANBgkqhkiG9w0BAQUFAAOCAQEAydijH3rbnvpBDB/30w2PCGMT7O0N/XYM\n" +
"wBtUidqa4NFumJrNrccx5Ehp4UP66BfP61HW8h2U/EekYfOsZyyWd4KnsDD6ycR8h/WvpK3BC2cn\n" +
"I299wbqCEZmk5ZFFaEIDHdLAdgMCuxJkAzy9mMrWEa05Soxi2/ZXdrU9nXo5dzuPGYlirVPDHl7r\n" +
"/urBxD6HVX3ObQJRJ7r/nAWyUVdX3/biJaDRsydftOpGU6Gi5c1JK4MWIz8Bsjh6mEjCsVatbPPl\n" +
"yygGiJbDZfAvN2XoaVEBii2GDDCWfaFwPVPYlNTvjkUkMP8YThlMsiJ8Q4693XoLOL94GpNlCfUg\n" +
"7n+KOQ==";
byte[] certificateBytes = Base64.decode(certificateString, 0);
Certificate certificate = SslHelper.parseCertificate(certificateBytes);
DeviceInfo deviceInfo = DeviceInfo.fromIdentityPacketAndCert(fakeNetworkPacket, certificate);
LanLinkProvider linkProvider = Mockito.mock(LanLinkProvider.class);
Mockito.when(linkProvider.getName()).thenReturn("LanLinkProvider");
LanLink link = Mockito.mock(LanLink.class);
Mockito.when(link.getLinkProvider()).thenReturn(linkProvider);
Mockito.when(link.getDeviceId()).thenReturn(deviceId);
Mockito.when(link.getDeviceInfo()).thenReturn(deviceInfo);
Device device = new Device(context, link);
assertNotNull(device);
assertEquals(device.getDeviceId(), deviceId);
assertEquals(device.getName(), "Unpaired Test Device");
assertEquals(device.getDeviceType(), DeviceType.PHONE);
assertNotNull(device.getDeviceInfo().certificate);
device.getPairingHandler().pairingDone();
assertTrue(device.isPaired());
SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
assertTrue(preferences.getBoolean(device.getDeviceId(), false));
SharedPreferences settings = context.getSharedPreferences(device.getDeviceId(), Context.MODE_PRIVATE);
assertEquals(settings.getString("deviceName", "Unknown device"), "Unpaired Test Device");
assertEquals(settings.getString("deviceType", "tablet"), "phone");
// Cleanup for unpaired test device
preferences.edit().remove(device.getDeviceId()).apply();
settings.edit().clear().apply();
}
@Test
public void testUnpair() throws CertificateException {
PairingHandler.PairingCallback pairingCallback = Mockito.mock(PairingHandler.PairingCallback.class);
Device device = new Device(context, "testDevice");
device.addPairingCallback(pairingCallback);
device.unpair();
assertFalse(device.isPaired());
SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
assertFalse(preferences.getBoolean(device.getDeviceId(), false));
Mockito.verify(pairingCallback, Mockito.times(1)).unpaired();
}
}

View File

@ -0,0 +1,269 @@
/*
* SPDX-FileCopyrightText: 2015 Vineet Garg <grg.vineet@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
package org.kde.kdeconnect
import android.app.NotificationManager
import android.content.Context
import android.preference.PreferenceManager
import android.util.Base64
import androidx.core.content.ContextCompat
import org.junit.After
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.kde.kdeconnect.Backends.LanBackend.LanLink
import org.kde.kdeconnect.Backends.LanBackend.LanLinkProvider
import org.kde.kdeconnect.DeviceInfo.Companion.fromIdentityPacketAndCert
import org.kde.kdeconnect.DeviceInfo.Companion.isValidIdentityPacket
import org.kde.kdeconnect.DeviceInfo.Companion.loadFromSettings
import org.kde.kdeconnect.DeviceType.Companion.fromString
import org.kde.kdeconnect.Helpers.DeviceHelper
import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper
import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper
import org.kde.kdeconnect.PairingHandler.PairingCallback
import org.mockito.ArgumentMatchers
import org.mockito.MockedStatic
import org.mockito.Mockito
import org.mockito.invocation.InvocationOnMock
import java.security.cert.CertificateException
class DeviceTest {
private lateinit var context: Context
private lateinit var mockBase64: MockedStatic<Base64>
private lateinit var preferenceManager: MockedStatic<PreferenceManager>
private lateinit var contextCompat: MockedStatic<ContextCompat>
// Creating a paired device before each test case
@Before
fun setUp() {
// Save new test device in settings
val deviceId = "testDevice"
val name = "Test Device"
val encodedCertificate = """
MIIDVzCCAj+gAwIBAgIBCjANBgkqhkiG9w0BAQUFADBVMS8wLQYDVQQDDCZfZGExNzlhOTFfZjA2
NF80NzhlX2JlOGNfMTkzNWQ3NTQ0ZDU0XzEMMAoGA1UECgwDS0RFMRQwEgYDVQQLDAtLZGUgY29u
bmVjdDAeFw0xNTA2MDMxMzE0MzhaFw0yNTA2MDMxMzE0MzhaMFUxLzAtBgNVBAMMJl9kYTE3OWE5
MV9mMDY0XzQ3OGVfYmU4Y18xOTM1ZDc1NDRkNTRfMQwwCgYDVQQKDANLREUxFDASBgNVBAsMC0tk
ZSBjb25uZWN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzH9GxS1lctpwYdSGAoPH
ws+MnVaL0PVDCuzrpxzXc+bChR87xofhQIesLPLZEcmUJ1MlEJ6jx4W+gVhvY2tUN7SoiKKbnq8s
WjI5ovs5yML3C1zPbOSJAdK613FcdkK+UGd/9dQk54gIozinC58iyTAChVVpB3pAF38EPxwKkuo2
qTzwk24d6PRxz1skkzwEphUQQzGboyHsAlJHN1MzM2/yFGB4l8iUua2d3ETyfy/xFEh/SwtGtXE5
KLz4cpb0fxjeYQZVruBKxzE07kgDO3zOhmP3LJ/KSPHWYImd1DWmpY9iDvoXr6+V7FAnRloaEIyg
7WwdlSCpo3TXVuIjLwIDAQABozIwMDAdBgNVHQ4EFgQUwmbHo8YbiR463GRKSLL3eIKyvDkwDwYD
VR0TAQH/BAUwAwIBADANBgkqhkiG9w0BAQUFAAOCAQEAydijH3rbnvpBDB/30w2PCGMT7O0N/XYM
wBtUidqa4NFumJrNrccx5Ehp4UP66BfP61HW8h2U/EekYfOsZyyWd4KnsDD6ycR8h/WvpK3BC2cn
I299wbqCEZmk5ZFFaEIDHdLAdgMCuxJkAzy9mMrWEa05Soxi2/ZXdrU9nXo5dzuPGYlirVPDHl7r
/urBxD6HVX3ObQJRJ7r/nAWyUVdX3/biJaDRsydftOpGU6Gi5c1JK4MWIz8Bsjh6mEjCsVatbPPl
yygGiJbDZfAvN2XoaVEBii2GDDCWfaFwPVPYlNTvjkUkMP8YThlMsiJ8Q4693XoLOL94GpNlCfUg
7n+KOQ==
""".trimIndent()
val context = Mockito.mock(Context::class.java)
val mockBase64 = Mockito.mockStatic(Base64::class.java)
mockBase64.`when`<Any> {
Base64.encodeToString(ArgumentMatchers.any(ByteArray::class.java), ArgumentMatchers.anyInt())
}.thenAnswer { invocation: InvocationOnMock ->
java.util.Base64.getMimeEncoder().encodeToString(invocation.arguments[0] as ByteArray)
}
mockBase64.`when`<Any> {
Base64.decode(ArgumentMatchers.anyString(), ArgumentMatchers.anyInt())
}.thenAnswer { invocation: InvocationOnMock ->
java.util.Base64.getMimeDecoder().decode(invocation.arguments[0] as String)
}
// Store device information needed to create a Device object in a future
val deviceSettings = MockSharedPreference()
val editor = deviceSettings.edit()
editor.putString("deviceName", name)
editor.putString("deviceType", DeviceType.PHONE.toString())
editor.putString("certificate", encodedCertificate)
editor.apply()
Mockito.`when`(context.getSharedPreferences(ArgumentMatchers.eq(deviceId), ArgumentMatchers.eq(Context.MODE_PRIVATE))).thenReturn(deviceSettings)
// Store the device as trusted
val trustedSettings = MockSharedPreference()
trustedSettings.edit().putBoolean(deviceId, true).apply()
Mockito.`when`(context.getSharedPreferences(ArgumentMatchers.eq("trusted_devices"), ArgumentMatchers.eq(Context.MODE_PRIVATE))).thenReturn(trustedSettings)
// Store an untrusted device
val untrustedSettings = MockSharedPreference()
Mockito.`when`(context.getSharedPreferences(ArgumentMatchers.eq("unpairedTestDevice"), ArgumentMatchers.eq(Context.MODE_PRIVATE))).thenReturn(untrustedSettings)
// Default shared prefs, including our own private key
val preferenceManager = Mockito.mockStatic(PreferenceManager::class.java)
val defaultSettings = MockSharedPreference()
preferenceManager.`when`<Any> {
PreferenceManager.getDefaultSharedPreferences(ArgumentMatchers.any(Context::class.java))
}.thenReturn(defaultSettings)
RsaHelper.initialiseRsaKeys(context)
val contextCompat = Mockito.mockStatic(ContextCompat::class.java)
contextCompat.`when`<Any> {
ContextCompat.getSystemService(context!!, NotificationManager::class.java)
}.thenReturn(Mockito.mock(NotificationManager::class.java))
this.context = context
this.mockBase64 = mockBase64
this.preferenceManager = preferenceManager
this.contextCompat = contextCompat
}
@After
fun tearDown() {
mockBase64.close()
preferenceManager.close()
contextCompat.close()
}
@Test
@Throws(CertificateException::class)
fun testDeviceInfoToIdentityPacket() {
val deviceId = "testDevice"
val settings = context.getSharedPreferences(deviceId, Context.MODE_PRIVATE)
val deviceInfo = loadFromSettings(context, deviceId, settings)
deviceInfo.protocolVersion = DeviceHelper.ProtocolVersion
deviceInfo.incomingCapabilities = hashSetOf("kdeconnect.plugin1State", "kdeconnect.plugin2State")
deviceInfo.outgoingCapabilities = hashSetOf("kdeconnect.plugin1State.request", "kdeconnect.plugin2State.request")
val networkPacket = deviceInfo.toIdentityPacket()
Assert.assertEquals(deviceInfo.id, networkPacket.getString("deviceId"))
Assert.assertEquals(deviceInfo.name, networkPacket.getString("deviceName"))
Assert.assertEquals(deviceInfo.protocolVersion.toLong(), networkPacket.getInt("protocolVersion").toLong())
Assert.assertEquals(deviceInfo.type.toString(), networkPacket.getString("deviceType"))
Assert.assertEquals(deviceInfo.incomingCapabilities, networkPacket.getStringSet("incomingCapabilities"))
Assert.assertEquals(deviceInfo.outgoingCapabilities, networkPacket.getStringSet("outgoingCapabilities"))
}
@Test
fun testIsValidIdentityPacket() {
val np = NetworkPacket(NetworkPacket.PACKET_TYPE_IDENTITY)
Assert.assertFalse(isValidIdentityPacket(np))
val validName = "MyDevice"
val validId = "123"
np["deviceName"] = validName
np["deviceId"] = validId
Assert.assertTrue(isValidIdentityPacket(np))
np["deviceName"] = " "
Assert.assertFalse(isValidIdentityPacket(np))
np["deviceName"] = "<><><><><><><><><>" // Only invalid characters
Assert.assertFalse(isValidIdentityPacket(np))
np["deviceName"] = validName
np["deviceId"] = " "
Assert.assertFalse(isValidIdentityPacket(np))
}
@Test
fun testDeviceType() {
Assert.assertEquals(DeviceType.PHONE, fromString(DeviceType.PHONE.toString()))
Assert.assertEquals(DeviceType.TABLET, fromString(DeviceType.TABLET.toString()))
Assert.assertEquals(DeviceType.DESKTOP, fromString(DeviceType.DESKTOP.toString()))
Assert.assertEquals(DeviceType.LAPTOP, fromString(DeviceType.LAPTOP.toString()))
Assert.assertEquals(DeviceType.TV, fromString(DeviceType.TV.toString()))
Assert.assertEquals(DeviceType.DESKTOP, fromString("invalid"))
}
// Basic paired device testing
@Test
@Throws(CertificateException::class)
fun testDevice() {
val device = Device(context, "testDevice")
Assert.assertEquals(device.deviceId, "testDevice")
Assert.assertEquals(device.deviceType, DeviceType.PHONE)
Assert.assertEquals(device.name, "Test Device")
Assert.assertTrue(device.isPaired)
Assert.assertNotNull(device.deviceInfo.certificate)
}
@Test
@Throws(CertificateException::class)
fun testPairingDone() {
val fakeNetworkPacket = NetworkPacket(NetworkPacket.PACKET_TYPE_IDENTITY)
val deviceId = "unpairedTestDevice"
fakeNetworkPacket["deviceId"] = deviceId
fakeNetworkPacket["deviceName"] = "Unpaired Test Device"
fakeNetworkPacket["protocolVersion"] = DeviceHelper.ProtocolVersion
fakeNetworkPacket["deviceType"] = DeviceType.PHONE.toString()
val certificateString =
"""
MIIDVzCCAj+gAwIBAgIBCjANBgkqhkiG9w0BAQUFADBVMS8wLQYDVQQDDCZfZGExNzlhOTFfZjA2
NF80NzhlX2JlOGNfMTkzNWQ3NTQ0ZDU0XzEMMAoGA1UECgwDS0RFMRQwEgYDVQQLDAtLZGUgY29u
bmVjdDAeFw0xNTA2MDMxMzE0MzhaFw0yNTA2MDMxMzE0MzhaMFUxLzAtBgNVBAMMJl9kYTE3OWE5
MV9mMDY0XzQ3OGVfYmU4Y18xOTM1ZDc1NDRkNTRfMQwwCgYDVQQKDANLREUxFDASBgNVBAsMC0tk
ZSBjb25uZWN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzH9GxS1lctpwYdSGAoPH
ws+MnVaL0PVDCuzrpxzXc+bChR87xofhQIesLPLZEcmUJ1MlEJ6jx4W+gVhvY2tUN7SoiKKbnq8s
WjI5ovs5yML3C1zPbOSJAdK613FcdkK+UGd/9dQk54gIozinC58iyTAChVVpB3pAF38EPxwKkuo2
qTzwk24d6PRxz1skkzwEphUQQzGboyHsAlJHN1MzM2/yFGB4l8iUua2d3ETyfy/xFEh/SwtGtXE5
KLz4cpb0fxjeYQZVruBKxzE07kgDO3zOhmP3LJ/KSPHWYImd1DWmpY9iDvoXr6+V7FAnRloaEIyg
7WwdlSCpo3TXVuIjLwIDAQABozIwMDAdBgNVHQ4EFgQUwmbHo8YbiR463GRKSLL3eIKyvDkwDwYD
VR0TAQH/BAUwAwIBADANBgkqhkiG9w0BAQUFAAOCAQEAydijH3rbnvpBDB/30w2PCGMT7O0N/XYM
wBtUidqa4NFumJrNrccx5Ehp4UP66BfP61HW8h2U/EekYfOsZyyWd4KnsDD6ycR8h/WvpK3BC2cn
I299wbqCEZmk5ZFFaEIDHdLAdgMCuxJkAzy9mMrWEa05Soxi2/ZXdrU9nXo5dzuPGYlirVPDHl7r
/urBxD6HVX3ObQJRJ7r/nAWyUVdX3/biJaDRsydftOpGU6Gi5c1JK4MWIz8Bsjh6mEjCsVatbPPl
yygGiJbDZfAvN2XoaVEBii2GDDCWfaFwPVPYlNTvjkUkMP8YThlMsiJ8Q4693XoLOL94GpNlCfUg
7n+KOQ==
""".trimIndent()
val certificateBytes = Base64.decode(certificateString, 0)
val certificate = SslHelper.parseCertificate(certificateBytes)
val deviceInfo = fromIdentityPacketAndCert(fakeNetworkPacket, certificate)
val linkProvider = Mockito.mock(LanLinkProvider::class.java)
Mockito.`when`(linkProvider.name).thenReturn("LanLinkProvider")
val link = Mockito.mock(LanLink::class.java)
Mockito.`when`(link.linkProvider).thenReturn(linkProvider)
Mockito.`when`(link.deviceId).thenReturn(deviceId)
Mockito.`when`(link.deviceInfo).thenReturn(deviceInfo)
val device = Device(context, link)
Assert.assertNotNull(device)
Assert.assertEquals(device.deviceId, deviceId)
Assert.assertEquals(device.name, "Unpaired Test Device")
Assert.assertEquals(device.deviceType, DeviceType.PHONE)
Assert.assertNotNull(device.deviceInfo.certificate)
device.pairingHandler.pairingDone()
Assert.assertTrue(device.isPaired)
val preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE)
Assert.assertTrue(preferences.getBoolean(device.deviceId, false))
val settings = context.getSharedPreferences(device.deviceId, Context.MODE_PRIVATE)
Assert.assertEquals(
settings.getString("deviceName", "Unknown device"),
"Unpaired Test Device"
)
Assert.assertEquals(settings.getString("deviceType", "tablet"), "phone")
// Cleanup for unpaired test device
preferences.edit().remove(device.deviceId).apply()
settings.edit().clear().apply()
}
@Test
@Throws(CertificateException::class)
fun testUnpair() {
val pairingCallback = Mockito.mock(PairingCallback::class.java)
val device = Device(context, "testDevice")
device.addPairingCallback(pairingCallback)
device.unpair()
Assert.assertFalse(device.isPaired)
val preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE)
Assert.assertFalse(preferences.getBoolean(device.deviceId, false))
Mockito.verify(pairingCallback, Mockito.times(1)).unpaired()
}
}