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 6c641096..09bf3654 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 @@ -33,7 +33,7 @@ class FeverDataSource(private val service: FeverService) { if (syncType == SyncType.INITIAL_SYNC) { return FeverSyncResult().apply { - listOf( + awaitAll( async { feverFeeds = service.getFeeds(body) }, async { folders = service.getFolders(body) }, async { @@ -58,11 +58,10 @@ class FeverDataSource(private val service: FeverService) { async { starredIds = service.getStarredItemsIds(body) }, async { favicons = service.getFavicons(body) } ) - .awaitAll() } } else { return FeverSyncResult().apply { - listOf( + awaitAll( async { folders = service.getFolders(body) }, async { feverFeeds = service.getFeeds(body) }, async { unreadIds = service.getUnreadItemsIds(body) }, @@ -90,7 +89,6 @@ class FeverDataSource(private val service: FeverService) { } } ) - .awaitAll() } } } diff --git a/api/src/main/java/com/readrops/api/services/freshrss/FreshRSSDataSource.kt b/api/src/main/java/com/readrops/api/services/freshrss/FreshRSSDataSource.kt index 137efee8..d9333f22 100644 --- a/api/src/main/java/com/readrops/api/services/freshrss/FreshRSSDataSource.kt +++ b/api/src/main/java/com/readrops/api/services/freshrss/FreshRSSDataSource.kt @@ -41,7 +41,7 @@ class FreshRSSDataSource(private val service: FreshRSSService) { ): DataSourceResult = with(CoroutineScope(Dispatchers.IO)) { return if (syncType == SyncType.INITIAL_SYNC) { DataSourceResult().apply { - listOf( + awaitAll( async { folders = getFolders() }, async { feeds = getFeeds() }, async { @@ -50,17 +50,17 @@ class FreshRSSDataSource(private val service: FreshRSSService) { async { starredItems = getStarredItems(MAX_STARRED_ITEMS) }, async { unreadIds = getItemsIds(GOOGLE_READ, GOOGLE_READING_LIST, MAX_ITEMS) }, async { starredIds = getItemsIds(null, GOOGLE_STARRED, MAX_STARRED_ITEMS) } - ).awaitAll() + ) } } else { DataSourceResult().apply { - listOf( + awaitAll( async { setItemsReadState(syncData, writeToken) }, async { setItemsStarState(syncData, writeToken) }, - ).awaitAll() + ) - listOf( + awaitAll( async { folders = getFolders() }, async { feeds = getFeeds() }, async { items = getItems(null, MAX_ITEMS, syncData.lastModified) }, @@ -69,7 +69,7 @@ class FreshRSSDataSource(private val service: FreshRSSService) { readIds = getItemsIds(GOOGLE_UNREAD, GOOGLE_READING_LIST, MAX_ITEMS) }, async { starredIds = getItemsIds(null, GOOGLE_STARRED, MAX_STARRED_ITEMS) } - ).awaitAll() + ) } } diff --git a/api/src/main/java/com/readrops/api/services/nextcloudnews/NextcloudNewsDataSource.kt b/api/src/main/java/com/readrops/api/services/nextcloudnews/NextcloudNewsDataSource.kt index 58d5f3ed..dbf7ccac 100644 --- a/api/src/main/java/com/readrops/api/services/nextcloudnews/NextcloudNewsDataSource.kt +++ b/api/src/main/java/com/readrops/api/services/nextcloudnews/NextcloudNewsDataSource.kt @@ -36,7 +36,7 @@ class NextcloudNewsDataSource(private val service: NextcloudNewsService) { with(CoroutineScope(Dispatchers.IO)) { return if (syncType == SyncType.INITIAL_SYNC) { DataSourceResult().apply { - listOf( + awaitAll( async { folders = getFolders() }, async { feeds = getFeeds() }, async { items = getItems(ItemQueryType.ALL.value, false, MAX_ITEMS) }, @@ -44,20 +44,20 @@ class NextcloudNewsDataSource(private val service: NextcloudNewsService) { starredItems = getItems(ItemQueryType.STARRED.value, true, MAX_STARRED_ITEMS) } - ).awaitAll() + ) } } else { - listOf( + awaitAll( async { setItemsReadState(syncData) }, async { setItemsStarState(syncData) }, - ).awaitAll() + ) DataSourceResult().apply { - listOf( + awaitAll( async { folders = getFolders() }, async { feeds = getFeeds() }, async { items = getNewItems(syncData.lastModified, ItemQueryType.ALL) } - ).awaitAll() + ) } } } diff --git a/api/src/test/java/com/readrops/api/services/nextcloudnews/NextcloudNewsDataSourceTest.kt b/api/src/test/java/com/readrops/api/services/nextcloudnews/NextcloudNewsDataSourceTest.kt index 6961c80a..c0034793 100644 --- a/api/src/test/java/com/readrops/api/services/nextcloudnews/NextcloudNewsDataSourceTest.kt +++ b/api/src/test/java/com/readrops/api/services/nextcloudnews/NextcloudNewsDataSourceTest.kt @@ -4,11 +4,16 @@ import com.readrops.api.TestUtils import com.readrops.api.apiModule import com.readrops.api.enqueueOK import com.readrops.api.enqueueOKStream +import com.readrops.api.okResponseWithBody +import com.readrops.api.services.SyncType import com.readrops.db.entities.account.Account import com.squareup.moshi.Moshi import com.squareup.moshi.Types import kotlinx.coroutines.test.runTest +import okhttp3.mockwebserver.Dispatcher +import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockWebServer +import okhttp3.mockwebserver.RecordedRequest import org.junit.After import org.junit.Before import org.junit.Rule @@ -93,12 +98,18 @@ class NextcloudNewsDataSourceTest : KoinTest { val stream = TestUtils.loadResource("services/nextcloudnews/adapters/items.json") mockServer.enqueueOKStream(stream) - val items = nextcloudNewsDataSource.getItems(NextcloudNewsDataSource.ItemQueryType.ALL.value, false, 10) + val type = NextcloudNewsDataSource.ItemQueryType.ALL.value + + val items = nextcloudNewsDataSource.getItems( + type = type, + read = false, + batchSize = 10 + ) val request = mockServer.takeRequest() assertTrue { items.size == 3 } with(request.requestUrl!!) { - assertEquals("3", queryParameter("type")) + assertEquals("$type", queryParameter("type")) assertEquals("false", queryParameter("getRead")) assertEquals("10", queryParameter("batchSize")) } @@ -152,12 +163,11 @@ class NextcloudNewsDataSourceTest : KoinTest { nextcloudNewsDataSource.changeFeedFolder(15, 18) val request = mockServer.takeRequest() - val type = - Types.newParameterizedType( - Map::class.java, - String::class.java, - Int::class.javaObjectType - ) + val type = Types.newParameterizedType( + Map::class.java, + String::class.java, + Int::class.javaObjectType + ) val adapter = moshi.adapter>(type) val body = adapter.fromJson(request.body)!! @@ -267,12 +277,11 @@ class NextcloudNewsDataSourceTest : KoinTest { val starRequest = mockServer.takeRequest() val unstarRequest = mockServer.takeRequest() - val type = - Types.newParameterizedType( - Map::class.java, - String::class.java, - Types.newParameterizedType(List::class.java, Int::class.javaObjectType) - ) + val type = Types.newParameterizedType( + Map::class.java, + String::class.java, + Types.newParameterizedType(List::class.java, Int::class.javaObjectType) + ) val adapter = moshi.adapter>>(type) val starBody = adapter.fromJson(starRequest.body)!! @@ -281,4 +290,98 @@ class NextcloudNewsDataSourceTest : KoinTest { assertEquals(data.starredIds, starBody["itemIds"]) assertEquals(data.unstarredIds, unstarBody["itemIds"]) } + + @Test + fun initialSyncTest() = runTest { + mockServer.dispatcher = object : Dispatcher() { + + override fun dispatch(request: RecordedRequest): MockResponse { + with(request.path!!) { + return when { + this == "/folders" -> { + MockResponse.okResponseWithBody(TestUtils.loadResource("services/nextcloudnews/adapters/valid_folder.json")) + } + + this == "/feeds" -> { + MockResponse.okResponseWithBody(TestUtils.loadResource("services/nextcloudnews/adapters/feeds.json")) + } + + contains("/items") -> { + + MockResponse.okResponseWithBody(TestUtils.loadResource("services/nextcloudnews/adapters/items.json")) + } + + else -> MockResponse().setResponseCode(404) + } + } + } + } + + val result = + nextcloudNewsDataSource.synchronize(SyncType.INITIAL_SYNC, NextcloudNewsSyncData()) + + with(result) { + assertEquals(1, folders.size) + assertEquals(3, feeds.size) + assertEquals(3, items.size) + assertEquals(3, starredItems.size) + } + } + + @Test + fun classicSyncTest() = runTest { + var setItemState = 0 + val lastModified = 10L + val ids = listOf(1, 2, 3, 4) + + mockServer.dispatcher = object : Dispatcher() { + + override fun dispatch(request: RecordedRequest): MockResponse { + with(request.path!!) { + return when { + this == "/folders" -> { + MockResponse.okResponseWithBody(TestUtils.loadResource("services/nextcloudnews/adapters/valid_folder.json")) + } + + this == "/feeds" -> { + MockResponse.okResponseWithBody(TestUtils.loadResource("services/nextcloudnews/adapters/feeds.json")) + } + + contains("/items/updated") -> { + assertEquals( + "$lastModified", + request.requestUrl!!.queryParameter("lastModified") + ) + MockResponse.okResponseWithBody(TestUtils.loadResource("services/nextcloudnews/adapters/items.json")) + } + + this.matches(Regex("/items/(read|unread|star|unstar)/multiple")) -> { + setItemState++ + MockResponse().setResponseCode(200) + } + + else -> MockResponse().setResponseCode(404) + } + } + } + } + + val result = nextcloudNewsDataSource.synchronize( + SyncType.CLASSIC_SYNC, + NextcloudNewsSyncData( + lastModified = lastModified, + readIds = ids, + unreadIds = ids, + starredIds = ids, + unstarredIds = ids + ) + ) + + with(result) { + assertEquals(4, setItemState) + assertEquals(1, folders.size) + assertEquals(3, feeds.size) + assertEquals(3, items.size) + } + } } \ No newline at end of file