Migrate API module instrumented tests into simple unit tests

This commit is contained in:
Shinokuni 2021-07-19 17:30:10 +02:00
parent 3c752b777a
commit 7a51364f48
8 changed files with 24 additions and 46 deletions

View File

@ -1,8 +1,5 @@
package com.readrops.api.opml package com.readrops.api.opml
import android.content.Context
import android.net.Uri
import android.util.Log
import com.readrops.api.opml.model.Body import com.readrops.api.opml.model.Body
import com.readrops.api.opml.model.Head import com.readrops.api.opml.model.Head
import com.readrops.api.opml.model.OPML import com.readrops.api.opml.model.OPML
@ -12,7 +9,6 @@ import com.readrops.db.entities.Feed
import com.readrops.db.entities.Folder import com.readrops.db.entities.Folder
import io.reactivex.Completable import io.reactivex.Completable
import io.reactivex.Single import io.reactivex.Single
import io.reactivex.SingleOnSubscribe
import org.simpleframework.xml.Serializer import org.simpleframework.xml.Serializer
import org.simpleframework.xml.core.Persister import org.simpleframework.xml.core.Persister
import java.io.InputStream import java.io.InputStream
@ -20,15 +16,7 @@ import java.io.OutputStream
object OPMLParser { object OPMLParser {
val TAG = OPMLParser.javaClass.simpleName val TAG: String = OPMLParser.javaClass.simpleName
@JvmStatic
fun read(uri: Uri, context: Context): Single<Map<Folder?, List<Feed>>> {
return Single.create(SingleOnSubscribe<InputStream> {
val stream = context.contentResolver.openInputStream(uri)
it.onSuccess(stream!!)
}).flatMap { stream -> read(stream) }
}
@JvmStatic @JvmStatic
fun read(stream: InputStream): Single<Map<Folder?, List<Feed>>> { fun read(stream: InputStream): Single<Map<Folder?, List<Feed>>> {
@ -40,7 +28,6 @@ object OPMLParser {
emitter.onSuccess(opmlToFoldersAndFeeds(opml)) emitter.onSuccess(opmlToFoldersAndFeeds(opml))
} catch (e: Exception) { } catch (e: Exception) {
Log.d(TAG, e.message, e)
emitter.onError(e) emitter.onError(e)
} }
} }
@ -148,8 +135,10 @@ object OPMLParser {
* @param folder the folder feeds will be associated to * @param folder the folder feeds will be associated to
* *
*/ */
private fun associateOrphanFeedsToFolder(foldersAndFeeds: MutableMap<Folder?, List<Feed>>, private fun associateOrphanFeedsToFolder(
parsingResult: MutableMap<Folder?, List<Feed>>, folder: Folder?) { foldersAndFeeds: MutableMap<Folder?, List<Feed>>,
parsingResult: MutableMap<Folder?, List<Feed>>, folder: Folder?,
) {
val feeds = parsingResult[null] val feeds = parsingResult[null]
if (feeds != null && feeds.isNotEmpty()) { if (feeds != null && feeds.isNotEmpty()) {
if (foldersAndFeeds[folder] == null) foldersAndFeeds[folder] = feeds if (foldersAndFeeds[folder] == null) foldersAndFeeds[folder] = feeds

View File

@ -1,7 +1,5 @@
package com.readrops.api.utils; package com.readrops.api.utils;
import android.util.Log;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import org.joda.time.LocalDateTime; import org.joda.time.LocalDateTime;
@ -57,7 +55,6 @@ public final class DateUtils {
return formatter.parseLocalDateTime(value); return formatter.parseLocalDateTime(value);
} catch (Exception e) { } catch (Exception e) {
Log.d(TAG, e.getMessage());
return null; return null;
} }
} }

View File

@ -1,35 +1,20 @@
package com.readrops.api package com.readrops.api.opml
import android.Manifest import com.readrops.api.TestUtils
import android.content.Context
import android.os.Environment
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.GrantPermissionRule
import com.readrops.api.opml.OPMLParser
import com.readrops.api.utils.exceptions.ParseException import com.readrops.api.utils.exceptions.ParseException
import com.readrops.db.entities.Feed import com.readrops.db.entities.Feed
import com.readrops.db.entities.Folder import com.readrops.db.entities.Folder
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import junit.framework.TestCase.assertEquals import junit.framework.TestCase.assertEquals
import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith
import java.io.File import java.io.File
import java.io.FileOutputStream import java.io.FileOutputStream
import java.io.OutputStream
@RunWith(AndroidJUnit4::class)
class OPMLParserTest { class OPMLParserTest {
private val context: Context = InstrumentationRegistry.getInstrumentation().context
@get:Rule
val permissionRule: GrantPermissionRule = GrantPermissionRule.grant(Manifest.permission.WRITE_EXTERNAL_STORAGE)
@Test @Test
fun readOpmlTest() { fun readOpmlTest() {
val stream = context.resources.assets.open("opml/subscriptions.opml") val stream = TestUtils.loadResource("opml/subscriptions.opml")
var foldersAndFeeds: Map<Folder?, List<Feed>>? = null var foldersAndFeeds: Map<Folder?, List<Feed>>? = null
@ -52,7 +37,7 @@ class OPMLParserTest {
@Test @Test
fun readLiteSubscriptionsTest() { fun readLiteSubscriptionsTest() {
val stream = context.resources.assets.open("opml/lite_subscriptions.opml") val stream = TestUtils.loadResource("opml/lite_subscriptions.opml")
var foldersAndFeeds: Map<Folder?, List<Feed>>? = null var foldersAndFeeds: Map<Folder?, List<Feed>>? = null
@ -68,7 +53,7 @@ class OPMLParserTest {
@Test @Test
fun opmlVersionTest() { fun opmlVersionTest() {
val stream = context.resources.assets.open("opml/wrong_version.opml") val stream = TestUtils.loadResource("opml/wrong_version.opml")
OPMLParser.read(stream) OPMLParser.read(stream)
.test() .test()
@ -79,10 +64,9 @@ class OPMLParserTest {
@Test @Test
fun writeOpmlTest() { fun writeOpmlTest() {
val filePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).absolutePath val file = File("subscriptions.opml")
val file = File(filePath, "subscriptions.opml") val outputStream = FileOutputStream(file)
val outputStream: OutputStream = FileOutputStream(file)
val foldersAndFeeds: Map<Folder?, List<Feed>> = HashMap<Folder?, List<Feed>>().apply { val foldersAndFeeds: Map<Folder?, List<Feed>> = HashMap<Folder?, List<Feed>>().apply {
put(null, listOf(Feed("Feed1", "", "https://feed1.com"), put(null, listOf(Feed("Feed1", "", "https://feed1.com"),
Feed("Feed2", "", "https://feed2.com"))) Feed("Feed2", "", "https://feed2.com")))

View File

@ -16,6 +16,7 @@ import com.readrops.db.entities.account.Account;
import org.koin.core.parameter.DefinitionParametersKt; import org.koin.core.parameter.DefinitionParametersKt;
import org.koin.java.KoinJavaComponent; import org.koin.java.KoinJavaComponent;
import java.io.FileNotFoundException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -62,8 +63,8 @@ public class AccountViewModel extends ViewModel {
return repository.getFoldersWithFeeds(); return repository.getFoldersWithFeeds();
} }
public Completable parseOPMLFile(Uri uri, Context context) { public Completable parseOPMLFile(Uri uri, Context context) throws FileNotFoundException {
return OPMLParser.read(uri, context) return OPMLParser.read(context.getContentResolver().openInputStream(uri))
.flatMapCompletable(foldersAndFeeds -> repository.insertOPMLFoldersAndFeeds(foldersAndFeeds)); .flatMapCompletable(foldersAndFeeds -> repository.insertOPMLFoldersAndFeeds(foldersAndFeeds));
} }
} }

View File

@ -10,6 +10,7 @@ import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.provider.Settings; import android.provider.Settings;
import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -39,6 +40,7 @@ import com.readrops.db.entities.account.AccountType;
import org.koin.androidx.viewmodel.compat.ViewModelCompat; import org.koin.androidx.viewmodel.compat.ViewModelCompat;
import java.io.FileNotFoundException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -203,13 +205,18 @@ public class AccountSettingsFragment extends PreferenceFragmentCompat {
.cancelable(false) .cancelable(false)
.show(); .show();
parseOPMLFile(uri, dialog); try {
parseOPMLFile(uri, dialog);
} catch (FileNotFoundException e) {
Log.d(TAG, e.getMessage());
displayErrorMessage();
}
} }
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);
} }
private void parseOPMLFile(Uri uri, MaterialDialog dialog) { private void parseOPMLFile(Uri uri, MaterialDialog dialog) throws FileNotFoundException {
viewModel.parseOPMLFile(uri, getContext()) viewModel.parseOPMLFile(uri, getContext())
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())