Add tests for FeverDataSource login method

This commit is contained in:
Shinokuni 2021-12-30 21:53:00 +01:00
parent 53c5d2f56b
commit 3d698b3051
6 changed files with 147 additions and 57 deletions

View File

@ -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())

View File

@ -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)

View File

@ -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<AuthInterceptor>())
.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())
}
}
}
}

View File

@ -0,0 +1,5 @@
{
"api_version": 3,
"auth": 0,
"last_refreshed_on_time": 1640564401
}

View File

@ -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<Feed>?, 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<Feed>?, 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<ParsingResult>?): Single<List<FeedInsertionResult>> {
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
}