From 3d698b30516bad8e700de4c392916681b7b275df Mon Sep 17 00:00:00 2001 From: Shinokuni Date: Thu, 30 Dec 2021 21:53:00 +0100 Subject: [PATCH] Add tests for FeverDataSource login method --- .../api/services/fever/FeverDataSource.kt | 13 +-- .../fever/adapters/FeverAPIAdapterTest.kt | 2 +- .../fever/adapters/FeverDataSourceTest.kt | 93 +++++++++++++++++++ .../resources/services/fever/failed_auth.json | 5 + ...thentication.json => successful_auth.json} | 0 .../app/repositories/FeverRepository.kt | 91 +++++++++--------- 6 files changed, 147 insertions(+), 57 deletions(-) create mode 100644 api/src/test/java/com/readrops/api/services/fever/adapters/FeverDataSourceTest.kt create mode 100644 api/src/test/resources/services/fever/failed_auth.json rename api/src/test/resources/services/fever/{authentication.json => successful_auth.json} (100%) diff --git a/api/src/main/java/com/readrops/api/services/fever/FeverDataSource.kt b/api/src/main/java/com/readrops/api/services/fever/FeverDataSource.kt index 80fb6213..f437a7fb 100644 --- a/api/src/main/java/com/readrops/api/services/fever/FeverDataSource.kt +++ b/api/src/main/java/com/readrops/api/services/fever/FeverDataSource.kt @@ -2,22 +2,15 @@ package com.readrops.api.services.fever import com.readrops.api.services.SyncType import com.readrops.api.services.fever.adapters.FeverAPIAdapter -import com.readrops.api.utils.ApiUtils +import com.readrops.api.utils.exceptions.LoginException import com.readrops.db.entities.Item import com.squareup.moshi.Moshi import okhttp3.MultipartBody class FeverDataSource(private val service: FeverService) { - suspend fun login(login: String, password: String) { - val credentials = ApiUtils.md5hash("$login:$password") - - val requestBody = MultipartBody.Builder() - .setType(MultipartBody.FORM) - .addFormDataPart("api_key", credentials) - .build() - - val response = service.login(requestBody) + suspend fun login(body: MultipartBody) { + val response = service.login(body) val adapter = Moshi.Builder() .add(Boolean::class.java, FeverAPIAdapter()) diff --git a/api/src/test/java/com/readrops/api/services/fever/adapters/FeverAPIAdapterTest.kt b/api/src/test/java/com/readrops/api/services/fever/adapters/FeverAPIAdapterTest.kt index 0535b25c..ac9cb356 100644 --- a/api/src/test/java/com/readrops/api/services/fever/adapters/FeverAPIAdapterTest.kt +++ b/api/src/test/java/com/readrops/api/services/fever/adapters/FeverAPIAdapterTest.kt @@ -15,7 +15,7 @@ class FeverAPIAdapterTest { @Test fun authenticatedTest() { - val stream = TestUtils.loadResource("services/fever/authentication.json") + val stream = TestUtils.loadResource("services/fever/successful_auth.json") val value = adapter.fromJson(Buffer().readFrom(stream))!! assertEquals(value, true) diff --git a/api/src/test/java/com/readrops/api/services/fever/adapters/FeverDataSourceTest.kt b/api/src/test/java/com/readrops/api/services/fever/adapters/FeverDataSourceTest.kt new file mode 100644 index 00000000..7ffe59e6 --- /dev/null +++ b/api/src/test/java/com/readrops/api/services/fever/adapters/FeverDataSourceTest.kt @@ -0,0 +1,93 @@ +package com.readrops.api.services.fever.adapters + +import com.readrops.api.TestUtils +import com.readrops.api.apiModule +import com.readrops.api.services.fever.FeverCredentials +import com.readrops.api.services.fever.FeverDataSource +import com.readrops.api.utils.ApiUtils +import com.readrops.api.utils.AuthInterceptor +import com.readrops.api.utils.exceptions.LoginException +import kotlinx.coroutines.runBlocking +import okhttp3.MultipartBody +import okhttp3.OkHttpClient +import okhttp3.mockwebserver.MockResponse +import okhttp3.mockwebserver.MockWebServer +import okio.Buffer +import org.junit.After +import org.junit.Assert.assertThrows +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.koin.core.parameter.parametersOf +import org.koin.dsl.module +import org.koin.test.KoinTest +import org.koin.test.KoinTestRule +import org.koin.test.get +import java.net.HttpURLConnection +import java.util.concurrent.TimeUnit + +class FeverDataSourceTest : KoinTest { + + private lateinit var dataSource: FeverDataSource + private val mockServer = MockWebServer() + + @Before + fun before() { + mockServer.start(8080) + val url = mockServer.url("") + dataSource = get(parameters = { + parametersOf(FeverCredentials(null, null, url.toString())) + }) + } + + @After + fun tearDown() { + mockServer.close() + } + + @get:Rule + val koinTestRule = KoinTestRule.create { + modules(apiModule, module { + single { + OkHttpClient.Builder() + .callTimeout(1, TimeUnit.MINUTES) + .readTimeout(1, TimeUnit.HOURS) + .addInterceptor(get()) + .build() + } + + }) + } + + @Test + fun loginSuccessfulTest() { + val stream = TestUtils.loadResource("services/fever/successful_auth.json") + + mockServer.enqueue(MockResponse().setResponseCode(HttpURLConnection.HTTP_OK) + .addHeader(ApiUtils.CONTENT_TYPE_HEADER, "application/json") + .setBody(Buffer().readFrom(stream))) + + runBlocking { + dataSource.login(MultipartBody.Builder() + .addFormDataPart("api_key", "value") + .build()) + } + } + + @Test + fun loginFailedTest() { + val stream = TestUtils.loadResource("services/fever/failed_auth.json") + + mockServer.enqueue(MockResponse().setResponseCode(HttpURLConnection.HTTP_OK) + .addHeader(ApiUtils.CONTENT_TYPE_HEADER, "application/json") + .setBody(Buffer().readFrom(stream))) + + assertThrows(LoginException::class.java) { + runBlocking { + dataSource.login(MultipartBody.Builder() + .addFormDataPart("api_key", "value") + .build()) + } + } + } +} \ No newline at end of file diff --git a/api/src/test/resources/services/fever/failed_auth.json b/api/src/test/resources/services/fever/failed_auth.json new file mode 100644 index 00000000..703f367c --- /dev/null +++ b/api/src/test/resources/services/fever/failed_auth.json @@ -0,0 +1,5 @@ +{ + "api_version": 3, + "auth": 0, + "last_refreshed_on_time": 1640564401 +} \ No newline at end of file diff --git a/api/src/test/resources/services/fever/authentication.json b/api/src/test/resources/services/fever/successful_auth.json similarity index 100% rename from api/src/test/resources/services/fever/authentication.json rename to api/src/test/resources/services/fever/successful_auth.json diff --git a/app/src/main/java/com/readrops/app/repositories/FeverRepository.kt b/app/src/main/java/com/readrops/app/repositories/FeverRepository.kt index c97b8a75..afa2c836 100644 --- a/app/src/main/java/com/readrops/app/repositories/FeverRepository.kt +++ b/app/src/main/java/com/readrops/app/repositories/FeverRepository.kt @@ -31,55 +31,46 @@ class FeverRepository( account: Account?, ) : ARepository(database, context, account) { - override fun login(account: Account, insert: Boolean): Completable { - return rxCompletable(context = dispatcher) { - try { - feverDataSource.login(account.login!!, account.password!!) - account.displayedName = account.accountType!!.name + override fun login(account: Account, insert: Boolean): Completable = + rxCompletable(context = dispatcher) { + try { + feverDataSource.login(getFeverRequestBody()) + account.displayedName = account.accountType!!.name - database.accountDao().insert(account) - .doOnSuccess { account.id = it.toInt() } - .await() - } catch (e: Exception) { - Log.e(TAG, "login: ${e.message}") - error(e.message!!) - } - } - } - - override fun sync(feeds: List?, update: FeedUpdate?): Completable { - return rxCompletable(context = dispatcher) { - try { - val syncType = if (account.lastModified != 0L) { - SyncType.CLASSIC_SYNC - } else { - SyncType.INITIAL_SYNC + database.accountDao().insert(account) + .doOnSuccess { account.id = it.toInt() } + .await() + } catch (e: Exception) { + Log.e(TAG, "login: ${e.message}") + error(e.message!!) + } + } + + override fun sync(feeds: List?, update: FeedUpdate?): Completable = + rxCompletable(context = dispatcher) { + try { + val syncType = if (account.lastModified != 0L) { + SyncType.CLASSIC_SYNC + } else { + SyncType.INITIAL_SYNC + } + + val syncResult = feverDataSource.sync(syncType, + FeverSyncData(account.lastModified.toString()), getFeverRequestBody()) + + insertFolders(syncResult.folders) + insertFeeds(syncResult.feverFeeds) + + insertItems(syncResult.items) + insertItemsIds(syncResult.unreadIds, syncResult.starredIds.toMutableList()) + + // We store the id to use for the next synchronisation even if it's not a timestamp + database.accountDao().updateLastModified(account.id, syncResult.sinceId) + } catch (e: Exception) { + Log.e(TAG, "sync: ${e.message}") + error(e.message!!) } - - val credentials = ApiUtils.md5hash("${account.login}:${account.password}") - - val requestBody = MultipartBody.Builder() - .setType(MultipartBody.FORM) - .addFormDataPart("api_key", credentials) - .build() - - val syncResult = feverDataSource.sync(syncType, - FeverSyncData(account.lastModified.toString()), requestBody) - - insertFolders(syncResult.folders) - insertFeeds(syncResult.feverFeeds) - - insertItems(syncResult.items) - insertItemsIds(syncResult.unreadIds, syncResult.starredIds.toMutableList()) - - // We store the id to use for the next synchronisation even if it's not a timestamp - database.accountDao().updateLastModified(account.id, syncResult.sinceId) - } catch (e: Exception) { - Log.e(TAG, "sync: ${e.message}") - error(e.message!!) } - } - } override fun addFeeds(results: List?): Single> { TODO("Not yet implemented") @@ -155,6 +146,14 @@ class FeverRepository( } } + private fun getFeverRequestBody(): MultipartBody { + val credentials = ApiUtils.md5hash("${account.login}:${account.password}") + return MultipartBody.Builder() + .setType(MultipartBody.FORM) + .addFormDataPart("api_key", credentials) + .build() + } + companion object { val TAG: String = FeverRepository::class.java.simpleName }