From ac0c477d23be4573987e15d2bf936ddf1c75fd30 Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Sat, 7 Apr 2018 16:36:17 -0500 Subject: [PATCH] Moved tests over to Kotlin. --- app/build.gradle | 25 +- .../nrw/commons/category/CategoryDao.java | 1 + .../fr/free/nrw/commons/FileUtilsTest.java | 40 -- .../java/fr/free/nrw/commons/LatLngTests.java | 64 --- .../fr/free/nrw/commons/LengthUtilsTest.java | 46 --- .../java/fr/free/nrw/commons/MediaTest.java | 25 -- .../nrw/commons/NearbyControllerTest.java | 44 --- .../fr/free/nrw/commons/PageTitleTest.java | 70 ---- .../nrw/commons/TestCommonsApplication.java | 181 --------- .../nrw/commons/UtilsFixExtensionTest.java | 57 --- .../nrw/commons/category/CategoryDaoTest.java | 294 -------------- .../contributions/ContributionDaoTest.java | 370 ------------------ .../ModifierSequenceDaoTest.java | 181 --------- .../ApacheHttpClientMediaWikiApiTest.java | 248 ------------ .../commons/utils/StringSortingUtilsTest.java | 41 -- .../fr/free/nrw/commons/FileUtilsTest.kt | 33 ++ .../kotlin/fr/free/nrw/commons/LatLngTests.kt | 64 +++ .../fr/free/nrw/commons/LengthUtilsTest.kt | 46 +++ .../kotlin/fr/free/nrw/commons/MediaTest.kt | 23 ++ .../free/nrw/commons/NearbyControllerTest.kt | 35 ++ .../fr/free/nrw/commons/PageTitleTest.kt | 67 ++++ .../nrw/commons/TestCommonsApplication.kt | 72 ++++ .../free/nrw/commons/UtilsFixExtensionTest.kt | 68 ++++ .../nrw/commons/category/CategoryDaoTest.kt | 257 ++++++++++++ .../contributions/ContributionDaoTest.kt | 335 ++++++++++++++++ .../modifications/ModifierSequenceDaoTest.kt | 156 ++++++++ .../mwapi/ApacheHttpClientMediaWikiApiTest.kt | 246 ++++++++++++ .../commons/utils/StringSortingUtilsTest.kt | 41 ++ build.gradle | 2 +- 29 files changed, 1453 insertions(+), 1679 deletions(-) delete mode 100644 app/src/test/java/fr/free/nrw/commons/FileUtilsTest.java delete mode 100644 app/src/test/java/fr/free/nrw/commons/LatLngTests.java delete mode 100644 app/src/test/java/fr/free/nrw/commons/LengthUtilsTest.java delete mode 100644 app/src/test/java/fr/free/nrw/commons/MediaTest.java delete mode 100644 app/src/test/java/fr/free/nrw/commons/NearbyControllerTest.java delete mode 100644 app/src/test/java/fr/free/nrw/commons/PageTitleTest.java delete mode 100644 app/src/test/java/fr/free/nrw/commons/TestCommonsApplication.java delete mode 100644 app/src/test/java/fr/free/nrw/commons/UtilsFixExtensionTest.java delete mode 100644 app/src/test/java/fr/free/nrw/commons/category/CategoryDaoTest.java delete mode 100644 app/src/test/java/fr/free/nrw/commons/contributions/ContributionDaoTest.java delete mode 100644 app/src/test/java/fr/free/nrw/commons/modifications/ModifierSequenceDaoTest.java delete mode 100644 app/src/test/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.java delete mode 100644 app/src/test/java/fr/free/nrw/commons/utils/StringSortingUtilsTest.java create mode 100644 app/src/test/kotlin/fr/free/nrw/commons/FileUtilsTest.kt create mode 100644 app/src/test/kotlin/fr/free/nrw/commons/LatLngTests.kt create mode 100644 app/src/test/kotlin/fr/free/nrw/commons/LengthUtilsTest.kt create mode 100644 app/src/test/kotlin/fr/free/nrw/commons/MediaTest.kt create mode 100644 app/src/test/kotlin/fr/free/nrw/commons/NearbyControllerTest.kt create mode 100644 app/src/test/kotlin/fr/free/nrw/commons/PageTitleTest.kt create mode 100644 app/src/test/kotlin/fr/free/nrw/commons/TestCommonsApplication.kt create mode 100644 app/src/test/kotlin/fr/free/nrw/commons/UtilsFixExtensionTest.kt create mode 100644 app/src/test/kotlin/fr/free/nrw/commons/category/CategoryDaoTest.kt create mode 100644 app/src/test/kotlin/fr/free/nrw/commons/contributions/ContributionDaoTest.kt create mode 100644 app/src/test/kotlin/fr/free/nrw/commons/modifications/ModifierSequenceDaoTest.kt create mode 100644 app/src/test/kotlin/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.kt create mode 100644 app/src/test/kotlin/fr/free/nrw/commons/utils/StringSortingUtilsTest.kt diff --git a/app/build.gradle b/app/build.gradle index b1ee9aef91..46008d1c25 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -18,11 +18,12 @@ dependencies { implementation 'com.google.code.gson:gson:2.8.1' implementation 'com.jakewharton.timber:timber:4.5.1' implementation 'info.debatty:java-string-similarity:0.24' + implementation 'com.borjabravo:readmoretextview:2.1.0' + implementation 'com.android.support.constraint:constraint-layout:1.0.2' implementation ('com.mapbox.mapboxsdk:mapbox-android-sdk:5.4.1@aar'){ transitive=true } - implementation "com.android.support:support-v4:$SUPPORT_LIB_VERSION" implementation "com.android.support:appcompat-v7:$SUPPORT_LIB_VERSION" implementation "com.android.support:design:$SUPPORT_LIB_VERSION" @@ -41,8 +42,6 @@ dependencies { // explicitly depend on RxJava's latest version for bug fixes and new features. implementation 'com.android.support:multidex:1.0.3' - testImplementation "org.robolectric:multidex:3.4.2" - implementation 'io.reactivex.rxjava2:rxjava:2.1.2' implementation 'com.jakewharton.rxbinding2:rxbinding:2.0.0' implementation 'com.jakewharton.rxbinding2:rxbinding-support-v4:2.0.0' @@ -54,33 +53,25 @@ dependencies { implementation "com.google.dagger:dagger:$DAGGER_VERSION" implementation "com.google.dagger:dagger-android-support:$DAGGER_VERSION" - kapt "com.google.dagger:dagger-android-processor:$DAGGER_VERSION" kapt "com.google.dagger:dagger-compiler:$DAGGER_VERSION" + testImplementation "org.robolectric:multidex:3.4.2" testImplementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" - androidTestImplementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" - + testImplementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" testImplementation 'junit:junit:4.12' testImplementation 'org.robolectric:robolectric:3.7.1' - testImplementation 'org.mockito:mockito-all:1.10.19' - + testImplementation 'com.nhaarman:mockito-kotlin:1.5.0' testImplementation 'com.squareup.okhttp3:mockwebserver:3.8.1' + + androidTestImplementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" androidTestImplementation 'com.squareup.okhttp3:mockwebserver:3.8.1' androidTestImplementation "com.android.support:support-annotations:$SUPPORT_LIB_VERSION" - androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2-alpha1' debugImplementation "com.squareup.leakcanary:leakcanary-android:$LEAK_CANARY" releaseImplementation "com.squareup.leakcanary:leakcanary-android-no-op:$LEAK_CANARY" testImplementation "com.squareup.leakcanary:leakcanary-android-no-op:$LEAK_CANARY" - - implementation "com.google.dagger:dagger:$DAGGER_VERSION" - implementation "com.google.dagger:dagger-android-support:$DAGGER_VERSION" - kapt "com.google.dagger:dagger-compiler:$DAGGER_VERSION" - kapt "com.google.dagger:dagger-android-processor:$DAGGER_VERSION" - - implementation 'com.borjabravo:readmoretextview:2.1.0' - implementation 'com.android.support.constraint:constraint-layout:1.0.2' } android { diff --git a/app/src/main/java/fr/free/nrw/commons/category/CategoryDao.java b/app/src/main/java/fr/free/nrw/commons/category/CategoryDao.java index a5202046b5..010e97095e 100644 --- a/app/src/main/java/fr/free/nrw/commons/category/CategoryDao.java +++ b/app/src/main/java/fr/free/nrw/commons/category/CategoryDao.java @@ -105,6 +105,7 @@ List recentCategories(int limit) { return items; } + @NonNull Category fromCursor(Cursor cursor) { // Hardcoding column positions! return new Category( diff --git a/app/src/test/java/fr/free/nrw/commons/FileUtilsTest.java b/app/src/test/java/fr/free/nrw/commons/FileUtilsTest.java deleted file mode 100644 index c6febc1e4e..0000000000 --- a/app/src/test/java/fr/free/nrw/commons/FileUtilsTest.java +++ /dev/null @@ -1,40 +0,0 @@ -package fr.free.nrw.commons; - -import org.junit.Assert; -import org.junit.Test; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; - -import fr.free.nrw.commons.upload.FileUtils; - -import static org.hamcrest.CoreMatchers.is; - -public class FileUtilsTest { - @Test public void copiedFileIsIdenticalToSource() throws IOException { - File source = File.createTempFile("temp", ""); - File dest = File.createTempFile("temp", ""); - writeToFile(source, "Hello, World"); - FileUtils.copy(new FileInputStream(source), new FileOutputStream(dest)); - Assert.assertThat(getString(dest), is(getString(source))); - } - - private static void writeToFile(File file, String s) throws IOException { - BufferedOutputStream buf = new BufferedOutputStream(new FileOutputStream(file)); - buf.write(s.getBytes()); - buf.close(); - } - - private static String getString(File file) throws IOException { - int size = (int) file.length(); - byte[] bytes = new byte[size]; - BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file)); - buf.read(bytes, 0, bytes.length); - buf.close(); - return new String(bytes); - } -} diff --git a/app/src/test/java/fr/free/nrw/commons/LatLngTests.java b/app/src/test/java/fr/free/nrw/commons/LatLngTests.java deleted file mode 100644 index c2fb1b159d..0000000000 --- a/app/src/test/java/fr/free/nrw/commons/LatLngTests.java +++ /dev/null @@ -1,64 +0,0 @@ -package fr.free.nrw.commons; - -import org.junit.Assert; -import org.junit.Test; - -import fr.free.nrw.commons.location.LatLng; - -import static org.hamcrest.CoreMatchers.is; - -public class LatLngTests { - @Test public void testZeroZero() { - LatLng place = new LatLng(0, 0, 0); - String prettyString = place.getPrettyCoordinateString(); - Assert.assertThat(prettyString, is("0.0 N, 0.0 E")); - } - - @Test public void testAntipode() { - LatLng place = new LatLng(0, 180, 0); - String prettyString = place.getPrettyCoordinateString(); - Assert.assertThat(prettyString, is("0.0 N, 180.0 W")); - } - - @Test public void testNorthPole() { - LatLng place = new LatLng(90, 0, 0); - String prettyString = place.getPrettyCoordinateString(); - Assert.assertThat(prettyString, is("90.0 N, 0.0 E")); - } - - @Test public void testSouthPole() { - LatLng place = new LatLng(-90, 0, 0); - String prettyString = place.getPrettyCoordinateString(); - Assert.assertThat(prettyString, is("90.0 S, 0.0 E")); - } - - @Test public void testLargerNumbers() { - LatLng place = new LatLng(120, 380, 0); - String prettyString = place.getPrettyCoordinateString(); - Assert.assertThat(prettyString, is("90.0 N, 20.0 E")); - } - - @Test public void testNegativeNumbers() { - LatLng place = new LatLng(-120, -30, 0); - String prettyString = place.getPrettyCoordinateString(); - Assert.assertThat(prettyString, is("90.0 S, 30.0 W")); - } - - @Test public void testTooBigWestValue() { - LatLng place = new LatLng(20, -190, 0); - String prettyString = place.getPrettyCoordinateString(); - Assert.assertThat(prettyString, is("20.0 N, 170.0 E")); - } - - @Test public void testRounding() { - LatLng place = new LatLng(0.1234567, -0.33333333, 0); - String prettyString = place.getPrettyCoordinateString(); - Assert.assertThat(prettyString, is("0.1235 N, 0.3333 W")); - } - - @Test public void testRoundingAgain() { - LatLng place = new LatLng(-0.000001, -0.999999, 0); - String prettyString = place.getPrettyCoordinateString(); - Assert.assertThat(prettyString, is("0.0 S, 1.0 W")); - } -} diff --git a/app/src/test/java/fr/free/nrw/commons/LengthUtilsTest.java b/app/src/test/java/fr/free/nrw/commons/LengthUtilsTest.java deleted file mode 100644 index 561f3f0e63..0000000000 --- a/app/src/test/java/fr/free/nrw/commons/LengthUtilsTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package fr.free.nrw.commons; - -import org.junit.Assert; -import org.junit.Test; - -import fr.free.nrw.commons.location.LatLng; -import fr.free.nrw.commons.utils.LengthUtils; - -import static org.hamcrest.CoreMatchers.is; - -public class LengthUtilsTest { - @Test public void testZeroDistance() { - LatLng pointA = new LatLng(0, 0, 0); - LatLng pointB = new LatLng(0, 0, 0); - String distance = LengthUtils.formatDistanceBetween(pointA, pointB); - Assert.assertThat(distance, is("0m")); - } - - @Test public void testOneDegreeOnEquator() { - LatLng pointA = new LatLng(0, 0, 0); - LatLng pointB = new LatLng(0, 1, 0); - String distance = LengthUtils.formatDistanceBetween(pointA, pointB); - Assert.assertThat(distance, is("111.2km")); - } - - @Test public void testOneDegreeFortyFiveDegrees() { - LatLng pointA = new LatLng(45, 0, 0); - LatLng pointB = new LatLng(45, 1, 0); - String distance = LengthUtils.formatDistanceBetween(pointA, pointB); - Assert.assertThat(distance, is("78.6km")); - } - - @Test public void testOneDegreeSouthPole() { - LatLng pointA = new LatLng(-90, 0, 0); - LatLng pointB = new LatLng(-90, 1, 0); - String distance = LengthUtils.formatDistanceBetween(pointA, pointB); - Assert.assertThat(distance, is("0m")); - } - - @Test public void testPoleToPole() { - LatLng pointA = new LatLng(90, 0, 0); - LatLng pointB = new LatLng(-90, 0, 0); - String distance = LengthUtils.formatDistanceBetween(pointA, pointB); - Assert.assertThat(distance, is("20,015.1km")); - } -} diff --git a/app/src/test/java/fr/free/nrw/commons/MediaTest.java b/app/src/test/java/fr/free/nrw/commons/MediaTest.java deleted file mode 100644 index 4f53351ad8..0000000000 --- a/app/src/test/java/fr/free/nrw/commons/MediaTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package fr.free.nrw.commons; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -@RunWith(RobolectricTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 21, application = TestCommonsApplication.class) -public class MediaTest { - @Test - public void displayTitleShouldStripExtension() { - Media m = new Media("File:Example.jpg"); - assertThat(m.getDisplayTitle(), is("Example")); - } - - @Test - public void displayTitleShouldUseSpaceForUnderscore() { - Media m = new Media("File:Example 1_2.jpg"); - assertThat(m.getDisplayTitle(), is("Example 1 2")); - } -} diff --git a/app/src/test/java/fr/free/nrw/commons/NearbyControllerTest.java b/app/src/test/java/fr/free/nrw/commons/NearbyControllerTest.java deleted file mode 100644 index 752b7404d5..0000000000 --- a/app/src/test/java/fr/free/nrw/commons/NearbyControllerTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package fr.free.nrw.commons; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; - -import java.util.ArrayList; -import java.util.List; - -import fr.free.nrw.commons.location.LatLng; -import fr.free.nrw.commons.nearby.NearbyBaseMarker; -import fr.free.nrw.commons.nearby.Place; - -import static fr.free.nrw.commons.nearby.NearbyController.loadAttractionsFromLocationToBaseMarkerOptions; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -@RunWith(RobolectricTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 21, application = TestCommonsApplication.class) -public class NearbyControllerTest { - - @Test - public void testNullAttractions() { - LatLng location = new LatLng(0, 0, 0); - - List options = loadAttractionsFromLocationToBaseMarkerOptions( - location, null, RuntimeEnvironment.application); - - assertThat(options.size(), is(0)); - } - - @Test - public void testEmptyList() { - LatLng location = new LatLng(0, 0, 0); - List emptyList = new ArrayList<>(); - - List options = loadAttractionsFromLocationToBaseMarkerOptions( - location, emptyList, RuntimeEnvironment.application); - - assertThat(options.size(), is(0)); - } -} diff --git a/app/src/test/java/fr/free/nrw/commons/PageTitleTest.java b/app/src/test/java/fr/free/nrw/commons/PageTitleTest.java deleted file mode 100644 index 16336b1b0e..0000000000 --- a/app/src/test/java/fr/free/nrw/commons/PageTitleTest.java +++ /dev/null @@ -1,70 +0,0 @@ -package fr.free.nrw.commons; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -import java.net.URLEncoder; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -@RunWith(RobolectricTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 21, application = TestCommonsApplication.class) -public class PageTitleTest { - @Test - public void displayTextShouldNotBeUnderscored() { - assertThat(new PageTitle("Ex_1 ").getDisplayText(), - is("Ex 1")); - } - - @Test - public void moreThanTwoColons() { - assertThat(new PageTitle("File:sample:a.jpg").getPrefixedText(), - is("File:Sample:a.jpg")); - } - - @Test - public void getTextShouldReturnWithoutNamespace() { - assertThat(new PageTitle("File:sample.jpg").getText(), - is("Sample.jpg")); - } - - - @Test - public void capitalizeNameAfterNamespace() { - assertThat(new PageTitle("File:sample.jpg").getPrefixedText(), - is("File:Sample.jpg")); - } - - @Test - public void prefixedTextShouldBeUnderscored() { - assertThat(new PageTitle("Ex 1 ").getPrefixedText(), - is("Ex_1")); - } - - @Test - public void getMobileUriForTest() { - assertThat(new PageTitle("Test").getMobileUri().toString(), - is(BuildConfig.MOBILE_HOME_URL + "Test")); - } - - @Test - public void spaceBecomesUnderscoreInUri() { - assertThat(new PageTitle("File:Ex 1.jpg").getCanonicalUri().toString(), - is(BuildConfig.HOME_URL + "File:Ex_1.jpg")); - } - - @Test - public void leaveSubpageNamesUncapitalizedInUri() { - assertThat(new PageTitle("User:Ex/subpage").getCanonicalUri().toString(), - is(BuildConfig.HOME_URL + "User:Ex/subpage")); - } - - @Test - public void unicodeUri() throws Throwable { - assertThat(new PageTitle("User:例").getCanonicalUri().toString(), - is(BuildConfig.HOME_URL + "User:" + URLEncoder.encode("例", "utf-8"))); - } -} diff --git a/app/src/test/java/fr/free/nrw/commons/TestCommonsApplication.java b/app/src/test/java/fr/free/nrw/commons/TestCommonsApplication.java deleted file mode 100644 index 9f7bc61845..0000000000 --- a/app/src/test/java/fr/free/nrw/commons/TestCommonsApplication.java +++ /dev/null @@ -1,181 +0,0 @@ -package fr.free.nrw.commons; - -import android.content.Context; -import android.content.SharedPreferences; -import android.support.v4.util.LruCache; - -import com.squareup.leakcanary.RefWatcher; - -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import javax.inject.Named; - -import dagger.Provides; -import fr.free.nrw.commons.auth.AccountUtil; -import fr.free.nrw.commons.auth.SessionManager; -import fr.free.nrw.commons.caching.CacheController; -import fr.free.nrw.commons.data.DBOpenHelper; -import fr.free.nrw.commons.di.CommonsApplicationComponent; -import fr.free.nrw.commons.di.CommonsApplicationModule; -import fr.free.nrw.commons.di.DaggerCommonsApplicationComponent; -import fr.free.nrw.commons.location.LocationServiceManager; -import fr.free.nrw.commons.mwapi.MediaWikiApi; -import fr.free.nrw.commons.nearby.NearbyPlaces; -import fr.free.nrw.commons.upload.UploadController; - -public class TestCommonsApplication extends CommonsApplication { - - CommonsApplicationComponent mockApplicationComponent; - - @Mock - CommonsApplicationModule commonsApplicationModule; - @Mock - AccountUtil accountUtil; - @Mock - SharedPreferences appSharedPreferences; - @Mock - SharedPreferences defaultSharedPreferences; - @Mock - SharedPreferences otherSharedPreferences; - @Mock - UploadController uploadController; - @Mock - SessionManager sessionManager; - @Mock - MediaWikiApi mediaWikiApi; - @Mock - LocationServiceManager locationServiceManager; - @Mock - CacheController cacheController; - @Mock - DBOpenHelper dbOpenHelper; - @Mock - NearbyPlaces nearbyPlaces; - @Mock - LruCache lruCache; - - @Override - public void onCreate() { - MockitoAnnotations.initMocks(this); - if (mockApplicationComponent == null) { - mockApplicationComponent = DaggerCommonsApplicationComponent.builder() - .appModule(new CommonsApplicationModule(this) { - @Override - public AccountUtil providesAccountUtil(Context context) { - return accountUtil; - } - - @Override - public SharedPreferences providesApplicationSharedPreferences(Context context) { - return appSharedPreferences; - } - - @Override - public SharedPreferences providesDefaultSharedPreferences(Context context) { - return defaultSharedPreferences; - } - - @Override - public SharedPreferences providesOtherSharedPreferences(Context context) { - return otherSharedPreferences; - } - - @Override - public UploadController providesUploadController(SessionManager sessionManager, SharedPreferences sharedPreferences, Context context) { - return uploadController; - } - - @Override - public SessionManager providesSessionManager(Context context, MediaWikiApi mediaWikiApi, SharedPreferences sharedPreferences) { - return sessionManager; - } - - @Override - public MediaWikiApi provideMediaWikiApi(Context context, SharedPreferences sharedPreferences) { - return mediaWikiApi; - } - - @Override - public LocationServiceManager provideLocationServiceManager(Context context) { - return locationServiceManager; - } - - @Override - public CacheController provideCacheController() { - return cacheController; - } - - @Override - public DBOpenHelper provideDBOpenHelper(Context context) { - return dbOpenHelper; - } - - @Override - public NearbyPlaces provideNearbyPlaces() { - return nearbyPlaces; - } - - @Override - public LruCache provideLruCache() { - return lruCache; - } - }).build(); - } - super.onCreate(); - } - - @Override - protected RefWatcher setupLeakCanary() { - // No leakcanary in unit tests. - return RefWatcher.DISABLED; - } - - public AccountUtil getAccountUtil() { - return accountUtil; - } - - public SharedPreferences getAppSharedPreferences() { - return appSharedPreferences; - } - - public SharedPreferences getDefaultSharedPreferences() { - return defaultSharedPreferences; - } - - public SharedPreferences getOtherSharedPreferences() { - return otherSharedPreferences; - } - - public UploadController getUploadController() { - return uploadController; - } - - public SessionManager getSessionManager() { - return sessionManager; - } - - public MediaWikiApi getMediaWikiApi() { - return mediaWikiApi; - } - - public LocationServiceManager getLocationServiceManager() { - return locationServiceManager; - } - - public CacheController getCacheController() { - return cacheController; - } - - public DBOpenHelper getDbOpenHelper() { - return dbOpenHelper; - } - - public NearbyPlaces getNearbyPlaces() { - return nearbyPlaces; - } - - public LruCache getLruCache() { - return lruCache; - } -} diff --git a/app/src/test/java/fr/free/nrw/commons/UtilsFixExtensionTest.java b/app/src/test/java/fr/free/nrw/commons/UtilsFixExtensionTest.java deleted file mode 100644 index 186f30df9c..0000000000 --- a/app/src/test/java/fr/free/nrw/commons/UtilsFixExtensionTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package fr.free.nrw.commons; - -import org.junit.Assert; -import org.junit.Test; - -import static org.hamcrest.CoreMatchers.is; - -public class UtilsFixExtensionTest { - - @Test public void jpegResultsInJpg() { - Assert.assertThat(Utils.fixExtension("SampleFile.jpeg", "jpeg"), is("SampleFile.jpg")); - } - - @Test public void capitalJpegWithNoHintResultsInJpg() { - Assert.assertThat(Utils.fixExtension("SampleFile.JPEG", null), is("SampleFile.jpg")); - } - - @Test public void jpegWithBogusHintResultsInJpg() { - Assert.assertThat(Utils.fixExtension("SampleFile.jpeg", null), is("SampleFile.jpg")); - } - - @Test public void jpegToCapitalJpegResultsInJpg() { - Assert.assertThat(Utils.fixExtension("SampleFile.jpeg", "JPEG"), is("SampleFile.jpg")); - } - - @Test public void jpgToJpegResultsInJpg() { - Assert.assertThat(Utils.fixExtension("SampleFile.jpg", "jpeg"), is("SampleFile.jpg")); - } - - @Test public void jpegToJpgResultsInJpg() { - Assert.assertThat(Utils.fixExtension("SampleFile.jpeg", "jpg"), is("SampleFile.jpg")); - } - - @Test public void jpgRemainsJpg() { - Assert.assertThat(Utils.fixExtension("SampleFile.jpg", "jpg"), is("SampleFile.jpg")); - } - - @Test public void pngRemainsPng() { - Assert.assertThat(Utils.fixExtension("SampleFile.png", "png"), is("SampleFile.png")); - } - - @Test public void jpgHintResultsInJpg() { - Assert.assertThat(Utils.fixExtension("SampleFile", "jpg"), is("SampleFile.jpg")); - } - - @Test public void jpegHintResultsInJpg() { - Assert.assertThat(Utils.fixExtension("SampleFile", "jpeg"), is("SampleFile.jpg")); - } - - @Test public void dotLessJpgToJpgResultsInJpg() { - Assert.assertThat(Utils.fixExtension("SAMPLEjpg", "jpg"), is("SAMPLEjpg.jpg")); - } - - @Test public void inWordJpegToJpgResultsInJpg() { - Assert.assertThat(Utils.fixExtension("X.jpeg.SAMPLE", "jpg"),is("X.jpeg.SAMPLE.jpg")); - } -} diff --git a/app/src/test/java/fr/free/nrw/commons/category/CategoryDaoTest.java b/app/src/test/java/fr/free/nrw/commons/category/CategoryDaoTest.java deleted file mode 100644 index 1cf0c338b9..0000000000 --- a/app/src/test/java/fr/free/nrw/commons/category/CategoryDaoTest.java +++ /dev/null @@ -1,294 +0,0 @@ -package fr.free.nrw.commons.category; - -import android.content.ContentProviderClient; -import android.content.ContentValues; -import android.database.Cursor; -import android.database.MatrixCursor; -import android.database.sqlite.SQLiteDatabase; -import android.net.Uri; -import android.os.RemoteException; -import android.support.annotation.NonNull; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.InOrder; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -import java.util.Arrays; -import java.util.Date; -import java.util.List; - -import fr.free.nrw.commons.BuildConfig; -import fr.free.nrw.commons.TestCommonsApplication; -import fr.free.nrw.commons.category.CategoryDao.Table; - -import static fr.free.nrw.commons.category.CategoryContentProvider.BASE_URI; -import static fr.free.nrw.commons.category.CategoryContentProvider.uriForId; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertNull; -import static junit.framework.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; -import static org.mockito.Matchers.isA; -import static org.mockito.Matchers.isNull; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; - -@RunWith(RobolectricTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 21, application = TestCommonsApplication.class) -public class CategoryDaoTest { - - @Mock - private ContentProviderClient client; - @Mock - private SQLiteDatabase database; - @Captor - private ArgumentCaptor captor; - @Captor - private ArgumentCaptor queryCaptor; - - private CategoryDao testObject; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - testObject = new CategoryDao(() -> client); - } - - @Test - public void createTable() { - Table.onCreate(database); - verify(database).execSQL(Table.CREATE_TABLE_STATEMENT); - } - - @Test - public void deleteTable() { - Table.onDelete(database); - InOrder inOrder = Mockito.inOrder(database); - inOrder.verify(database).execSQL(Table.DROP_TABLE_STATEMENT); - inOrder.verify(database).execSQL(Table.CREATE_TABLE_STATEMENT); - } - - @Test - public void migrateTableVersionFrom_v1_to_v2() { - Table.onUpdate(database, 1, 2); - // Table didnt exist before v5 - verifyZeroInteractions(database); - } - - @Test - public void migrateTableVersionFrom_v2_to_v3() { - Table.onUpdate(database, 2, 3); - // Table didnt exist before v5 - verifyZeroInteractions(database); - } - - @Test - public void migrateTableVersionFrom_v3_to_v4() { - Table.onUpdate(database, 3, 4); - // Table didnt exist before v5 - verifyZeroInteractions(database); - } - - @Test - public void migrateTableVersionFrom_v4_to_v5() { - Table.onUpdate(database, 4, 5); - verify(database).execSQL(Table.CREATE_TABLE_STATEMENT); - } - - @Test - public void migrateTableVersionFrom_v5_to_v6() { - Table.onUpdate(database, 5, 6); - // Table didnt change in version 6 - verifyZeroInteractions(database); - } - - @Test - public void createFromCursor() { - MatrixCursor cursor = createCursor(1); - cursor.moveToFirst(); - Category category = testObject.fromCursor(cursor); - - assertEquals(uriForId(1), category.getContentUri()); - assertEquals("foo", category.getName()); - assertEquals(123, category.getLastUsed().getTime()); - assertEquals(2, category.getTimesUsed()); - } - - @Test - public void saveExistingCategory() throws Exception { - MatrixCursor cursor = createCursor(1); - cursor.moveToFirst(); - Category category = testObject.fromCursor(cursor); - - testObject.save(category); - - verify(client).update(eq(category.getContentUri()), captor.capture(), isNull(String.class), isNull(String[].class)); - ContentValues cv = captor.getValue(); - assertEquals(3, cv.size()); - assertEquals(category.getName(), cv.getAsString(Table.COLUMN_NAME)); - assertEquals(category.getLastUsed().getTime(), cv.getAsLong(Table.COLUMN_LAST_USED).longValue()); - assertEquals(category.getTimesUsed(), cv.getAsInteger(Table.COLUMN_TIMES_USED).intValue()); - } - - @Test - public void saveNewCategory() throws Exception { - Uri contentUri = CategoryContentProvider.uriForId(111); - when(client.insert(isA(Uri.class), isA(ContentValues.class))).thenReturn(contentUri); - Category category = new Category(null, "foo", new Date(234L), 1); - - testObject.save(category); - - verify(client).insert(eq(BASE_URI), captor.capture()); - ContentValues cv = captor.getValue(); - assertEquals(3, cv.size()); - assertEquals(category.getName(), cv.getAsString(Table.COLUMN_NAME)); - assertEquals(category.getLastUsed().getTime(), cv.getAsLong(Table.COLUMN_LAST_USED).longValue()); - assertEquals(category.getTimesUsed(), cv.getAsInteger(Table.COLUMN_TIMES_USED).intValue()); - assertEquals(contentUri, category.getContentUri()); - } - - @Test(expected = RuntimeException.class) - public void testSaveTranslatesRemoteExceptions() throws Exception { - when(client.insert(isA(Uri.class), isA(ContentValues.class))).thenThrow(new RemoteException("")); - testObject.save(new Category()); - } - - @Test - public void whenTheresNoDataFindReturnsNull_nullCursor() throws Exception { - when(client.query(any(), any(), anyString(), any(), anyString())).thenReturn(null); - - assertNull(testObject.find("foo")); - } - - @Test - public void whenTheresNoDataFindReturnsNull_emptyCursor() throws Exception { - when(client.query(any(), any(), anyString(), any(), anyString())).thenReturn(createCursor(0)); - - assertNull(testObject.find("foo")); - } - - @Test - public void cursorsAreClosedAfterUse() throws Exception { - Cursor mockCursor = mock(Cursor.class); - when(client.query(any(), any(), anyString(), any(), anyString())).thenReturn(mockCursor); - when(mockCursor.moveToFirst()).thenReturn(false); - - testObject.find("foo"); - - verify(mockCursor).close(); - } - - @Test - public void findCategory() throws Exception { - when(client.query(any(), any(), anyString(), any(), anyString())).thenReturn(createCursor(1)); - - Category category = testObject.find("foo"); - - assertEquals(uriForId(1), category.getContentUri()); - assertEquals("foo", category.getName()); - assertEquals(123, category.getLastUsed().getTime()); - assertEquals(2, category.getTimesUsed()); - - verify(client).query( - eq(BASE_URI), - eq(Table.ALL_FIELDS), - eq(Table.COLUMN_NAME + "=?"), - queryCaptor.capture(), - isNull(String.class) - ); - assertEquals("foo", queryCaptor.getValue()[0]); - } - - @Test(expected = RuntimeException.class) - public void findCategoryTranslatesExceptions() throws Exception { - when(client.query(any(), any(), anyString(), any(), anyString())).thenThrow(new RemoteException("")); - testObject.find("foo"); - } - - @Test(expected = RuntimeException.class) - public void recentCategoriesTranslatesExceptions() throws Exception { - when(client.query(any(), any(), anyString(), any(), anyString())).thenThrow(new RemoteException("")); - testObject.recentCategories(1); - } - - @Test - public void recentCategoriesReturnsEmptyList_nullCursor() throws Exception { - when(client.query(any(), any(), anyString(), any(), anyString())).thenReturn(null); - - assertTrue(testObject.recentCategories(1).isEmpty()); - } - - @Test - public void recentCategoriesReturnsEmptyList_emptyCursor() throws Exception { - when(client.query(any(), any(), anyString(), any(), anyString())).thenReturn(createCursor(0)); - - assertTrue(testObject.recentCategories(1).isEmpty()); - } - - @Test - public void cursorsAreClosedAfterRecentCategoriesQuery() throws Exception { - Cursor mockCursor = mock(Cursor.class); - when(client.query(any(), any(), anyString(), any(), anyString())).thenReturn(mockCursor); - when(mockCursor.moveToFirst()).thenReturn(false); - - testObject.recentCategories(1); - - verify(mockCursor).close(); - } - - @Test - public void recentCategoriesReturnsLessThanLimit() throws Exception { - when(client.query(any(), any(), anyString(), any(), anyString())).thenReturn(createCursor(1)); - - List result = testObject.recentCategories(10); - - assertEquals(1, result.size()); - assertEquals("foo", result.get(0)); - - verify(client).query( - eq(BASE_URI), - eq(Table.ALL_FIELDS), - isNull(String.class), - queryCaptor.capture(), - eq(Table.COLUMN_LAST_USED + " DESC") - ); - assertEquals(0, queryCaptor.getValue().length); - } - - @Test - public void recentCategoriesHomorsLimit() throws Exception { - when(client.query(any(), any(), anyString(), any(), anyString())).thenReturn(createCursor(10)); - - List result = testObject.recentCategories(5); - - assertEquals(5, result.size()); - } - - @NonNull - private MatrixCursor createCursor(int rowCount) { - MatrixCursor cursor = new MatrixCursor(new String[]{ - Table.COLUMN_ID, - Table.COLUMN_NAME, - Table.COLUMN_LAST_USED, - Table.COLUMN_TIMES_USED - }, rowCount); - - for (int i = 0; i < rowCount; i++) { - cursor.addRow(Arrays.asList("1", "foo", "123", "2")); - } - - return cursor; - } - -} \ No newline at end of file diff --git a/app/src/test/java/fr/free/nrw/commons/contributions/ContributionDaoTest.java b/app/src/test/java/fr/free/nrw/commons/contributions/ContributionDaoTest.java deleted file mode 100644 index 15e37e6408..0000000000 --- a/app/src/test/java/fr/free/nrw/commons/contributions/ContributionDaoTest.java +++ /dev/null @@ -1,370 +0,0 @@ -package fr.free.nrw.commons.contributions; - -import android.content.ContentProviderClient; -import android.content.ContentValues; -import android.database.MatrixCursor; -import android.database.sqlite.SQLiteDatabase; -import android.net.Uri; -import android.os.RemoteException; -import android.support.annotation.NonNull; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.InOrder; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -import java.util.Arrays; -import java.util.Date; - -import fr.free.nrw.commons.BuildConfig; -import fr.free.nrw.commons.TestCommonsApplication; -import fr.free.nrw.commons.Utils; - -import static fr.free.nrw.commons.contributions.Contribution.SOURCE_CAMERA; -import static fr.free.nrw.commons.contributions.Contribution.SOURCE_GALLERY; -import static fr.free.nrw.commons.contributions.Contribution.STATE_COMPLETED; -import static fr.free.nrw.commons.contributions.Contribution.STATE_QUEUED; -import static fr.free.nrw.commons.contributions.ContributionDao.Table; -import static fr.free.nrw.commons.contributions.ContributionsContentProvider.BASE_URI; -import static fr.free.nrw.commons.contributions.ContributionsContentProvider.uriForId; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Matchers.isA; -import static org.mockito.Matchers.isNull; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; - -@RunWith(RobolectricTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 21, application = TestCommonsApplication.class) -public class ContributionDaoTest { - - private static final String LOCAL_URI = "http://example.com/"; - @Mock - private ContentProviderClient client; - @Mock - private SQLiteDatabase database; - @Captor - private ArgumentCaptor captor; - - private Uri contentUri; - private ContributionDao testObject; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - - contentUri = uriForId(111); - - testObject = new ContributionDao(() -> client); - } - - @Test - public void createTable() { - Table.onCreate(database); - verify(database).execSQL(Table.CREATE_TABLE_STATEMENT); - } - - @Test - public void deleteTable() { - Table.onDelete(database); - - InOrder inOrder = Mockito.inOrder(database); - inOrder.verify(database).execSQL(Table.DROP_TABLE_STATEMENT); - inOrder.verify(database).execSQL(Table.CREATE_TABLE_STATEMENT); - } - - @Test - public void upgradeDatabase_v1_to_v2() { - Table.onUpdate(database, 1, 2); - - InOrder inOrder = Mockito.inOrder(database); - inOrder.verify(database).execSQL(Table.ADD_DESCRIPTION_FIELD); - inOrder.verify(database).execSQL(Table.ADD_CREATOR_FIELD); - } - - @Test - public void upgradeDatabase_v2_to_v3() { - Table.onUpdate(database, 2, 3); - - InOrder inOrder = Mockito.inOrder(database); - inOrder.verify(database).execSQL(Table.ADD_MULTIPLE_FIELD); - inOrder.verify(database).execSQL(Table.SET_DEFAULT_MULTIPLE); - } - - @Test - public void upgradeDatabase_v3_to_v4() { - Table.onUpdate(database, 3, 4); - - // No changes - verifyZeroInteractions(database); - } - - @Test - public void upgradeDatabase_v4_to_v5() { - Table.onUpdate(database, 4, 5); - - // No changes - verifyZeroInteractions(database); - } - - @Test - public void upgradeDatabase_v5_to_v6() { - Table.onUpdate(database, 5, 6); - - InOrder inOrder = Mockito.inOrder(database); - inOrder.verify(database).execSQL(Table.ADD_WIDTH_FIELD); - inOrder.verify(database).execSQL(Table.SET_DEFAULT_WIDTH); - inOrder.verify(database).execSQL(Table.ADD_HEIGHT_FIELD); - inOrder.verify(database).execSQL(Table.SET_DEFAULT_HEIGHT); - inOrder.verify(database).execSQL(Table.ADD_LICENSE_FIELD); - inOrder.verify(database).execSQL(Table.SET_DEFAULT_LICENSE); - } - - @Test - public void saveNewContribution_nonNullFields() throws Exception { - when(client.insert(isA(Uri.class), isA(ContentValues.class))).thenReturn(contentUri); - Contribution contribution = createContribution(true, null, null, null, null); - - testObject.save(contribution); - - assertEquals(contentUri, contribution.getContentUri()); - verify(client).insert(eq(BASE_URI), captor.capture()); - ContentValues cv = captor.getValue(); - - // Long fields - assertEquals(222L, cv.getAsLong(Table.COLUMN_LENGTH).longValue()); - assertEquals(321L, cv.getAsLong(Table.COLUMN_TIMESTAMP).longValue()); - assertEquals(333L, cv.getAsLong(Table.COLUMN_TRANSFERRED).longValue()); - - // Integer fields - assertEquals(STATE_COMPLETED, cv.getAsInteger(Table.COLUMN_STATE).intValue()); - assertEquals(640, cv.getAsInteger(Table.COLUMN_WIDTH).intValue()); - assertEquals(480, cv.getAsInteger(Table.COLUMN_HEIGHT).intValue()); - - // String fields - assertEquals(SOURCE_CAMERA, cv.getAsString(Table.COLUMN_SOURCE)); - assertEquals("desc", cv.getAsString(Table.COLUMN_DESCRIPTION)); - assertEquals("create", cv.getAsString(Table.COLUMN_CREATOR)); - assertEquals("007", cv.getAsString(Table.COLUMN_LICENSE)); - } - - @Test - public void saveNewContribution_nullableFieldsAreNull() throws Exception { - when(client.insert(isA(Uri.class), isA(ContentValues.class))).thenReturn(contentUri); - Contribution contribution = createContribution(true, null, null, null, null); - - testObject.save(contribution); - - assertEquals(contentUri, contribution.getContentUri()); - verify(client).insert(eq(BASE_URI), captor.capture()); - ContentValues cv = captor.getValue(); - - // Nullable fields are absent if null - assertFalse(cv.containsKey(Table.COLUMN_LOCAL_URI)); - assertFalse(cv.containsKey(Table.COLUMN_IMAGE_URL)); - assertFalse(cv.containsKey(Table.COLUMN_UPLOADED)); - } - - @Test - public void saveNewContribution_nullableImageUrlUsesFileAsBackup() throws Exception { - when(client.insert(isA(Uri.class), isA(ContentValues.class))).thenReturn(contentUri); - Contribution contribution = createContribution(true, null, null, null, "file"); - - testObject.save(contribution); - - assertEquals(contentUri, contribution.getContentUri()); - verify(client).insert(eq(BASE_URI), captor.capture()); - ContentValues cv = captor.getValue(); - - // Nullable fields are absent if null - assertFalse(cv.containsKey(Table.COLUMN_LOCAL_URI)); - assertFalse(cv.containsKey(Table.COLUMN_UPLOADED)); - - assertEquals(Utils.makeThumbBaseUrl("file"), cv.getAsString(Table.COLUMN_IMAGE_URL)); - } - - @Test - public void saveNewContribution_nullableFieldsAreNonNull() throws Exception { - when(client.insert(isA(Uri.class), isA(ContentValues.class))).thenReturn(contentUri); - Contribution contribution = createContribution(true, Uri.parse(LOCAL_URI), - "image", new Date(456L), null); - - testObject.save(contribution); - - assertEquals(contentUri, contribution.getContentUri()); - verify(client).insert(eq(BASE_URI), captor.capture()); - ContentValues cv = captor.getValue(); - - assertEquals(LOCAL_URI, cv.getAsString(Table.COLUMN_LOCAL_URI)); - assertEquals("image", cv.getAsString(Table.COLUMN_IMAGE_URL)); - assertEquals(456L, cv.getAsLong(Table.COLUMN_UPLOADED).longValue()); - } - - @Test - public void saveNewContribution_booleanEncodesTrue() throws Exception { - when(client.insert(isA(Uri.class), isA(ContentValues.class))).thenReturn(contentUri); - Contribution contribution = createContribution(true, null, null, null, null); - - testObject.save(contribution); - - assertEquals(contentUri, contribution.getContentUri()); - verify(client).insert(eq(BASE_URI), captor.capture()); - ContentValues cv = captor.getValue(); - - // Boolean true --> 1 for ths encoding scheme - assertEquals("Boolean true should be encoded as 1", 1, - cv.getAsInteger(Table.COLUMN_MULTIPLE).intValue()); - } - - @Test - public void saveNewContribution_booleanEncodesFalse() throws Exception { - when(client.insert(isA(Uri.class), isA(ContentValues.class))).thenReturn(contentUri); - Contribution contribution = createContribution(false, null, null, null, null); - - testObject.save(contribution); - - assertEquals(contentUri, contribution.getContentUri()); - verify(client).insert(eq(BASE_URI), captor.capture()); - ContentValues cv = captor.getValue(); - - // Boolean true --> 1 for ths encoding scheme - assertEquals("Boolean false should be encoded as 0", 0, - cv.getAsInteger(Table.COLUMN_MULTIPLE).intValue()); - } - - @Test - public void saveExistingContribution() throws Exception { - Contribution contribution = createContribution(false, null, null, null, null); - contribution.setContentUri(contentUri); - - testObject.save(contribution); - - verify(client).update(eq(contentUri), isA(ContentValues.class), isNull(String.class), isNull(String[].class)); - } - - @Test(expected = RuntimeException.class) - public void saveTranslatesExceptions() throws Exception { - when(client.insert(isA(Uri.class), isA(ContentValues.class))).thenThrow(new RemoteException("")); - - testObject.save(createContribution(false, null, null, null, null)); - } - - @Test(expected = RuntimeException.class) - public void deleteTranslatesExceptions() throws Exception { - when(client.delete(isA(Uri.class), any(), any())).thenThrow(new RemoteException("")); - - Contribution contribution = createContribution(false, null, null, null, null); - contribution.setContentUri(contentUri); - testObject.delete(contribution); - } - - @Test(expected = RuntimeException.class) - public void exceptionThrownWhenAttemptingToDeleteUnsavedContribution() { - testObject.delete(createContribution(false, null, null, null, null)); - } - - @Test - public void deleteExistingContribution() throws Exception { - Contribution contribution = createContribution(false, null, null, null, null); - contribution.setContentUri(contentUri); - - testObject.delete(contribution); - - verify(client).delete(eq(contentUri), isNull(String.class), isNull(String[].class)); - } - - @Test - public void createFromCursor() { - long created = 321L; - long uploaded = 456L; - MatrixCursor mc = createCursor(created, uploaded, false, LOCAL_URI); - - Contribution c = testObject.fromCursor(mc); - - assertEquals(uriForId(111), c.getContentUri()); - assertEquals("file", c.getFilename()); - assertEquals(LOCAL_URI, c.getLocalUri().toString()); - assertEquals("image", c.getImageUrl()); - assertEquals(created, c.getTimestamp().getTime()); - assertEquals(created, c.getDateCreated().getTime()); - assertEquals(STATE_QUEUED, c.getState()); - assertEquals(222L, c.getDataLength()); - assertEquals(uploaded, c.getDateUploaded().getTime()); - assertEquals(88L, c.getTransferred()); - assertEquals(SOURCE_GALLERY, c.getSource()); - assertEquals("desc", c.getDescription()); - assertEquals("create", c.getCreator()); - assertEquals(640, c.getWidth()); - assertEquals(480, c.getHeight()); - assertEquals("007", c.getLicense()); - } - - @Test - public void createFromCursor_nullableTimestamps() { - MatrixCursor mc = createCursor(0L, 0L, false, LOCAL_URI); - - Contribution c = testObject.fromCursor(mc); - - assertNull(c.getTimestamp()); - assertNull(c.getDateCreated()); - assertNull(c.getDateUploaded()); - } - - @Test - public void createFromCursor_nullableLocalUri() { - MatrixCursor mc = createCursor(0L, 0L, false, ""); - - Contribution c = testObject.fromCursor(mc); - - assertNull(c.getLocalUri()); - assertNull(c.getDateCreated()); - assertNull(c.getDateUploaded()); - } - - @Test - public void createFromCursor_booleanEncoding() { - MatrixCursor mcFalse = createCursor(0L, 0L, false, LOCAL_URI); - assertFalse(testObject.fromCursor(mcFalse).getMultiple()); - - MatrixCursor mcHammer = createCursor(0L, 0L, true, LOCAL_URI); - assertTrue(testObject.fromCursor(mcHammer).getMultiple()); - } - - @NonNull - private MatrixCursor createCursor(long created, long uploaded, boolean multiple, String localUri) { - MatrixCursor mc = new MatrixCursor(Table.ALL_FIELDS, 1); - mc.addRow(Arrays.asList("111", "file", localUri, "image", - created, STATE_QUEUED, 222L, uploaded, 88L, SOURCE_GALLERY, "desc", - "create", multiple ? 1 : 0, 640, 480, "007")); - mc.moveToFirst(); - return mc; - } - - @NonNull - private Contribution createContribution(boolean multiple, Uri localUri, - String imageUrl, Date dateUploaded, String filename) { - Contribution contribution = new Contribution(localUri, imageUrl, filename, "desc", 222L, - new Date(321L), dateUploaded, "create", "edit", "coords"); - contribution.setState(STATE_COMPLETED); - contribution.setTransferred(333L); - contribution.setSource(SOURCE_CAMERA); - contribution.setLicense("007"); - contribution.setMultiple(multiple); - contribution.setTimestamp(new Date(321L)); - contribution.setWidth(640); - contribution.setHeight(480); // VGA should be enough for anyone, right? - return contribution; - } -} \ No newline at end of file diff --git a/app/src/test/java/fr/free/nrw/commons/modifications/ModifierSequenceDaoTest.java b/app/src/test/java/fr/free/nrw/commons/modifications/ModifierSequenceDaoTest.java deleted file mode 100644 index ef290500d0..0000000000 --- a/app/src/test/java/fr/free/nrw/commons/modifications/ModifierSequenceDaoTest.java +++ /dev/null @@ -1,181 +0,0 @@ -package fr.free.nrw.commons.modifications; - -import android.content.ContentProviderClient; -import android.content.ContentValues; -import android.database.MatrixCursor; -import android.database.sqlite.SQLiteDatabase; -import android.net.Uri; -import android.os.RemoteException; -import android.support.annotation.NonNull; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.InOrder; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; - -import java.util.Arrays; - -import fr.free.nrw.commons.BuildConfig; -import fr.free.nrw.commons.TestCommonsApplication; - -import static fr.free.nrw.commons.modifications.ModificationsContentProvider.BASE_URI; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.eq; -import static org.mockito.Matchers.isA; -import static org.mockito.Matchers.isNull; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -@RunWith(RobolectricTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 21, application = TestCommonsApplication.class) -public class ModifierSequenceDaoTest { - - private static final String EXPECTED_MEDIA_URI = "http://example.com/"; - - @Mock - ContentProviderClient client; - @Mock - SQLiteDatabase database; - @Captor - ArgumentCaptor contentValuesCaptor; - - private ModifierSequenceDao testObject; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - testObject = new ModifierSequenceDao(() -> client); - } - - @Test - public void createFromCursorWithEmptyModifiers() { - MatrixCursor cursor = createCursor(""); - - ModifierSequence seq = testObject.fromCursor(cursor); - - assertEquals(EXPECTED_MEDIA_URI, seq.getMediaUri().toString()); - assertEquals(BASE_URI.buildUpon().appendPath("1").toString(), seq.getContentUri().toString()); - assertTrue(seq.getModifiers().isEmpty()); - } - - @Test - public void createFromCursorWtihCategoryModifier() { - MatrixCursor cursor = createCursor("{\"name\": \"CategoriesModifier\", \"data\": {}}"); - - ModifierSequence seq = testObject.fromCursor(cursor); - - assertEquals(1, seq.getModifiers().size()); - assertTrue(seq.getModifiers().get(0) instanceof CategoryModifier); - } - - @Test - public void createFromCursorWithRemoveModifier() { - MatrixCursor cursor = createCursor("{\"name\": \"TemplateRemoverModifier\", \"data\": {}}"); - - ModifierSequence seq = testObject.fromCursor(cursor); - - assertEquals(1, seq.getModifiers().size()); - assertTrue(seq.getModifiers().get(0) instanceof TemplateRemoveModifier); - } - - @Test - public void deleteSequence() throws Exception { - when(client.delete(isA(Uri.class), isNull(String.class), isNull(String[].class))).thenReturn(1); - ModifierSequence seq = testObject.fromCursor(createCursor("")); - - testObject.delete(seq); - - verify(client).delete(eq(seq.getContentUri()), isNull(String.class), isNull(String[].class)); - } - - @Test(expected = RuntimeException.class) - public void deleteTranslatesRemoteExceptions() throws Exception { - when(client.delete(isA(Uri.class), isNull(String.class), isNull(String[].class))).thenThrow(new RemoteException("")); - ModifierSequence seq = testObject.fromCursor(createCursor("")); - - testObject.delete(seq); - } - - @Test - public void saveExistingSequence() throws Exception { - String modifierJson = "{\"name\":\"CategoriesModifier\",\"data\":{}}"; - String expectedData = "{\"modifiers\":[" + modifierJson + "]}"; - MatrixCursor cursor = createCursor(modifierJson); - - testObject.save(testObject.fromCursor(cursor)); - - verify(client).update(eq(testObject.fromCursor(cursor).getContentUri()), contentValuesCaptor.capture(), isNull(String.class), isNull(String[].class)); - ContentValues cv = contentValuesCaptor.getValue(); - assertEquals(2, cv.size()); - assertEquals(EXPECTED_MEDIA_URI, cv.get(ModifierSequenceDao.Table.COLUMN_MEDIA_URI)); - assertEquals(expectedData, cv.get(ModifierSequenceDao.Table.COLUMN_DATA)); - } - - @Test - public void saveNewSequence() throws Exception { - Uri expectedContentUri = BASE_URI.buildUpon().appendPath("1").build(); - when(client.insert(isA(Uri.class), isA(ContentValues.class))).thenReturn(expectedContentUri); - - ModifierSequence seq = new ModifierSequence(Uri.parse(EXPECTED_MEDIA_URI)); - testObject.save(seq); - - verify(client).insert(eq(ModificationsContentProvider.BASE_URI), contentValuesCaptor.capture()); - ContentValues cv = contentValuesCaptor.getValue(); - assertEquals(2, cv.size()); - assertEquals(EXPECTED_MEDIA_URI, cv.get(ModifierSequenceDao.Table.COLUMN_MEDIA_URI)); - assertEquals("{\"modifiers\":[]}", cv.get(ModifierSequenceDao.Table.COLUMN_DATA)); - assertEquals(expectedContentUri.toString(), seq.getContentUri().toString()); - } - - @Test(expected = RuntimeException.class) - public void saveTranslatesRemoteExceptions() throws Exception { - when(client.insert(isA(Uri.class), isA(ContentValues.class))).thenThrow(new RemoteException("")); - - testObject.save(new ModifierSequence(Uri.parse(EXPECTED_MEDIA_URI))); - } - - @Test - public void createTable() { - ModifierSequenceDao.Table.onCreate(database); - - verify(database).execSQL(ModifierSequenceDao.Table.CREATE_TABLE_STATEMENT); - } - - @Test - public void updateTable() { - ModifierSequenceDao.Table.onUpdate(database, 1, 2); - - InOrder inOrder = inOrder(database); - inOrder.verify(database).execSQL(ModifierSequenceDao.Table.DROP_TABLE_STATEMENT); - inOrder.verify(database).execSQL(ModifierSequenceDao.Table.CREATE_TABLE_STATEMENT); - } - - @Test - public void deleteTable() { - ModifierSequenceDao.Table.onDelete(database); - - InOrder inOrder = inOrder(database); - inOrder.verify(database).execSQL(ModifierSequenceDao.Table.DROP_TABLE_STATEMENT); - inOrder.verify(database).execSQL(ModifierSequenceDao.Table.CREATE_TABLE_STATEMENT); - } - - @NonNull - private MatrixCursor createCursor(String modifierJson) { - MatrixCursor cursor = new MatrixCursor(new String[]{ - ModifierSequenceDao.Table.COLUMN_ID, - ModifierSequenceDao.Table.COLUMN_MEDIA_URI, - ModifierSequenceDao.Table.COLUMN_DATA - }, 1); - cursor.addRow(Arrays.asList("1", EXPECTED_MEDIA_URI, "{\"modifiers\": [" + modifierJson + "]}")); - cursor.moveToFirst(); - return cursor; - } -} \ No newline at end of file diff --git a/app/src/test/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.java b/app/src/test/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.java deleted file mode 100644 index e2c8b82f6f..0000000000 --- a/app/src/test/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.java +++ /dev/null @@ -1,248 +0,0 @@ -package fr.free.nrw.commons.mwapi; - -import android.content.SharedPreferences; -import android.os.Build; -import android.preference.PreferenceManager; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import fr.free.nrw.commons.BuildConfig; -import fr.free.nrw.commons.TestCommonsApplication; -import io.reactivex.observers.TestObserver; -import okhttp3.HttpUrl; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import okhttp3.mockwebserver.RecordedRequest; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -@RunWith(RobolectricTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 21, application = TestCommonsApplication.class) -public class ApacheHttpClientMediaWikiApiTest { - - private ApacheHttpClientMediaWikiApi testObject; - private MockWebServer server; - private SharedPreferences sharedPreferences; - - @Before - public void setUp() throws Exception { - server = new MockWebServer(); - sharedPreferences = PreferenceManager.getDefaultSharedPreferences(RuntimeEnvironment.application); - testObject = new ApacheHttpClientMediaWikiApi(RuntimeEnvironment.application, "http://" + server.getHostName() + ":" + server.getPort() + "/", sharedPreferences); - testObject.setWikiMediaToolforgeUrl("http://" + server.getHostName() + ":" + server.getPort() + "/"); - } - - @After - public void teardown() throws IOException { - server.shutdown(); - } - - @Test - public void authCookiesAreHandled() { - assertEquals("", testObject.getAuthCookie()); - - testObject.setAuthCookie("cookie=chocolate-chip"); - - assertEquals("cookie=chocolate-chip", testObject.getAuthCookie()); - } - - @Test - public void simpleLoginWithWrongPassword() throws Exception { - server.enqueue(new MockResponse().setBody("")); - server.enqueue(new MockResponse().setBody("")); - - String result = testObject.login("foo", "bar"); - - RecordedRequest loginTokenRequest = assertBasicRequestParameters(server, "POST"); - Map body = parseBody(loginTokenRequest.getBody().readUtf8()); - assertEquals("xml", body.get("format")); - assertEquals("query", body.get("action")); - assertEquals("login", body.get("type")); - assertEquals("tokens", body.get("meta")); - - RecordedRequest loginRequest = assertBasicRequestParameters(server, "POST"); - body = parseBody(loginRequest.getBody().readUtf8()); - assertEquals("1", body.get("rememberMe")); - assertEquals("foo", body.get("username")); - assertEquals("bar", body.get("password")); - assertEquals("baz", body.get("logintoken")); - assertEquals("https://commons.wikimedia.org", body.get("loginreturnurl")); - assertEquals("xml", body.get("format")); - - assertEquals("wrongpassword", result); - } - - @Test - public void simpleLogin() throws Exception { - server.enqueue(new MockResponse().setBody("")); - server.enqueue(new MockResponse().setBody("")); - - String result = testObject.login("foo", "bar"); - - RecordedRequest loginTokenRequest = assertBasicRequestParameters(server, "POST"); - Map body = parseBody(loginTokenRequest.getBody().readUtf8()); - assertEquals("xml", body.get("format")); - assertEquals("query", body.get("action")); - assertEquals("login", body.get("type")); - assertEquals("tokens", body.get("meta")); - - RecordedRequest loginRequest = assertBasicRequestParameters(server, "POST"); - body = parseBody(loginRequest.getBody().readUtf8()); - assertEquals("1", body.get("rememberMe")); - assertEquals("foo", body.get("username")); - assertEquals("bar", body.get("password")); - assertEquals("baz", body.get("logintoken")); - assertEquals("https://commons.wikimedia.org", body.get("loginreturnurl")); - assertEquals("xml", body.get("format")); - - assertEquals("PASS", result); - } - - @Test - public void twoFactorLogin() throws Exception { - server.enqueue(new MockResponse().setBody("")); - server.enqueue(new MockResponse().setBody("")); - - String result = testObject.login("foo", "bar", "2fa"); - - RecordedRequest loginTokenRequest = assertBasicRequestParameters(server, "POST"); - Map body = parseBody(loginTokenRequest.getBody().readUtf8()); - assertEquals("xml", body.get("format")); - assertEquals("query", body.get("action")); - assertEquals("login", body.get("type")); - assertEquals("tokens", body.get("meta")); - - RecordedRequest loginRequest = assertBasicRequestParameters(server, "POST"); - body = parseBody(loginRequest.getBody().readUtf8()); - assertEquals("true", body.get("rememberMe")); - assertEquals("foo", body.get("username")); - assertEquals("bar", body.get("password")); - assertEquals("baz", body.get("logintoken")); - assertEquals("true", body.get("logincontinue")); - assertEquals("2fa", body.get("OATHToken")); - assertEquals("xml", body.get("format")); - - assertEquals("PASS", result); - } - - @Test - public void validateLoginForLoggedInUser() throws Exception { - server.enqueue(new MockResponse().setBody("")); - - boolean result = testObject.validateLogin(); - - RecordedRequest loginTokenRequest = assertBasicRequestParameters(server, "GET"); - Map body = parseQueryParams(loginTokenRequest); - assertEquals("xml", body.get("format")); - assertEquals("query", body.get("action")); - assertEquals("userinfo", body.get("meta")); - - assertTrue(result); - } - - @Test - public void validateLoginForLoggedOutUser() throws Exception { - server.enqueue(new MockResponse().setBody("")); - - boolean result = testObject.validateLogin(); - - RecordedRequest loginTokenRequest = assertBasicRequestParameters(server, "GET"); - Map params = parseQueryParams(loginTokenRequest); - assertEquals("xml", params.get("format")); - assertEquals("query", params.get("action")); - assertEquals("userinfo", params.get("meta")); - - assertFalse(result); - } - - @Test - public void editToken() throws Exception { - server.enqueue(new MockResponse().setBody("")); - - String result = testObject.getEditToken(); - - RecordedRequest loginTokenRequest = assertBasicRequestParameters(server, "GET"); - Map params = parseQueryParams(loginTokenRequest); - assertEquals("xml", params.get("format")); - assertEquals("tokens", params.get("action")); - assertEquals("edit", params.get("type")); - - assertEquals("baz", result); - } - - @Test - public void fileExistsWithName_FileNotFound() throws Exception { - server.enqueue(new MockResponse().setBody(" ")); - - boolean result = testObject.fileExistsWithName("foo"); - - RecordedRequest request = assertBasicRequestParameters(server, "GET"); - Map params = parseQueryParams(request); - assertEquals("xml", params.get("format")); - assertEquals("query", params.get("action")); - assertEquals("imageinfo", params.get("prop")); - assertEquals("File:foo", params.get("titles")); - - assertFalse(result); - } - - @Test - public void getUploadCount() throws InterruptedException { - server.enqueue(new MockResponse().setBody("23\n")); - - TestObserver testObserver = testObject.getUploadCount("testUsername").test(); - - RecordedRequest request = server.takeRequest(); - Map params = parseQueryParams(request); - assertEquals("testUsername", params.get("user")); - - assertEquals(1, testObserver.valueCount()); - assertEquals(23, (int)testObserver.values().get(0)); - } - - private RecordedRequest assertBasicRequestParameters(MockWebServer server, String method) throws InterruptedException { - RecordedRequest request = server.takeRequest(); - assertEquals("/", request.getRequestUrl().encodedPath()); - assertEquals(method, request.getMethod()); - assertEquals("Commons/" + BuildConfig.VERSION_NAME + " (https://mediawiki.org/wiki/Apps/Commons) Android/" + Build.VERSION.RELEASE, request.getHeader("User-Agent")); - if ("POST".equals(method)) { - assertEquals("application/x-www-form-urlencoded", request.getHeader("Content-Type")); - } - return request; - } - - private Map parseQueryParams(RecordedRequest request) { - Map result = new HashMap<>(); - HttpUrl url = request.getRequestUrl(); - Set params = url.queryParameterNames(); - for (String name : params) { - result.put(name, url.queryParameter(name)); - } - return result; - } - - private Map parseBody(String body) throws UnsupportedEncodingException { - String[] props = body.split("&"); - Map result = new HashMap<>(); - for (String prop : props) { - String[] pair = prop.split("="); - result.put(pair[0], URLDecoder.decode(pair[1], "utf-8")); - } - return result; - } -} diff --git a/app/src/test/java/fr/free/nrw/commons/utils/StringSortingUtilsTest.java b/app/src/test/java/fr/free/nrw/commons/utils/StringSortingUtilsTest.java deleted file mode 100644 index 6384fb096d..0000000000 --- a/app/src/test/java/fr/free/nrw/commons/utils/StringSortingUtilsTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package fr.free.nrw.commons.utils; - -import org.junit.Assert; -import org.junit.Test; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -public class StringSortingUtilsTest { - - @Test - public void testSortingNumbersBySimilarity() throws Exception { - List actualList = Arrays.asList("1234567", "4567", "12345", "123", "1234"); - List expectedList = Arrays.asList("1234", "12345", "123", "1234567", "4567"); - - Collections.sort(actualList, StringSortingUtils.sortBySimilarity("1234")); - Assert.assertEquals(expectedList, actualList); - } - - @Test - public void testSortingTextBySimilarity() throws Exception { - List actualList = Arrays.asList("The quick brown fox", - "quick brown fox", - "The", - "The quick ", - "The fox", - "brown fox", - "fox"); - List expectedList = Arrays.asList("The", - "The fox", - "The quick ", - "The quick brown fox", - "quick brown fox", - "brown fox", - "fox"); - - Collections.sort(actualList, StringSortingUtils.sortBySimilarity("The")); - Assert.assertEquals(expectedList, actualList); - } -} \ No newline at end of file diff --git a/app/src/test/kotlin/fr/free/nrw/commons/FileUtilsTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/FileUtilsTest.kt new file mode 100644 index 0000000000..8be291d4dc --- /dev/null +++ b/app/src/test/kotlin/fr/free/nrw/commons/FileUtilsTest.kt @@ -0,0 +1,33 @@ +package fr.free.nrw.commons + +import fr.free.nrw.commons.upload.FileUtils +import org.junit.Assert.assertEquals +import org.junit.Test +import java.io.* + +class FileUtilsTest { + @Test + fun copiedFileIsIdenticalToSource() { + val source = File.createTempFile("temp", "") + val dest = File.createTempFile("temp", "") + writeToFile(source, "Hello, World") + + FileUtils.copy(FileInputStream(source), FileOutputStream(dest)) + + assertEquals(getString(source), getString(dest)) + } + + private fun writeToFile(file: File, s: String) { + val buf = BufferedOutputStream(FileOutputStream(file)) + buf.write(s.toByteArray()) + buf.close() + } + + private fun getString(file: File): String { + val bytes = ByteArray(file.length().toInt()) + val buf = BufferedInputStream(FileInputStream(file)) + buf.read(bytes, 0, bytes.size) + buf.close() + return String(bytes) + } +} diff --git a/app/src/test/kotlin/fr/free/nrw/commons/LatLngTests.kt b/app/src/test/kotlin/fr/free/nrw/commons/LatLngTests.kt new file mode 100644 index 0000000000..efafa4e3ab --- /dev/null +++ b/app/src/test/kotlin/fr/free/nrw/commons/LatLngTests.kt @@ -0,0 +1,64 @@ +package fr.free.nrw.commons + +import fr.free.nrw.commons.location.LatLng +import org.junit.Assert.assertEquals +import org.junit.Test + +class LatLngTests { + @Test + fun testZeroZero() { + val place = LatLng(0.0, 0.0, 0f) + assertPrettyCoordinateString("0.0 N, 0.0 E", place) + } + + @Test + fun testAntipode() { + val place = LatLng(0.0, 180.0, 0f) + assertPrettyCoordinateString("0.0 N, 180.0 W", place) + } + + @Test + fun testNorthPole() { + val place = LatLng(90.0, 0.0, 0f) + assertPrettyCoordinateString("90.0 N, 0.0 E", place) + } + + @Test + fun testSouthPole() { + val place = LatLng(-90.0, 0.0, 0f) + assertPrettyCoordinateString("90.0 S, 0.0 E", place) + } + + @Test + fun testLargerNumbers() { + val place = LatLng(120.0, 380.0, 0f) + assertPrettyCoordinateString("90.0 N, 20.0 E", place) + } + + @Test + fun testNegativeNumbers() { + val place = LatLng(-120.0, -30.0, 0f) + assertPrettyCoordinateString("90.0 S, 30.0 W", place) + } + + @Test + fun testTooBigWestValue() { + val place = LatLng(20.0, -190.0, 0f) + assertPrettyCoordinateString("20.0 N, 170.0 E", place) + } + + @Test + fun testRounding() { + val place = LatLng(0.1234567, -0.33333333, 0f) + assertPrettyCoordinateString("0.1235 N, 0.3333 W", place) + } + + @Test + fun testRoundingAgain() { + val place = LatLng(-0.000001, -0.999999, 0f) + assertPrettyCoordinateString("0.0 S, 1.0 W", place) + } + + private fun assertPrettyCoordinateString(expected: String, place: LatLng) = + assertEquals(expected, place.prettyCoordinateString) +} diff --git a/app/src/test/kotlin/fr/free/nrw/commons/LengthUtilsTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/LengthUtilsTest.kt new file mode 100644 index 0000000000..63b0b4d0a2 --- /dev/null +++ b/app/src/test/kotlin/fr/free/nrw/commons/LengthUtilsTest.kt @@ -0,0 +1,46 @@ +package fr.free.nrw.commons + +import fr.free.nrw.commons.location.LatLng +import fr.free.nrw.commons.utils.LengthUtils +import org.junit.Assert.assertEquals +import org.junit.Test + +class LengthUtilsTest { + @Test + fun testZeroDistance() { + val pointA = LatLng(0.0, 0.0, 0f) + val pointB = LatLng(0.0, 0.0, 0f) + assertDistanceBetween("0m", pointA, pointB) + } + + @Test + fun testOneDegreeOnEquator() { + val pointA = LatLng(0.0, 0.0, 0f) + val pointB = LatLng(0.0, 1.0, 0f) + assertDistanceBetween("111.2km", pointA, pointB) + } + + @Test + fun testOneDegreeFortyFiveDegrees() { + val pointA = LatLng(45.0, 0.0, 0f) + val pointB = LatLng(45.0, 1.0, 0f) + assertDistanceBetween("78.6km", pointA, pointB) + } + + @Test + fun testOneDegreeSouthPole() { + val pointA = LatLng(-90.0, 0.0, 0f) + val pointB = LatLng(-90.0, 1.0, 0f) + assertDistanceBetween("0m", pointA, pointB) + } + + @Test + fun testPoleToPole() { + val pointA = LatLng(90.0, 0.0, 0f) + val pointB = LatLng(-90.0, 0.0, 0f) + assertDistanceBetween("20,015.1km", pointA, pointB) + } + + private fun assertDistanceBetween(expected: String, pointA: LatLng, pointB: LatLng) = + assertEquals(expected, LengthUtils.formatDistanceBetween(pointA, pointB)) +} diff --git a/app/src/test/kotlin/fr/free/nrw/commons/MediaTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/MediaTest.kt new file mode 100644 index 0000000000..f75c345684 --- /dev/null +++ b/app/src/test/kotlin/fr/free/nrw/commons/MediaTest.kt @@ -0,0 +1,23 @@ +package fr.free.nrw.commons + +import org.junit.Assert.assertEquals +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config + +@RunWith(RobolectricTestRunner::class) +@Config(constants = BuildConfig::class, sdk = intArrayOf(21), application = TestCommonsApplication::class) +class MediaTest { + @Test + fun displayTitleShouldStripExtension() { + val m = Media("File:Example.jpg") + assertEquals("Example", m.displayTitle) + } + + @Test + fun displayTitleShouldUseSpaceForUnderscore() { + val m = Media("File:Example 1_2.jpg") + assertEquals("Example 1 2", m.displayTitle) + } +} diff --git a/app/src/test/kotlin/fr/free/nrw/commons/NearbyControllerTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/NearbyControllerTest.kt new file mode 100644 index 0000000000..fc0be84d04 --- /dev/null +++ b/app/src/test/kotlin/fr/free/nrw/commons/NearbyControllerTest.kt @@ -0,0 +1,35 @@ +package fr.free.nrw.commons + +import fr.free.nrw.commons.location.LatLng +import fr.free.nrw.commons.nearby.NearbyController.loadAttractionsFromLocationToBaseMarkerOptions +import org.junit.Assert.assertEquals +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.RuntimeEnvironment +import org.robolectric.annotation.Config + +@RunWith(RobolectricTestRunner::class) +@Config(constants = BuildConfig::class, sdk = intArrayOf(21), application = TestCommonsApplication::class) +class NearbyControllerTest { + + @Test + fun testNullAttractions() { + val location = LatLng(0.0, 0.0, 0f) + + val options = loadAttractionsFromLocationToBaseMarkerOptions( + location, null, RuntimeEnvironment.application) + + assertEquals(0, options.size.toLong()) + } + + @Test + fun testEmptyList() { + val location = LatLng(0.0, 0.0, 0f) + + val options = loadAttractionsFromLocationToBaseMarkerOptions( + location, emptyList(), RuntimeEnvironment.application) + + assertEquals(0, options.size.toLong()) + } +} diff --git a/app/src/test/kotlin/fr/free/nrw/commons/PageTitleTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/PageTitleTest.kt new file mode 100644 index 0000000000..28112b196a --- /dev/null +++ b/app/src/test/kotlin/fr/free/nrw/commons/PageTitleTest.kt @@ -0,0 +1,67 @@ +package fr.free.nrw.commons + +import org.junit.Assert.assertEquals +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import java.net.URLEncoder + +@RunWith(RobolectricTestRunner::class) +@Config(constants = BuildConfig::class, sdk = intArrayOf(21), application = TestCommonsApplication::class) +class PageTitleTest { + @Test + fun displayTextShouldNotBeUnderscored() { + val pageTitle = PageTitle("Ex_1 ") + assertEquals("Ex 1", pageTitle.displayText) + } + + @Test + fun moreThanTwoColons() { + val pageTitle = PageTitle("File:sample:a.jpg") + assertEquals("File:Sample:a.jpg", pageTitle.prefixedText) + } + + @Test + fun getTextShouldReturnWithoutNamespace() { + val pageTitle = PageTitle("File:sample.jpg") + assertEquals("Sample.jpg", pageTitle.text) + } + + + @Test + fun capitalizeNameAfterNamespace() { + val pageTitle = PageTitle("File:sample.jpg") + assertEquals("File:Sample.jpg", pageTitle.prefixedText) + } + + @Test + fun prefixedTextShouldBeUnderscored() { + val pageTitle = PageTitle("Ex 1 ") + assertEquals("Ex_1", pageTitle.prefixedText) + } + + @Test + fun getMobileUriForTest() { + val pageTitle = PageTitle("Test") + assertEquals(BuildConfig.MOBILE_HOME_URL + "Test", pageTitle.mobileUri.toString()) + } + + @Test + fun spaceBecomesUnderscoreInUri() { + val pageTitle = PageTitle("File:Ex 1.jpg") + assertEquals(BuildConfig.HOME_URL + "File:Ex_1.jpg", pageTitle.canonicalUri.toString()) + } + + @Test + fun leaveSubpageNamesUncapitalizedInUri() { + val pageTitle = PageTitle("User:Ex/subpage") + assertEquals(BuildConfig.HOME_URL + "User:Ex/subpage", pageTitle.canonicalUri.toString()) + } + + @Test + fun unicodeUri() { + val pageTitle = PageTitle("User:例") + assertEquals(BuildConfig.HOME_URL + "User:" + URLEncoder.encode("例", "utf-8"), pageTitle.canonicalUri.toString()) + } +} diff --git a/app/src/test/kotlin/fr/free/nrw/commons/TestCommonsApplication.kt b/app/src/test/kotlin/fr/free/nrw/commons/TestCommonsApplication.kt new file mode 100644 index 0000000000..73760dd40b --- /dev/null +++ b/app/src/test/kotlin/fr/free/nrw/commons/TestCommonsApplication.kt @@ -0,0 +1,72 @@ +package fr.free.nrw.commons + +import android.content.Context +import android.content.SharedPreferences +import android.support.v4.util.LruCache +import com.nhaarman.mockito_kotlin.mock +import com.squareup.leakcanary.RefWatcher +import fr.free.nrw.commons.auth.AccountUtil +import fr.free.nrw.commons.auth.SessionManager +import fr.free.nrw.commons.caching.CacheController +import fr.free.nrw.commons.data.DBOpenHelper +import fr.free.nrw.commons.di.CommonsApplicationComponent +import fr.free.nrw.commons.di.CommonsApplicationModule +import fr.free.nrw.commons.di.DaggerCommonsApplicationComponent +import fr.free.nrw.commons.location.LocationServiceManager +import fr.free.nrw.commons.mwapi.MediaWikiApi +import fr.free.nrw.commons.nearby.NearbyPlaces +import fr.free.nrw.commons.upload.UploadController + +class TestCommonsApplication : CommonsApplication() { + private var mockApplicationComponent: CommonsApplicationComponent? = null + + override fun onCreate() { + if (mockApplicationComponent == null) { + mockApplicationComponent = DaggerCommonsApplicationComponent.builder() + .appModule(MockCommonsApplicationModule(this)).build() + } + super.onCreate() + } + + // No leakcanary in unit tests. + override fun setupLeakCanary(): RefWatcher = RefWatcher.DISABLED +} + +class MockCommonsApplicationModule(appContext: Context) : CommonsApplicationModule(appContext) { + val accountUtil: AccountUtil = mock() + val appSharedPreferences: SharedPreferences = mock() + val defaultSharedPreferences: SharedPreferences = mock() + val otherSharedPreferences: SharedPreferences = mock() + val uploadController: UploadController = mock() + val mockSessionManager: SessionManager = mock() + val mediaWikiApi: MediaWikiApi = mock() + val locationServiceManager: LocationServiceManager = mock() + val cacheController: CacheController = mock() + val mockDbOpenHelper: DBOpenHelper = mock() + val nearbyPlaces: NearbyPlaces = mock() + val lruCache: LruCache = mock() + + override fun providesAccountUtil(context: Context): AccountUtil = accountUtil + + override fun providesApplicationSharedPreferences(context: Context): SharedPreferences = appSharedPreferences + + override fun providesDefaultSharedPreferences(context: Context): SharedPreferences = defaultSharedPreferences + + override fun providesOtherSharedPreferences(context: Context): SharedPreferences = otherSharedPreferences + + override fun providesUploadController(sessionManager: SessionManager, sharedPreferences: SharedPreferences, context: Context): UploadController = uploadController + + override fun providesSessionManager(context: Context, mediaWikiApi: MediaWikiApi, sharedPreferences: SharedPreferences): SessionManager = mockSessionManager + + override fun provideMediaWikiApi(context: Context, sharedPreferences: SharedPreferences): MediaWikiApi = mediaWikiApi + + override fun provideLocationServiceManager(context: Context): LocationServiceManager = locationServiceManager + + override fun provideCacheController(): CacheController = cacheController + + override fun provideDBOpenHelper(context: Context): DBOpenHelper = mockDbOpenHelper + + override fun provideNearbyPlaces(): NearbyPlaces = nearbyPlaces + + override fun provideLruCache(): LruCache = lruCache +} \ No newline at end of file diff --git a/app/src/test/kotlin/fr/free/nrw/commons/UtilsFixExtensionTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/UtilsFixExtensionTest.kt new file mode 100644 index 0000000000..0082b9d284 --- /dev/null +++ b/app/src/test/kotlin/fr/free/nrw/commons/UtilsFixExtensionTest.kt @@ -0,0 +1,68 @@ +package fr.free.nrw.commons + +import fr.free.nrw.commons.Utils.fixExtension +import org.junit.Assert.assertEquals +import org.junit.Test + +class UtilsFixExtensionTest { + + @Test + fun jpegResultsInJpg() { + assertEquals("SampleFile.jpg", fixExtension("SampleFile.jpeg", "jpeg")) + } + + @Test + fun capitalJpegWithNoHintResultsInJpg() { + assertEquals("SampleFile.jpg", fixExtension("SampleFile.JPEG", null)) + } + + @Test + fun jpegWithBogusHintResultsInJpg() { + assertEquals("SampleFile.jpg", fixExtension("SampleFile.jpeg", null)) + } + + @Test + fun jpegToCapitalJpegResultsInJpg() { + assertEquals("SampleFile.jpg", fixExtension("SampleFile.jpeg", "JPEG")) + } + + @Test + fun jpgToJpegResultsInJpg() { + assertEquals("SampleFile.jpg", fixExtension("SampleFile.jpg", "jpeg")) + } + + @Test + fun jpegToJpgResultsInJpg() { + assertEquals("SampleFile.jpg", fixExtension("SampleFile.jpeg", "jpg")) + } + + @Test + fun jpgRemainsJpg() { + assertEquals("SampleFile.jpg", fixExtension("SampleFile.jpg", "jpg")) + } + + @Test + fun pngRemainsPng() { + assertEquals("SampleFile.png", fixExtension("SampleFile.png", "png")) + } + + @Test + fun jpgHintResultsInJpg() { + assertEquals("SampleFile.jpg", fixExtension("SampleFile", "jpg")) + } + + @Test + fun jpegHintResultsInJpg() { + assertEquals("SampleFile.jpg", fixExtension("SampleFile", "jpeg")) + } + + @Test + fun dotLessJpgToJpgResultsInJpg() { + assertEquals("SAMPLEjpg.jpg", fixExtension("SAMPLEjpg", "jpg")) + } + + @Test + fun inWordJpegToJpgResultsInJpg() { + assertEquals("X.jpeg.SAMPLE.jpg", fixExtension("X.jpeg.SAMPLE", "jpg")) + } +} diff --git a/app/src/test/kotlin/fr/free/nrw/commons/category/CategoryDaoTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/category/CategoryDaoTest.kt new file mode 100644 index 0000000000..b64d3b8aa3 --- /dev/null +++ b/app/src/test/kotlin/fr/free/nrw/commons/category/CategoryDaoTest.kt @@ -0,0 +1,257 @@ +package fr.free.nrw.commons.category + +import android.content.ContentProviderClient +import android.content.ContentValues +import android.database.Cursor +import android.database.MatrixCursor +import android.database.sqlite.SQLiteDatabase +import android.os.RemoteException +import com.nhaarman.mockito_kotlin.* +import fr.free.nrw.commons.BuildConfig +import fr.free.nrw.commons.TestCommonsApplication +import fr.free.nrw.commons.category.CategoryContentProvider.BASE_URI +import fr.free.nrw.commons.category.CategoryContentProvider.uriForId +import fr.free.nrw.commons.category.CategoryDao.Table.* +import org.junit.Assert.* +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import java.util.* + +@RunWith(RobolectricTestRunner::class) +@Config(constants = BuildConfig::class, sdk = [21], application = TestCommonsApplication::class) +class CategoryDaoTest { + + private val columns = arrayOf(COLUMN_ID, COLUMN_NAME, COLUMN_LAST_USED, COLUMN_TIMES_USED) + private val client: ContentProviderClient = mock() + private val database: SQLiteDatabase = mock() + private val captor = argumentCaptor() + private val queryCaptor = argumentCaptor>() + + private lateinit var testObject: CategoryDao + + @Before + fun setUp() { + testObject = CategoryDao { client } + } + + @Test + fun createTable() { + onCreate(database) + verify(database).execSQL(CREATE_TABLE_STATEMENT) + } + + @Test + fun deleteTable() { + onDelete(database) + inOrder(database) { + verify(database).execSQL(DROP_TABLE_STATEMENT) + verify(database).execSQL(CREATE_TABLE_STATEMENT) + } + } + + @Test + fun migrateTableVersionFrom_v1_to_v2() { + onUpdate(database, 1, 2) + // Table didnt exist before v5 + verifyZeroInteractions(database) + } + + @Test + fun migrateTableVersionFrom_v2_to_v3() { + onUpdate(database, 2, 3) + // Table didnt exist before v5 + verifyZeroInteractions(database) + } + + @Test + fun migrateTableVersionFrom_v3_to_v4() { + onUpdate(database, 3, 4) + // Table didnt exist before v5 + verifyZeroInteractions(database) + } + + @Test + fun migrateTableVersionFrom_v4_to_v5() { + onUpdate(database, 4, 5) + verify(database).execSQL(CREATE_TABLE_STATEMENT) + } + + @Test + fun migrateTableVersionFrom_v5_to_v6() { + onUpdate(database, 5, 6) + // Table didnt change in version 6 + verifyZeroInteractions(database) + } + + @Test + fun createFromCursor() { + createCursor(1).let { cursor -> + cursor.moveToFirst() + testObject.fromCursor(cursor).let { + assertEquals(uriForId(1), it.contentUri) + assertEquals("foo", it.name) + assertEquals(123, it.lastUsed.time) + assertEquals(2, it.timesUsed) + } + } + } + + @Test + fun saveExistingCategory() { + createCursor(1).let { + val category = testObject.fromCursor(it.apply { moveToFirst() }) + + testObject.save(category) + + verify(client).update(eq(category.contentUri), captor.capture(), isNull(), isNull()) + captor.firstValue.let { cv -> + assertEquals(3, cv.size()) + assertEquals(category.name, cv.getAsString(COLUMN_NAME)) + assertEquals(category.lastUsed.time, cv.getAsLong(COLUMN_LAST_USED)) + assertEquals(category.timesUsed, cv.getAsInteger(COLUMN_TIMES_USED)) + } + } + } + + @Test + fun saveNewCategory() { + val contentUri = CategoryContentProvider.uriForId(111) + whenever(client.insert(isA(), isA())).thenReturn(contentUri) + val category = Category(null, "foo", Date(234L), 1) + + testObject.save(category) + + verify(client).insert(eq(BASE_URI), captor.capture()) + captor.firstValue.let { cv -> + assertEquals(3, cv.size()) + assertEquals(category.name, cv.getAsString(COLUMN_NAME)) + assertEquals(category.lastUsed.time, cv.getAsLong(COLUMN_LAST_USED)) + assertEquals(category.timesUsed, cv.getAsInteger(COLUMN_TIMES_USED)) + assertEquals(contentUri, category.contentUri) + } + } + + @Test(expected = RuntimeException::class) + fun testSaveTranslatesRemoteExceptions() { + whenever(client.insert(isA(), isA())).thenThrow(RemoteException("")) + testObject.save(Category()) + } + + @Test + fun whenTheresNoDataFindReturnsNull_nullCursor() { + whenever(client.query(any(), any(), any(), any(), any())).thenReturn(null) + assertNull(testObject.find("foo")) + } + + @Test + fun whenTheresNoDataFindReturnsNull_emptyCursor() { + whenever(client.query(any(), any(), any(), any(), any())).thenReturn(createCursor(0)) + assertNull(testObject.find("foo")) + } + + @Test + fun cursorsAreClosedAfterUse() { + val mockCursor: Cursor = mock() + whenever(client.query(any(), any(), any(), any(), anyOrNull())).thenReturn(mockCursor) + whenever(mockCursor.moveToFirst()).thenReturn(false) + + testObject.find("foo") + + verify(mockCursor).close() + } + + @Test + fun findCategory() { + whenever(client.query(any(), any(), any(), any(), anyOrNull())).thenReturn(createCursor(1)) + + val category = testObject.find("foo") + assertNotNull(category) + + assertEquals(uriForId(1), category?.contentUri) + assertEquals("foo", category?.name) + assertEquals(123L, category?.lastUsed?.time) + assertEquals(2, category?.timesUsed) + + verify(client).query( + eq(BASE_URI), + eq(ALL_FIELDS), + eq("$COLUMN_NAME=?"), + queryCaptor.capture(), + isNull() + ) + assertEquals("foo", queryCaptor.firstValue[0]) + } + + @Test(expected = RuntimeException::class) + fun findCategoryTranslatesExceptions() { + whenever(client.query(any(), any(), any(), any(), anyOrNull())).thenThrow(RemoteException("")) + testObject.find("foo") + } + + @Test(expected = RuntimeException::class) + fun recentCategoriesTranslatesExceptions() { + whenever(client.query(any(), any(), anyOrNull(), any(), any())).thenThrow(RemoteException("")) + testObject.recentCategories(1) + } + + @Test + fun recentCategoriesReturnsEmptyList_nullCursor() { + whenever(client.query(any(), any(), anyOrNull(), any(), any())).thenReturn(null) + assertTrue(testObject.recentCategories(1).isEmpty()) + } + + @Test + fun recentCategoriesReturnsEmptyList_emptyCursor() { + whenever(client.query(any(), any(), any(), any(), any())).thenReturn(createCursor(0)) + assertTrue(testObject.recentCategories(1).isEmpty()) + } + + @Test + fun cursorsAreClosedAfterRecentCategoriesQuery() { + val mockCursor: Cursor = mock() + whenever(client.query(any(), any(), anyOrNull(), any(), any())).thenReturn(mockCursor) + whenever(mockCursor.moveToFirst()).thenReturn(false) + + testObject.recentCategories(1) + + verify(mockCursor).close() + } + + @Test + fun recentCategoriesReturnsLessThanLimit() { + whenever(client.query(any(), any(), anyOrNull(), any(), any())).thenReturn(createCursor(1)) + + val result = testObject.recentCategories(10) + + assertEquals(1, result.size) + assertEquals("foo", result[0]) + + verify(client).query( + eq(BASE_URI), + eq(ALL_FIELDS), + isNull(), + queryCaptor.capture(), + eq("$COLUMN_LAST_USED DESC") + ) + assertEquals(0, queryCaptor.firstValue.size) + } + + @Test + fun recentCategoriesHonorsLimit() { + whenever(client.query(any(), any(), anyOrNull(), any(), any())).thenReturn(createCursor(10)) + + val result = testObject.recentCategories(5) + + assertEquals(5, result.size) + } + + private fun createCursor(rowCount: Int) = MatrixCursor(columns, rowCount).apply { + for (i in 0 until rowCount) { + addRow(listOf("1", "foo", "123", "2")) + } + } + +} \ No newline at end of file diff --git a/app/src/test/kotlin/fr/free/nrw/commons/contributions/ContributionDaoTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/contributions/ContributionDaoTest.kt new file mode 100644 index 0000000000..762e0bb855 --- /dev/null +++ b/app/src/test/kotlin/fr/free/nrw/commons/contributions/ContributionDaoTest.kt @@ -0,0 +1,335 @@ +package fr.free.nrw.commons.contributions + +import android.content.ContentProviderClient +import android.content.ContentValues +import android.database.MatrixCursor +import android.database.sqlite.SQLiteDatabase +import android.net.Uri +import android.os.RemoteException +import com.nhaarman.mockito_kotlin.* +import fr.free.nrw.commons.BuildConfig +import fr.free.nrw.commons.TestCommonsApplication +import fr.free.nrw.commons.Utils +import fr.free.nrw.commons.contributions.Contribution.* +import fr.free.nrw.commons.contributions.ContributionDao.Table +import fr.free.nrw.commons.contributions.ContributionsContentProvider.BASE_URI +import fr.free.nrw.commons.contributions.ContributionsContentProvider.uriForId +import org.junit.Assert.* +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import java.util.* + +@RunWith(RobolectricTestRunner::class) +@Config(constants = BuildConfig::class, sdk = [21], application = TestCommonsApplication::class) +class ContributionDaoTest { + private val localUri = "http://example.com/" + private val client: ContentProviderClient = mock() + private val database: SQLiteDatabase = mock() + private val captor = argumentCaptor() + + private lateinit var contentUri: Uri + private lateinit var testObject: ContributionDao + + @Before + fun setUp() { + contentUri = uriForId(111) + testObject = ContributionDao { client } + } + + @Test + fun createTable() { + Table.onCreate(database) + verify(database).execSQL(Table.CREATE_TABLE_STATEMENT) + } + + @Test + fun deleteTable() { + Table.onDelete(database) + + inOrder(database) { + verify(database).execSQL(Table.DROP_TABLE_STATEMENT) + verify(database).execSQL(Table.CREATE_TABLE_STATEMENT) + } + } + + @Test + fun upgradeDatabase_v1_to_v2() { + Table.onUpdate(database, 1, 2) + + inOrder(database) { + verify(database).execSQL(Table.ADD_DESCRIPTION_FIELD) + verify(database).execSQL(Table.ADD_CREATOR_FIELD) + } + } + + @Test + fun upgradeDatabase_v2_to_v3() { + Table.onUpdate(database, 2, 3) + + inOrder(database) { + verify(database).execSQL(Table.ADD_MULTIPLE_FIELD) + verify(database).execSQL(Table.SET_DEFAULT_MULTIPLE) + } + } + + @Test + fun upgradeDatabase_v3_to_v4() { + Table.onUpdate(database, 3, 4) + + // No changes + verifyZeroInteractions(database) + } + + @Test + fun upgradeDatabase_v4_to_v5() { + Table.onUpdate(database, 4, 5) + + // No changes + verifyZeroInteractions(database) + } + + @Test + fun upgradeDatabase_v5_to_v6() { + Table.onUpdate(database, 5, 6) + + inOrder(database) { + verify(database).execSQL(Table.ADD_WIDTH_FIELD) + verify(database).execSQL(Table.SET_DEFAULT_WIDTH) + verify(database).execSQL(Table.ADD_HEIGHT_FIELD) + verify(database).execSQL(Table.SET_DEFAULT_HEIGHT) + verify(database).execSQL(Table.ADD_LICENSE_FIELD) + verify(database).execSQL(Table.SET_DEFAULT_LICENSE) + } + } + + @Test + fun saveNewContribution_nonNullFields() { + whenever(client.insert(isA(), isA())).thenReturn(contentUri) + val contribution = createContribution(true, null, null, null, null) + + testObject.save(contribution) + + assertEquals(contentUri, contribution.contentUri) + verify(client).insert(eq(BASE_URI), captor.capture()) + captor.firstValue.let { + // Long fields + assertEquals(222L, it.getAsLong(Table.COLUMN_LENGTH)) + assertEquals(321L, it.getAsLong(Table.COLUMN_TIMESTAMP)) + assertEquals(333L, it.getAsLong(Table.COLUMN_TRANSFERRED)) + + // Integer fields + assertEquals(STATE_COMPLETED, it.getAsInteger(Table.COLUMN_STATE)) + assertEquals(640, it.getAsInteger(Table.COLUMN_WIDTH)) + assertEquals(480, it.getAsInteger(Table.COLUMN_HEIGHT)) + + // String fields + assertEquals(SOURCE_CAMERA, it.getAsString(Table.COLUMN_SOURCE)) + assertEquals("desc", it.getAsString(Table.COLUMN_DESCRIPTION)) + assertEquals("create", it.getAsString(Table.COLUMN_CREATOR)) + assertEquals("007", it.getAsString(Table.COLUMN_LICENSE)) + } + } + + @Test + fun saveNewContribution_nullableFieldsAreNull() { + whenever(client.insert(isA(), isA())).thenReturn(contentUri) + val contribution = createContribution(true, null, null, null, null) + + testObject.save(contribution) + + assertEquals(contentUri, contribution.contentUri) + verify(client).insert(eq(BASE_URI), captor.capture()) + captor.firstValue.let { + // Nullable fields are absent if null + assertFalse(it.containsKey(Table.COLUMN_LOCAL_URI)) + assertFalse(it.containsKey(Table.COLUMN_IMAGE_URL)) + assertFalse(it.containsKey(Table.COLUMN_UPLOADED)) + } + } + + @Test + fun saveNewContribution_nullableImageUrlUsesFileAsBackup() { + whenever(client.insert(isA(), isA())).thenReturn(contentUri) + val contribution = createContribution(true, null, null, null, "file") + + testObject.save(contribution) + + assertEquals(contentUri, contribution.contentUri) + verify(client).insert(eq(BASE_URI), captor.capture()) + captor.firstValue.let { + // Nullable fields are absent if null + assertFalse(it.containsKey(Table.COLUMN_LOCAL_URI)) + assertFalse(it.containsKey(Table.COLUMN_UPLOADED)) + assertEquals(Utils.makeThumbBaseUrl("file"), it.getAsString(Table.COLUMN_IMAGE_URL)) + } + } + + @Test + fun saveNewContribution_nullableFieldsAreNonNull() { + whenever(client.insert(isA(), isA())).thenReturn(contentUri) + val contribution = createContribution(true, Uri.parse(localUri), + "image", Date(456L), null) + + testObject.save(contribution) + + assertEquals(contentUri, contribution.contentUri) + verify(client).insert(eq(BASE_URI), captor.capture()) + captor.firstValue.let { + assertEquals(localUri, it.getAsString(Table.COLUMN_LOCAL_URI)) + assertEquals("image", it.getAsString(Table.COLUMN_IMAGE_URL)) + assertEquals(456L, it.getAsLong(Table.COLUMN_UPLOADED)) + } + } + + @Test + fun saveNewContribution_booleanEncodesTrue() { + whenever(client.insert(isA(), isA())).thenReturn(contentUri) + val contribution = createContribution(true, null, null, null, null) + + testObject.save(contribution) + + assertEquals(contentUri, contribution.contentUri) + verify(client).insert(eq(BASE_URI), captor.capture()) + + // Boolean true --> 1 for ths encoding scheme + assertEquals("Boolean true should be encoded as 1", 1, + captor.firstValue.getAsInteger(Table.COLUMN_MULTIPLE)) + } + + @Test + fun saveNewContribution_booleanEncodesFalse() { + whenever(client.insert(isA(), isA())).thenReturn(contentUri) + val contribution = createContribution(false, null, null, null, null) + + testObject.save(contribution) + + assertEquals(contentUri, contribution.contentUri) + verify(client).insert(eq(BASE_URI), captor.capture()) + + // Boolean true --> 1 for ths encoding scheme + assertEquals("Boolean false should be encoded as 0", 0, + captor.firstValue.getAsInteger(Table.COLUMN_MULTIPLE)) + } + + @Test + fun saveExistingContribution() { + val contribution = createContribution(false, null, null, null, null) + contribution.contentUri = contentUri + + testObject.save(contribution) + + verify(client).update(eq(contentUri), isA(), isNull(), isNull()) + } + + @Test(expected = RuntimeException::class) + fun saveTranslatesExceptions() { + whenever(client.insert(isA(), isA())).thenThrow(RemoteException("")) + + testObject.save(createContribution(false, null, null, null, null)) + } + + @Test(expected = RuntimeException::class) + fun deleteTranslatesExceptions() { + whenever(client.delete(anyOrNull(), anyOrNull(), anyOrNull())).thenThrow(RemoteException("")) + + val contribution = createContribution(false, null, null, null, null) + contribution.contentUri = contentUri + testObject.delete(contribution) + } + + @Test(expected = RuntimeException::class) + fun exceptionThrownWhenAttemptingToDeleteUnsavedContribution() { + testObject.delete(createContribution(false, null, null, null, null)) + } + + @Test + fun deleteExistingContribution() { + val contribution = createContribution(false, null, null, null, null) + contribution.contentUri = contentUri + + testObject.delete(contribution) + + verify(client).delete(eq(contentUri), isNull(), isNull()) + } + + @Test + fun createFromCursor() { + val created = 321L + val uploaded = 456L + createCursor(created, uploaded, false, localUri).let { mc -> + testObject.fromCursor(mc).let { + assertEquals(uriForId(111), it.contentUri) + assertEquals("file", it.filename) + assertEquals(localUri, it.localUri.toString()) + assertEquals("image", it.imageUrl) + assertEquals(created, it.timestamp.time) + assertEquals(created, it.dateCreated.time) + assertEquals(STATE_QUEUED, it.state) + assertEquals(222L, it.dataLength) + assertEquals(uploaded, it.dateUploaded?.time) + assertEquals(88L, it.transferred) + assertEquals(SOURCE_GALLERY, it.source) + assertEquals("desc", it.description) + assertEquals("create", it.creator) + assertEquals(640, it.width) + assertEquals(480, it.height) + assertEquals("007", it.license) + } + } + } + + @Test + fun createFromCursor_nullableTimestamps() { + createCursor(0L, 0L, false, localUri).let { mc -> + testObject.fromCursor(mc).let { + assertNull(it.timestamp) + assertNull(it.dateCreated) + assertNull(it.dateUploaded) + } + } + } + + @Test + fun createFromCursor_nullableLocalUri() { + createCursor(0L, 0L, false, "").let { mc -> + testObject.fromCursor(mc).let { + assertNull(it.localUri) + assertNull(it.dateCreated) + assertNull(it.dateUploaded) + } + } + } + + @Test + fun createFromCursor_booleanEncoding() { + val mcFalse = createCursor(0L, 0L, false, localUri) + assertFalse(testObject.fromCursor(mcFalse).multiple) + + val mcHammer = createCursor(0L, 0L, true, localUri) + assertTrue(testObject.fromCursor(mcHammer).multiple) + } + + private fun createCursor(created: Long, uploaded: Long, multiple: Boolean, localUri: String) = + MatrixCursor(Table.ALL_FIELDS, 1).apply { + addRow(listOf("111", "file", localUri, "image", + created, STATE_QUEUED, 222L, uploaded, 88L, SOURCE_GALLERY, "desc", + "create", if (multiple) 1 else 0, 640, 480, "007")) + moveToFirst() + } + + private fun createContribution(isMultiple: Boolean, localUri: Uri?, imageUrl: String?, dateUploaded: Date?, filename: String?) = + Contribution(localUri, imageUrl, filename, "desc", 222L, Date(321L), dateUploaded, + "create", "edit", "coords").apply { + state = STATE_COMPLETED + transferred = 333L + source = SOURCE_CAMERA + license = "007" + multiple = isMultiple + timestamp = Date(321L) + width = 640 + height = 480 // VGA should be enough for anyone, right? + } +} \ No newline at end of file diff --git a/app/src/test/kotlin/fr/free/nrw/commons/modifications/ModifierSequenceDaoTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/modifications/ModifierSequenceDaoTest.kt new file mode 100644 index 0000000000..bf0ddf7728 --- /dev/null +++ b/app/src/test/kotlin/fr/free/nrw/commons/modifications/ModifierSequenceDaoTest.kt @@ -0,0 +1,156 @@ +package fr.free.nrw.commons.modifications + +import android.content.ContentProviderClient +import android.content.ContentValues +import android.database.MatrixCursor +import android.database.sqlite.SQLiteDatabase +import android.net.Uri +import android.os.RemoteException +import com.nhaarman.mockito_kotlin.* +import fr.free.nrw.commons.BuildConfig +import fr.free.nrw.commons.TestCommonsApplication +import fr.free.nrw.commons.modifications.ModificationsContentProvider.BASE_URI +import fr.free.nrw.commons.modifications.ModifierSequenceDao.Table.* +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config + +@RunWith(RobolectricTestRunner::class) +@Config(constants = BuildConfig::class, sdk = [21], application = TestCommonsApplication::class) +class ModifierSequenceDaoTest { + + private val mediaUrl = "http://example.com/" + private val columns = arrayOf(COLUMN_ID, COLUMN_MEDIA_URI, COLUMN_DATA) + private val client: ContentProviderClient = mock() + private val database: SQLiteDatabase = mock() + private val contentValuesCaptor = argumentCaptor() + + private lateinit var testObject: ModifierSequenceDao + + @Before + fun setUp() { + testObject = ModifierSequenceDao { client } + } + + @Test + fun createFromCursorWithEmptyModifiers() { + testObject.fromCursor(createCursor("")).let { + assertEquals(mediaUrl, it.mediaUri.toString()) + assertEquals(BASE_URI.buildUpon().appendPath("1").toString(), it.contentUri.toString()) + assertTrue(it.modifiers.isEmpty()) + } + } + + @Test + fun createFromCursorWtihCategoryModifier() { + val cursor = createCursor("{\"name\": \"CategoriesModifier\", \"data\": {}}") + + val seq = testObject.fromCursor(cursor) + + assertEquals(1, seq.modifiers.size) + assertTrue(seq.modifiers[0] is CategoryModifier) + } + + @Test + fun createFromCursorWithRemoveModifier() { + val cursor = createCursor("{\"name\": \"TemplateRemoverModifier\", \"data\": {}}") + + val seq = testObject.fromCursor(cursor) + + assertEquals(1, seq.modifiers.size) + assertTrue(seq.modifiers[0] is TemplateRemoveModifier) + } + + @Test + fun deleteSequence() { + whenever(client.delete(isA(), isNull(), isNull())).thenReturn(1) + val seq = testObject.fromCursor(createCursor("")) + + testObject.delete(seq) + + verify(client).delete(eq(seq.contentUri), isNull(), isNull()) + } + + @Test(expected = RuntimeException::class) + fun deleteTranslatesRemoteExceptions() { + whenever(client.delete(isA(), isNull(), isNull())).thenThrow(RemoteException("")) + val seq = testObject.fromCursor(createCursor("")) + + testObject.delete(seq) + } + + @Test + fun saveExistingSequence() { + val modifierJson = "{\"name\":\"CategoriesModifier\",\"data\":{}}" + val expectedData = "{\"modifiers\":[$modifierJson]}" + val cursor = createCursor(modifierJson) + val seq = testObject.fromCursor(cursor) + + testObject.save(seq) + + verify(client).update(eq(seq.contentUri), contentValuesCaptor.capture(), isNull(), isNull()) + contentValuesCaptor.firstValue.let { + assertEquals(2, it.size()) + assertEquals(mediaUrl, it.get(COLUMN_MEDIA_URI)) + assertEquals(expectedData, it.get(COLUMN_DATA)) + } + } + + @Test + fun saveNewSequence() { + val expectedContentUri = BASE_URI.buildUpon().appendPath("1").build() + whenever(client.insert(isA(), isA())).thenReturn(expectedContentUri) + val seq = ModifierSequence(Uri.parse(mediaUrl)) + + testObject.save(seq) + + assertEquals(expectedContentUri.toString(), seq.contentUri.toString()) + verify(client).insert(eq(ModificationsContentProvider.BASE_URI), contentValuesCaptor.capture()) + contentValuesCaptor.firstValue.let { + assertEquals(2, it.size()) + assertEquals(mediaUrl, it.get(COLUMN_MEDIA_URI)) + assertEquals("{\"modifiers\":[]}", it.get(COLUMN_DATA)) + } + } + + @Test(expected = RuntimeException::class) + fun saveTranslatesRemoteExceptions() { + whenever(client.insert(isA(), isA())).thenThrow(RemoteException("")) + testObject.save(ModifierSequence(Uri.parse(mediaUrl))) + } + + @Test + fun createTable() { + onCreate(database) + verify(database).execSQL(CREATE_TABLE_STATEMENT) + } + + @Test + fun updateTable() { + onUpdate(database, 1, 2) + + inOrder(database) { + verify(database).execSQL(DROP_TABLE_STATEMENT) + verify(database).execSQL(CREATE_TABLE_STATEMENT) + } + } + + @Test + fun deleteTable() { + onDelete(database) + + inOrder(database) { + verify(database).execSQL(DROP_TABLE_STATEMENT) + verify(database).execSQL(CREATE_TABLE_STATEMENT) + } + } + + private fun createCursor(modifierJson: String) = MatrixCursor(columns, 1).apply { + addRow(listOf("1", mediaUrl, "{\"modifiers\": [$modifierJson]}")) + moveToFirst() + } +} \ No newline at end of file diff --git a/app/src/test/kotlin/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.kt new file mode 100644 index 0000000000..c51d354c27 --- /dev/null +++ b/app/src/test/kotlin/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.kt @@ -0,0 +1,246 @@ +package fr.free.nrw.commons.mwapi + +import android.content.SharedPreferences +import android.os.Build +import android.preference.PreferenceManager +import fr.free.nrw.commons.BuildConfig +import fr.free.nrw.commons.TestCommonsApplication +import okhttp3.mockwebserver.MockResponse +import okhttp3.mockwebserver.MockWebServer +import okhttp3.mockwebserver.RecordedRequest +import org.junit.After +import org.junit.Assert.* +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.RuntimeEnvironment +import org.robolectric.annotation.Config +import java.net.URLDecoder +import java.util.* + +@RunWith(RobolectricTestRunner::class) +@Config(constants = BuildConfig::class, sdk = intArrayOf(21), application = TestCommonsApplication::class) +class ApacheHttpClientMediaWikiApiTest { + + private lateinit var testObject: ApacheHttpClientMediaWikiApi + private lateinit var server: MockWebServer + private lateinit var sharedPreferences: SharedPreferences + + @Before + fun setUp() { + server = MockWebServer() + sharedPreferences = PreferenceManager.getDefaultSharedPreferences(RuntimeEnvironment.application) + testObject = ApacheHttpClientMediaWikiApi(RuntimeEnvironment.application, "http://" + server.hostName + ":" + server.port + "/", sharedPreferences) + testObject.setWikiMediaToolforgeUrl("http://" + server.hostName + ":" + server.port + "/") + } + + @After + fun teardown() { + server.shutdown() + } + + @Test + fun authCookiesAreHandled() { + assertEquals("", testObject.authCookie) + + testObject.authCookie = "cookie=chocolate-chip" + + assertEquals("cookie=chocolate-chip", testObject.authCookie) + } + + @Test + fun simpleLoginWithWrongPassword() { + server.enqueue(MockResponse().setBody("")) + server.enqueue(MockResponse().setBody("")) + + val result = testObject.login("foo", "bar") + + assertBasicRequestParameters(server, "POST").let { loginTokenRequest -> + parseBody(loginTokenRequest.body.readUtf8()).let { body -> + assertEquals("xml", body["format"]) + assertEquals("query", body["action"]) + assertEquals("login", body["type"]) + assertEquals("tokens", body["meta"]) + } + } + + assertBasicRequestParameters(server, "POST").let { loginRequest -> + parseBody(loginRequest.body.readUtf8()).let { body -> + assertEquals("1", body["rememberMe"]) + assertEquals("foo", body["username"]) + assertEquals("bar", body["password"]) + assertEquals("baz", body["logintoken"]) + assertEquals("https://commons.wikimedia.org", body["loginreturnurl"]) + assertEquals("xml", body["format"]) + } + } + + assertEquals("wrongpassword", result) + } + + @Test + fun simpleLogin() { + server.enqueue(MockResponse().setBody("")) + server.enqueue(MockResponse().setBody("")) + + val result = testObject.login("foo", "bar") + + assertBasicRequestParameters(server, "POST").let { loginTokenRequest -> + parseBody(loginTokenRequest.body.readUtf8()).let { body -> + assertEquals("xml", body["format"]) + assertEquals("query", body["action"]) + assertEquals("login", body["type"]) + assertEquals("tokens", body["meta"]) + } + } + + assertBasicRequestParameters(server, "POST").let { loginRequest -> + parseBody(loginRequest.body.readUtf8()).let { body -> + assertEquals("1", body["rememberMe"]) + assertEquals("foo", body["username"]) + assertEquals("bar", body["password"]) + assertEquals("baz", body["logintoken"]) + assertEquals("https://commons.wikimedia.org", body["loginreturnurl"]) + assertEquals("xml", body["format"]) + } + } + + assertEquals("PASS", result) + } + + @Test + fun twoFactorLogin() { + server.enqueue(MockResponse().setBody("")) + server.enqueue(MockResponse().setBody("")) + + val result = testObject.login("foo", "bar", "2fa") + + assertBasicRequestParameters(server, "POST").let { loginTokenRequest -> + parseBody(loginTokenRequest.body.readUtf8()).let { body -> + assertEquals("xml", body["format"]) + assertEquals("query", body["action"]) + assertEquals("login", body["type"]) + assertEquals("tokens", body["meta"]) + } + } + + assertBasicRequestParameters(server, "POST").let { loginRequest -> + parseBody(loginRequest.body.readUtf8()).let { body -> + assertEquals("true", body["rememberMe"]) + assertEquals("foo", body["username"]) + assertEquals("bar", body["password"]) + assertEquals("baz", body["logintoken"]) + assertEquals("true", body["logincontinue"]) + assertEquals("2fa", body["OATHToken"]) + assertEquals("xml", body["format"]) + } + } + + assertEquals("PASS", result) + } + + @Test + fun validateLoginForLoggedInUser() { + server.enqueue(MockResponse().setBody("")) + + val result = testObject.validateLogin() + + assertBasicRequestParameters(server, "GET").let { loginTokenRequest -> + parseQueryParams(loginTokenRequest).let { body -> + assertEquals("xml", body["format"]) + assertEquals("query", body["action"]) + assertEquals("userinfo", body["meta"]) + } + } + + assertTrue(result) + } + + @Test + fun validateLoginForLoggedOutUser() { + server.enqueue(MockResponse().setBody("")) + + val result = testObject.validateLogin() + + assertBasicRequestParameters(server, "GET").let { loginTokenRequest -> + parseQueryParams(loginTokenRequest).let { params -> + assertEquals("xml", params["format"]) + assertEquals("query", params["action"]) + assertEquals("userinfo", params["meta"]) + } + } + + assertFalse(result) + } + + @Test + fun editToken() { + server.enqueue(MockResponse().setBody("")) + + val result = testObject.editToken + + assertBasicRequestParameters(server, "GET").let { loginTokenRequest -> + parseQueryParams(loginTokenRequest).let { params -> + assertEquals("xml", params["format"]) + assertEquals("tokens", params["action"]) + assertEquals("edit", params["type"]) + } + } + + assertEquals("baz", result) + } + + @Test + fun fileExistsWithName_FileNotFound() { + server.enqueue(MockResponse().setBody(" ")) + + val result = testObject.fileExistsWithName("foo") + + assertBasicRequestParameters(server, "GET").let { request -> + parseQueryParams(request).let { params -> + assertEquals("xml", params["format"]) + assertEquals("query", params["action"]) + assertEquals("imageinfo", params["prop"]) + assertEquals("File:foo", params["titles"]) + } + } + + assertFalse(result) + } + + @Test + fun getUploadCount() { + server.enqueue(MockResponse().setBody("23\n")) + + val testObserver = testObject.getUploadCount("testUsername").test() + + assertEquals("testUsername", parseQueryParams(server.takeRequest())["user"]) + assertEquals(1, testObserver.valueCount()) + assertEquals(23, testObserver.values()[0]) + } + + private fun assertBasicRequestParameters(server: MockWebServer, method: String): RecordedRequest = server.takeRequest().let { + assertEquals("/", it.requestUrl.encodedPath()) + assertEquals(method, it.method) + assertEquals("Commons/${BuildConfig.VERSION_NAME} (https://mediawiki.org/wiki/Apps/Commons) Android/${Build.VERSION.RELEASE}", + it.getHeader("User-Agent")) + if ("POST" == method) { + assertEquals("application/x-www-form-urlencoded", it.getHeader("Content-Type")) + } + return it + } + + private fun parseQueryParams(request: RecordedRequest) = HashMap().apply { + request.requestUrl.let { + it.queryParameterNames().forEach { name -> put(name, it.queryParameter(name)) } + } + } + + private fun parseBody(body: String): Map = HashMap().apply { + body.split("&".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray().forEach { prop -> + val pair = prop.split("=".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + put(pair[0], URLDecoder.decode(pair[1], "utf-8")) + } + } +} diff --git a/app/src/test/kotlin/fr/free/nrw/commons/utils/StringSortingUtilsTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/utils/StringSortingUtilsTest.kt new file mode 100644 index 0000000000..83e2f7169d --- /dev/null +++ b/app/src/test/kotlin/fr/free/nrw/commons/utils/StringSortingUtilsTest.kt @@ -0,0 +1,41 @@ +package fr.free.nrw.commons.utils + +import fr.free.nrw.commons.utils.StringSortingUtils.sortBySimilarity +import org.junit.Assert.assertEquals +import org.junit.Test +import java.util.Collections.sort + +class StringSortingUtilsTest { + + @Test + fun testSortingNumbersBySimilarity() { + val actualList = listOf("1234567", "4567", "12345", "123", "1234") + val expectedList = listOf("1234", "12345", "123", "1234567", "4567") + + sort(actualList, sortBySimilarity("1234")) + + assertEquals(expectedList, actualList) + } + + @Test + fun testSortingTextBySimilarity() { + val actualList = listOf("The quick brown fox", + "quick brown fox", + "The", + "The quick ", + "The fox", + "brown fox", + "fox") + val expectedList = listOf("The", + "The fox", + "The quick ", + "The quick brown fox", + "quick brown fox", + "brown fox", + "fox") + + sort(actualList, sortBySimilarity("The")) + + assertEquals(expectedList, actualList) + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index b0e8b67186..42dfeec754 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.1.51' + ext.kotlin_version = '1.2.31' repositories { jcenter() mavenCentral()