mirror of
https://github.com/KDE/kdeconnect-android
synced 2025-08-31 14:15:14 +00:00
Fixed all tests
Now they are local tests and not Android tests
This commit is contained in:
13
build.gradle
13
build.gradle
@@ -15,8 +15,6 @@ android {
|
||||
defaultConfig {
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 28
|
||||
//multiDexEnabled true
|
||||
//testInstrumentationRunner "com.android.test.runner.MultiDexTestRunner"
|
||||
}
|
||||
dexOptions {
|
||||
javaMaxHeapSize "2g"
|
||||
@@ -33,7 +31,7 @@ android {
|
||||
res.srcDirs = ['res']
|
||||
assets.srcDirs = ['assets']
|
||||
}
|
||||
androidTest {
|
||||
test {
|
||||
java.srcDirs = ['tests']
|
||||
}
|
||||
}
|
||||
@@ -87,9 +85,10 @@ dependencies {
|
||||
annotationProcessor 'org.atteo.classindex:classindex:3.6'
|
||||
|
||||
// Testing
|
||||
androidTestImplementation 'org.mockito:mockito-core:1.10.19'
|
||||
androidTestImplementation 'com.google.dexmaker:dexmaker-mockito:1.1'// Because mockito has some problems with dex environment
|
||||
androidTestImplementation 'org.skyscreamer:jsonassert:1.3.0'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
|
||||
testImplementation 'org.powermock:powermock-core:2.0.0'
|
||||
testImplementation 'org.powermock:powermock-module-junit4:2.0.0'
|
||||
testImplementation 'org.powermock:powermock-api-mockito2:2.0.0'
|
||||
testImplementation 'org.mockito:mockito-core:2.23.0'
|
||||
testImplementation 'org.skyscreamer:jsonassert:1.3.0'
|
||||
}
|
||||
|
@@ -20,44 +20,52 @@
|
||||
|
||||
package org.kde.kdeconnect;
|
||||
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.kde.kdeconnect.Backends.BasePairingHandler;
|
||||
import org.kde.kdeconnect.Backends.LanBackend.LanLink;
|
||||
import org.kde.kdeconnect.Backends.LanBackend.LanLinkProvider;
|
||||
import org.kde.kdeconnect.Backends.LanBackend.LanPairingHandler;
|
||||
import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper;
|
||||
import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper;
|
||||
import org.mockito.Mockito;
|
||||
import org.spongycastle.asn1.x500.X500NameBuilder;
|
||||
import org.spongycastle.asn1.x500.style.BCStyle;
|
||||
import org.spongycastle.cert.X509v3CertificateBuilder;
|
||||
import org.spongycastle.cert.jcajce.JcaX509CertificateConverter;
|
||||
import org.spongycastle.cert.jcajce.JcaX509v3CertificateBuilder;
|
||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.spongycastle.operator.ContentSigner;
|
||||
import org.spongycastle.operator.jcajce.JcaContentSignerBuilder;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.math.BigInteger;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Date;
|
||||
|
||||
class DeviceTest extends AndroidTestCase {
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
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.Matchers.eq;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({Base64.class, Log.class, PreferenceManager.class})
|
||||
public class DeviceTest {
|
||||
|
||||
Context context;
|
||||
|
||||
// Creating a paired device before each test case
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
// Dexmaker has problems guessing cache directory, setting manually
|
||||
System.setProperty("dexmaker.dexcache", getContext().getCacheDir().getPath());
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
// Save new test device in settings
|
||||
Context context = getContext();
|
||||
|
||||
String deviceId = "testDevice";
|
||||
String name = "Test Device";
|
||||
@@ -73,45 +81,46 @@ class DeviceTest extends AndroidTestCase {
|
||||
return;
|
||||
}
|
||||
|
||||
SharedPreferences settings = context.getSharedPreferences(deviceId, Context.MODE_PRIVATE);
|
||||
this.context = Mockito.mock(Context.class);
|
||||
|
||||
PowerMockito.mockStatic(Base64.class);
|
||||
PowerMockito.when(Base64.encodeToString(any(), anyInt())).thenAnswer(invocation -> java.util.Base64.getMimeEncoder().encodeToString((byte[]) invocation.getArguments()[0]));
|
||||
PowerMockito.when(Base64.decode(anyString(), anyInt())).thenAnswer(invocation -> java.util.Base64.getMimeDecoder().decode((String) invocation.getArguments()[0]));
|
||||
|
||||
PowerMockito.mockStatic(Log.class);
|
||||
|
||||
//Store device information needed to create a Device object in a future
|
||||
SharedPreferences.Editor editor = settings.edit();
|
||||
MockSharedPreference deviceSettings = new MockSharedPreference();
|
||||
SharedPreferences.Editor editor = deviceSettings.edit();
|
||||
editor.putString("deviceName", name);
|
||||
editor.putString("deviceType", Device.DeviceType.Phone.toString());
|
||||
editor.putString("publicKey", Base64.encodeToString(keyPair.getPublic().getEncoded(), 0).trim() + "\n");
|
||||
editor.apply();
|
||||
Mockito.when(context.getSharedPreferences(eq(deviceId), eq(Context.MODE_PRIVATE))).thenReturn(deviceSettings);
|
||||
|
||||
SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
|
||||
preferences.edit().putBoolean(deviceId, true).apply();
|
||||
}
|
||||
//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);
|
||||
|
||||
// Removing paired device info after each test case
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
//Default shared prefs, including our own private key
|
||||
PowerMockito.mockStatic(PreferenceManager.class);
|
||||
MockSharedPreference defaultSettings = new MockSharedPreference();
|
||||
PowerMockito.when(PreferenceManager.getDefaultSharedPreferences(any())).thenReturn(defaultSettings);
|
||||
RsaHelper.initialiseRsaKeys(context);
|
||||
|
||||
// Remove saved test device
|
||||
Context context = getContext();
|
||||
|
||||
String deviceId = "testDevice";
|
||||
|
||||
SharedPreferences settings = context.getSharedPreferences(deviceId, Context.MODE_PRIVATE);
|
||||
|
||||
//Store device information needed to create a Device object in a future
|
||||
SharedPreferences.Editor editor = settings.edit();
|
||||
editor.clear();
|
||||
editor.apply();
|
||||
|
||||
SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
|
||||
preferences.edit().remove(deviceId).apply();
|
||||
}
|
||||
Mockito.when(context.getSystemService(eq(Context.NOTIFICATION_SERVICE))).thenReturn(Mockito.mock(NotificationManager.class));
|
||||
}
|
||||
|
||||
// Basic paired device testing
|
||||
@Test
|
||||
public void testDevice() {
|
||||
|
||||
Device device = new Device(getContext(), "testDevice");
|
||||
Device device = new Device(context, "testDevice");
|
||||
|
||||
assertEquals(device.getDeviceId(), "testDevice");
|
||||
assertEquals(device.getDeviceType(), Device.DeviceType.Phone);
|
||||
@@ -122,6 +131,7 @@ class DeviceTest extends AndroidTestCase {
|
||||
|
||||
// Testing pairing done using reflection since it is private
|
||||
// Created an unpaired device inside this test
|
||||
@Test
|
||||
public void testPairingDone() {
|
||||
|
||||
NetworkPacket fakeNetworkPacket = new NetworkPacket(NetworkPacket.PACKET_TYPE_IDENTITY);
|
||||
@@ -134,8 +144,8 @@ class DeviceTest extends AndroidTestCase {
|
||||
Mockito.when(linkProvider.getName()).thenReturn("LanLinkProvider");
|
||||
LanLink link = Mockito.mock(LanLink.class);
|
||||
Mockito.when(link.getLinkProvider()).thenReturn(linkProvider);
|
||||
Mockito.when(link.getPairingHandler(Mockito.any(Device.class), Mockito.any(BasePairingHandler.PairingHandlerCallback.class))).thenReturn(Mockito.mock(LanPairingHandler.class));
|
||||
Device device = new Device(getContext(), fakeNetworkPacket, link);
|
||||
Mockito.when(link.getPairingHandler(any(Device.class), any(BasePairingHandler.PairingHandlerCallback.class))).thenReturn(Mockito.mock(LanPairingHandler.class));
|
||||
Device device = new Device(context, fakeNetworkPacket, link);
|
||||
|
||||
KeyPair keyPair;
|
||||
try {
|
||||
@@ -167,10 +177,10 @@ class DeviceTest extends AndroidTestCase {
|
||||
|
||||
assertTrue(device.isPaired());
|
||||
|
||||
SharedPreferences preferences = getContext().getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
|
||||
SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
|
||||
assertTrue(preferences.getBoolean(device.getDeviceId(), false));
|
||||
|
||||
SharedPreferences settings = getContext().getSharedPreferences(device.getDeviceId(), Context.MODE_PRIVATE);
|
||||
SharedPreferences settings = context.getSharedPreferences(device.getDeviceId(), Context.MODE_PRIVATE);
|
||||
assertEquals(settings.getString("deviceName", "Unknown device"), "Unpaired Test Device");
|
||||
assertEquals(settings.getString("deviceType", "tablet"), "phone");
|
||||
|
||||
@@ -180,6 +190,7 @@ class DeviceTest extends AndroidTestCase {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPairingDoneWithCertificate() throws Exception {
|
||||
KeyPair keyPair = null;
|
||||
try {
|
||||
@@ -191,46 +202,35 @@ class DeviceTest extends AndroidTestCase {
|
||||
Log.e("KDE/initializeRsaKeys", "Exception");
|
||||
}
|
||||
|
||||
X509Certificate certificate = null;
|
||||
try {
|
||||
|
||||
BouncyCastleProvider BC = new BouncyCastleProvider();
|
||||
|
||||
X500NameBuilder nameBuilder = new X500NameBuilder(BCStyle.INSTANCE);
|
||||
nameBuilder.addRDN(BCStyle.CN, "testDevice");
|
||||
nameBuilder.addRDN(BCStyle.OU, "KDE Connect");
|
||||
nameBuilder.addRDN(BCStyle.O, "KDE");
|
||||
Date notBefore = new Date(System.currentTimeMillis());
|
||||
Date notAfter = new Date(System.currentTimeMillis() + System.currentTimeMillis());
|
||||
X509v3CertificateBuilder certificateBuilder = new JcaX509v3CertificateBuilder(
|
||||
nameBuilder.build(),
|
||||
BigInteger.ONE,
|
||||
notBefore,
|
||||
notAfter,
|
||||
nameBuilder.build(),
|
||||
keyPair.getPublic()
|
||||
);
|
||||
ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(BC).build(keyPair.getPrivate());
|
||||
certificate = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certificateBuilder.build(contentSigner));
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Log.e("KDE/initialiseCert", "Exception");
|
||||
}
|
||||
|
||||
NetworkPacket fakeNetworkPacket = new NetworkPacket(NetworkPacket.PACKET_TYPE_IDENTITY);
|
||||
fakeNetworkPacket.set("deviceId", "unpairedTestDevice");
|
||||
fakeNetworkPacket.set("deviceName", "Unpaired Test Device");
|
||||
fakeNetworkPacket.set("protocolVersion", NetworkPacket.ProtocolVersion);
|
||||
fakeNetworkPacket.set("deviceType", Device.DeviceType.Phone.toString());
|
||||
fakeNetworkPacket.set("certificate", Base64.encodeToString(certificate.getEncoded(), 0));
|
||||
fakeNetworkPacket.set("certificate",
|
||||
"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==");
|
||||
|
||||
LanLinkProvider linkProvider = Mockito.mock(LanLinkProvider.class);
|
||||
Mockito.when(linkProvider.getName()).thenReturn("LanLinkProvider");
|
||||
LanLink link = Mockito.mock(LanLink.class);
|
||||
Mockito.when(link.getPairingHandler(Mockito.any(Device.class), Mockito.any(BasePairingHandler.PairingHandlerCallback.class))).thenReturn(Mockito.mock(LanPairingHandler.class));
|
||||
Mockito.when(link.getPairingHandler(any(Device.class), any(BasePairingHandler.PairingHandlerCallback.class))).thenReturn(Mockito.mock(LanPairingHandler.class));
|
||||
Mockito.when(link.getLinkProvider()).thenReturn(linkProvider);
|
||||
Device device = new Device(getContext(), fakeNetworkPacket, link);
|
||||
Device device = new Device(context, fakeNetworkPacket, link);
|
||||
device.publicKey = keyPair.getPublic();
|
||||
|
||||
assertNotNull(device);
|
||||
@@ -251,10 +251,10 @@ class DeviceTest extends AndroidTestCase {
|
||||
|
||||
assertTrue(device.isPaired());
|
||||
|
||||
SharedPreferences preferences = getContext().getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
|
||||
SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
|
||||
assertTrue(preferences.getBoolean(device.getDeviceId(), false));
|
||||
|
||||
SharedPreferences settings = getContext().getSharedPreferences(device.getDeviceId(), Context.MODE_PRIVATE);
|
||||
SharedPreferences settings = context.getSharedPreferences(device.getDeviceId(), Context.MODE_PRIVATE);
|
||||
assertEquals(settings.getString("deviceName", "Unknown device"), "Unpaired Test Device");
|
||||
assertEquals(settings.getString("deviceType", "tablet"), "phone");
|
||||
|
||||
@@ -263,15 +263,16 @@ class DeviceTest extends AndroidTestCase {
|
||||
settings.edit().clear().apply();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnpair() {
|
||||
|
||||
Device device = new Device(getContext(), "testDevice");
|
||||
Device device = new Device(context, "testDevice");
|
||||
|
||||
device.unpair();
|
||||
|
||||
assertFalse(device.isPaired());
|
||||
|
||||
SharedPreferences preferences = getContext().getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
|
||||
SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
|
||||
assertFalse(preferences.getBoolean(device.getDeviceId(), false));
|
||||
|
||||
}
|
||||
|
@@ -20,30 +20,44 @@
|
||||
|
||||
package org.kde.kdeconnect;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.kde.kdeconnect.Backends.LanBackend.LanLink;
|
||||
import org.kde.kdeconnect.Backends.LanBackend.LanLinkProvider;
|
||||
import org.kde.kdeconnect.Helpers.DeviceHelper;
|
||||
import org.mockito.Mockito;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.Socket;
|
||||
import java.util.HashMap;
|
||||
|
||||
class LanLinkProviderTest extends AndroidTestCase {
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
|
||||
private LanLinkProvider linkProvider;
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({DeviceHelper.class, Log.class})
|
||||
public class LanLinkProviderTest {
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
@Before
|
||||
public void setUp() {
|
||||
PowerMockito.mockStatic(DeviceHelper.class);
|
||||
PowerMockito.when(DeviceHelper.getDeviceId(any())).thenReturn("123");
|
||||
|
||||
System.setProperty("dexmaker.dexcache", getContext().getCacheDir().getPath());
|
||||
|
||||
linkProvider = new LanLinkProvider(getContext());
|
||||
PowerMockito.mockStatic(Log.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIdentityPacketReceived() throws Exception {
|
||||
|
||||
LanLinkProvider linkProvider = new LanLinkProvider(null);
|
||||
|
||||
NetworkPacket networkPacket = Mockito.mock(NetworkPacket.class);
|
||||
Mockito.when(networkPacket.getType()).thenReturn("kdeconnect.identity");
|
||||
Mockito.when(networkPacket.getString("deviceId")).thenReturn("testDevice");
|
||||
|
@@ -20,13 +20,21 @@
|
||||
|
||||
package org.kde.kdeconnect;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.kde.kdeconnect.Backends.LanBackend.LanLink;
|
||||
import org.kde.kdeconnect.Backends.LanBackend.LanLinkProvider;
|
||||
import org.kde.kdeconnect.Helpers.DeviceHelper;
|
||||
import org.mockito.Mockito;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -36,7 +44,11 @@ import java.io.OutputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
|
||||
class LanLinkTest extends AndroidTestCase {
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({Log.class})
|
||||
public class LanLinkTest {
|
||||
|
||||
private LanLink badLanLink;
|
||||
private LanLink goodLanLink;
|
||||
@@ -46,11 +58,9 @@ class LanLinkTest extends AndroidTestCase {
|
||||
|
||||
private Device.SendPacketStatusCallback callback;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
System.setProperty("dexmaker.dexcache", getContext().getCacheDir().getPath());
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
PowerMockito.mockStatic(Log.class);
|
||||
|
||||
LanLinkProvider linkProvider = Mockito.mock(LanLinkProvider.class);
|
||||
Mockito.when(linkProvider.getName()).thenReturn("LanLinkProvider");
|
||||
@@ -70,10 +80,12 @@ class LanLinkTest extends AndroidTestCase {
|
||||
Mockito.when(socketBadMock.getRemoteSocketAddress()).thenReturn(new InetSocketAddress(5000));
|
||||
Mockito.when(socketBadMock.getOutputStream()).thenReturn(badOutputStream);
|
||||
|
||||
goodLanLink = new LanLink(getContext(), "testDevice", linkProvider, socketMock, LanLink.ConnectionStarted.Remotely);
|
||||
badLanLink = new LanLink(getContext(), "testDevice", linkProvider, socketBadMock, LanLink.ConnectionStarted.Remotely);
|
||||
Context context = Mockito.mock(Context.class);
|
||||
goodLanLink = new LanLink(context, "testDevice", linkProvider, socketMock, LanLink.ConnectionStarted.Remotely);
|
||||
badLanLink = new LanLink(context, "testDevice", linkProvider, socketBadMock, LanLink.ConnectionStarted.Remotely);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendPacketSuccess() throws JSONException {
|
||||
|
||||
NetworkPacket testPacket = Mockito.mock(NetworkPacket.class);
|
||||
@@ -87,6 +99,7 @@ class LanLinkTest extends AndroidTestCase {
|
||||
Mockito.verify(callback).onSuccess();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendPacketFail() throws JSONException {
|
||||
|
||||
NetworkPacket testPacket = Mockito.mock(NetworkPacket.class);
|
||||
@@ -97,11 +110,11 @@ class LanLinkTest extends AndroidTestCase {
|
||||
|
||||
badLanLink.sendPacket(testPacket, callback);
|
||||
|
||||
Mockito.verify(callback).onFailure(Mockito.any(RuntimeException.class));
|
||||
Mockito.verify(callback).onFailure(Mockito.any(IOException.class));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSendPayload() throws Exception {
|
||||
|
||||
class Downloader extends Thread {
|
||||
@@ -127,7 +140,7 @@ class LanLinkTest extends AndroidTestCase {
|
||||
int tcpPort = np.getPayloadTransferInfo().getInt("port");
|
||||
InetSocketAddress address = new InetSocketAddress(5000);
|
||||
socket.connect(new InetSocketAddress(address.getAddress(), tcpPort));
|
||||
np.setPayload(socket.getInputStream(), np.getPayloadSize());
|
||||
np.setPayload(new NetworkPacket.Payload(socket.getInputStream(), np.getPayloadSize()));
|
||||
} catch (Exception e) {
|
||||
socket.close();
|
||||
e.printStackTrace();
|
||||
@@ -135,7 +148,7 @@ class LanLinkTest extends AndroidTestCase {
|
||||
throw e;
|
||||
}
|
||||
|
||||
final InputStream input = np.getPayload();
|
||||
final InputStream input = np.getPayload().getInputStream();
|
||||
final long fileLength = np.getPayloadSize();
|
||||
|
||||
byte data[] = new byte[1024];
|
||||
@@ -193,7 +206,7 @@ class LanLinkTest extends AndroidTestCase {
|
||||
Mockito.when(sharePacket.hasPayload()).thenReturn(true);
|
||||
Mockito.when(sharePacket.hasPayloadTransferInfo()).thenReturn(true);
|
||||
Mockito.doAnswer(invocationOnMock -> sharePacketJson.toString()).when(sharePacket).serialize();
|
||||
Mockito.when(sharePacket.getPayload()).thenReturn(new ByteArrayInputStream(data));
|
||||
Mockito.when(sharePacket.getPayload()).thenReturn(new NetworkPacket.Payload(new ByteArrayInputStream(data), -1));
|
||||
Mockito.when(sharePacket.getPayloadSize()).thenReturn((long) data.length);
|
||||
Mockito.doAnswer(invocationOnMock -> sharePacketJson.getJSONObject("payloadTransferInfo")).when(sharePacket).getPayloadTransferInfo();
|
||||
Mockito.doAnswer(invocationOnMock -> {
|
||||
|
159
tests/org/kde/kdeconnect/MockSharedPreference.java
Normal file
159
tests/org/kde/kdeconnect/MockSharedPreference.java
Normal file
@@ -0,0 +1,159 @@
|
||||
package org.kde.kdeconnect;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
|
||||
/**
|
||||
* Mock implementation of shared preference, which just saves data in memory using map.
|
||||
*
|
||||
* It DOES NOT support transactions, changes are immediate
|
||||
*
|
||||
* From https://gist.github.com/amardeshbd/354173d00b988574ee5019c4ba0c8a0b
|
||||
*/
|
||||
public class MockSharedPreference implements SharedPreferences {
|
||||
|
||||
private final HashMap<String, Object> preferenceMap;
|
||||
private final MockSharedPreferenceEditor preferenceEditor;
|
||||
|
||||
public MockSharedPreference() {
|
||||
preferenceMap = new HashMap<>();
|
||||
preferenceEditor = new MockSharedPreferenceEditor(preferenceMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ?> getAll() {
|
||||
return preferenceMap;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getString(final String s, @Nullable final String def) {
|
||||
if (!preferenceMap.containsKey(s)) return def;
|
||||
return (String) preferenceMap.get(s);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Set<String> getStringSet(final String s, @Nullable final Set<String> def) {
|
||||
if (!preferenceMap.containsKey(s)) return def;
|
||||
return (Set<String>) preferenceMap.get(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(final String s, final int def) {
|
||||
if (!preferenceMap.containsKey(s)) return def;
|
||||
return (int) preferenceMap.get(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLong(final String s, final long def) {
|
||||
if (!preferenceMap.containsKey(s)) return def;
|
||||
return (long) preferenceMap.get(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFloat(final String s, final float def) {
|
||||
if (!preferenceMap.containsKey(s)) return def;
|
||||
return (float) preferenceMap.get(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean(final String s, final boolean def) {
|
||||
if (!preferenceMap.containsKey(s)) return def;
|
||||
return (boolean) preferenceMap.get(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(final String s) {
|
||||
return preferenceMap.containsKey(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Editor edit() {
|
||||
return preferenceEditor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerOnSharedPreferenceChangeListener(final OnSharedPreferenceChangeListener onSharedPreferenceChangeListener) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterOnSharedPreferenceChangeListener(final OnSharedPreferenceChangeListener onSharedPreferenceChangeListener) {
|
||||
|
||||
}
|
||||
|
||||
public static class MockSharedPreferenceEditor implements Editor {
|
||||
|
||||
private final HashMap<String, Object> preferenceMap;
|
||||
|
||||
public MockSharedPreferenceEditor(final HashMap<String, Object> preferenceMap) {
|
||||
this.preferenceMap = preferenceMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Editor putString(final String s, @Nullable final String s1) {
|
||||
preferenceMap.put(s, s1);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Editor putStringSet(final String s, @Nullable final Set<String> set) {
|
||||
preferenceMap.put(s, set);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Editor putInt(final String s, final int i) {
|
||||
preferenceMap.put(s, i);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Editor putLong(final String s, final long l) {
|
||||
preferenceMap.put(s, l);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Editor putFloat(final String s, final float v) {
|
||||
preferenceMap.put(s, v);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Editor putBoolean(final String s, final boolean b) {
|
||||
preferenceMap.put(s, b);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Editor remove(final String s) {
|
||||
preferenceMap.remove(s);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Editor clear() {
|
||||
preferenceMap.clear();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean commit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() {
|
||||
// Nothing to do, everything is saved in memory.
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -20,19 +20,40 @@
|
||||
|
||||
package org.kde.kdeconnect;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper;
|
||||
import org.skyscreamer.jsonassert.JSONAssert;
|
||||
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.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
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 static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
|
||||
class NetworkPacketTest extends AndroidTestCase {
|
||||
@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(Device.DeviceType.Phone);
|
||||
|
||||
PowerMockito.mockStatic(Log.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNetworkPacket() throws JSONException {
|
||||
NetworkPacket np = new NetworkPacket("com.test");
|
||||
|
||||
@@ -61,67 +82,17 @@ class NetworkPacketTest extends AndroidTestCase {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIdentity() {
|
||||
|
||||
NetworkPacket np = NetworkPacket.createIdentityPacket(getContext());
|
||||
Context context = Mockito.mock(Context.class);
|
||||
MockSharedPreference settings = new MockSharedPreference();
|
||||
Mockito.when(context.getSharedPreferences(anyString(), anyInt())).thenReturn(settings);
|
||||
|
||||
NetworkPacket np = NetworkPacket.createIdentityPacket(context);
|
||||
|
||||
assertEquals(np.getInt("protocolVersion"), NetworkPacket.ProtocolVersion);
|
||||
|
||||
}
|
||||
|
||||
public void testEncryption() throws JSONException {
|
||||
NetworkPacket original = new NetworkPacket("com.test");
|
||||
original.set("hello", "hola");
|
||||
|
||||
NetworkPacket copy = NetworkPacket.unserialize(original.serialize());
|
||||
|
||||
NetworkPacket decrypted = new NetworkPacket("");
|
||||
|
||||
KeyPair keyPair;
|
||||
try {
|
||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
|
||||
keyGen.initialize(2048);
|
||||
keyPair = keyGen.genKeyPair();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Log.e("KDE/initializeRsaKeys", "Exception");
|
||||
return;
|
||||
}
|
||||
|
||||
PrivateKey privateKey = keyPair.getPrivate();
|
||||
assertNotNull(privateKey);
|
||||
|
||||
PublicKey publicKey = keyPair.getPublic();
|
||||
assertNotNull(publicKey);
|
||||
|
||||
// Encrypt and decrypt np
|
||||
assertEquals(original.getType(), "com.test");
|
||||
try {
|
||||
NetworkPacket encrypted = RsaHelper.encrypt(original, publicKey);
|
||||
assertEquals(encrypted.getType(), NetworkPacket.PACKET_TYPE_ENCRYPTED);
|
||||
|
||||
decrypted = RsaHelper.decrypt(encrypted, privateKey);
|
||||
assertEquals(decrypted.getType(), "com.test");
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// np should be equal to np2
|
||||
assertEquals(decrypted.getLong("id"), copy.getLong("id"));
|
||||
assertEquals(decrypted.getType(), copy.getType());
|
||||
assertEquals(decrypted.getJSONArray("body"), copy.getJSONArray("body"));
|
||||
|
||||
String json = "{\"body\":{\"nowPlaying\":\"A really long song name - A really long artist name\",\"player\":\"A really long player name\",\"the_meaning_of_life_the_universe_and_everything\":\"42\"},\"id\":945945945,\"type\":\"kdeconnect.a_really_really_long_package_type\"}\n";
|
||||
NetworkPacket longJsonNp = NetworkPacket.unserialize(json);
|
||||
try {
|
||||
NetworkPacket encrypted = RsaHelper.encrypt(longJsonNp, publicKey);
|
||||
decrypted = RsaHelper.decrypt(encrypted, privateKey);
|
||||
String decryptedJson = decrypted.serialize();
|
||||
JSONAssert.assertEquals(json, decryptedJson, true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user