Merge pull request #441 from android/refactor/remote_fake_data_source

Remove FakeDataSource
pull/460/head
Milosz Moczkowski 3 years ago committed by GitHub
commit a70761f24b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -21,18 +21,13 @@ import com.google.samples.apps.nowinandroid.core.data.repository.AuthorsReposito
import com.google.samples.apps.nowinandroid.core.model.data.Author import com.google.samples.apps.nowinandroid.core.model.data.Author
import com.google.samples.apps.nowinandroid.core.network.Dispatcher import com.google.samples.apps.nowinandroid.core.network.Dispatcher
import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO
import com.google.samples.apps.nowinandroid.core.network.fake.FakeAssetManager import com.google.samples.apps.nowinandroid.core.network.fake.FakeNiaNetworkDataSource
import com.google.samples.apps.nowinandroid.core.network.fake.FakeDataSource
import com.google.samples.apps.nowinandroid.core.network.model.NetworkAuthor
import java.io.InputStream
import javax.inject.Inject import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream
/** /**
* Fake implementation of the [AuthorsRepository] that returns hardcoded authors. * Fake implementation of the [AuthorsRepository] that returns hardcoded authors.
@ -42,15 +37,12 @@ import kotlinx.serialization.json.decodeFromStream
*/ */
class FakeAuthorsRepository @Inject constructor( class FakeAuthorsRepository @Inject constructor(
@Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher, @Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher,
private val networkJson: Json, private val datasource: FakeNiaNetworkDataSource
private val assets: FakeAssetManager,
) : AuthorsRepository { ) : AuthorsRepository {
override fun getAuthorsStream(): Flow<List<Author>> = flow { override fun getAuthorsStream(): Flow<List<Author>> = flow {
emit( emit(
assets.open(FakeDataSource.AUTHORS) datasource.getAuthors().map {
.use<InputStream, List<NetworkAuthor>>(networkJson::decodeFromStream)
.map {
Author( Author(
id = it.id, id = it.id,
name = it.name, name = it.name,
@ -61,8 +53,7 @@ class FakeAuthorsRepository @Inject constructor(
) )
} }
) )
} }.flowOn(ioDispatcher)
.flowOn(ioDispatcher)
override fun getAuthorStream(id: String): Flow<Author> { override fun getAuthorStream(id: String): Flow<Author> {
return getAuthorsStream().map { it.first { author -> author.id == id } } return getAuthorsStream().map { it.first { author -> author.id == id } }

@ -24,17 +24,13 @@ import com.google.samples.apps.nowinandroid.core.database.model.asExternalModel
import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResource
import com.google.samples.apps.nowinandroid.core.network.Dispatcher import com.google.samples.apps.nowinandroid.core.network.Dispatcher
import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO
import com.google.samples.apps.nowinandroid.core.network.fake.FakeAssetManager import com.google.samples.apps.nowinandroid.core.network.fake.FakeNiaNetworkDataSource
import com.google.samples.apps.nowinandroid.core.network.fake.FakeDataSource
import com.google.samples.apps.nowinandroid.core.network.model.NetworkNewsResource import com.google.samples.apps.nowinandroid.core.network.model.NetworkNewsResource
import java.io.InputStream
import javax.inject.Inject import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream
/** /**
* Fake implementation of the [NewsRepository] that retrieves the news resources from a JSON String. * Fake implementation of the [NewsRepository] that retrieves the news resources from a JSON String.
@ -44,20 +40,17 @@ import kotlinx.serialization.json.decodeFromStream
*/ */
class FakeNewsRepository @Inject constructor( class FakeNewsRepository @Inject constructor(
@Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher, @Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher,
private val networkJson: Json, private val datasource: FakeNiaNetworkDataSource
private val assets: FakeAssetManager,
) : NewsRepository { ) : NewsRepository {
override fun getNewsResourcesStream(): Flow<List<NewsResource>> = override fun getNewsResourcesStream(): Flow<List<NewsResource>> =
flow { flow {
emit( emit(
assets.open(FakeDataSource.DATA) datasource.getNewsResources()
.use<InputStream, List<NetworkNewsResource>>(networkJson::decodeFromStream)
.map(NetworkNewsResource::asEntity) .map(NetworkNewsResource::asEntity)
.map(NewsResourceEntity::asExternalModel) .map(NewsResourceEntity::asExternalModel)
) )
} }.flowOn(ioDispatcher)
.flowOn(ioDispatcher)
override fun getNewsResourcesStream( override fun getNewsResourcesStream(
filterAuthorIds: Set<String>, filterAuthorIds: Set<String>,
@ -65,18 +58,16 @@ class FakeNewsRepository @Inject constructor(
): Flow<List<NewsResource>> = ): Flow<List<NewsResource>> =
flow { flow {
emit( emit(
assets.open(FakeDataSource.DATA).use { stream -> datasource
networkJson.decodeFromStream<List<NetworkNewsResource>>(stream) .getNewsResources()
.filter { .filter {
it.authors.intersect(filterAuthorIds).isNotEmpty() || it.authors.intersect(filterAuthorIds).isNotEmpty() ||
it.topics.intersect(filterTopicIds).isNotEmpty() it.topics.intersect(filterTopicIds).isNotEmpty()
} }
.map(NetworkNewsResource::asEntity) .map(NetworkNewsResource::asEntity)
.map(NewsResourceEntity::asExternalModel) .map(NewsResourceEntity::asExternalModel)
}
) )
} }.flowOn(ioDispatcher)
.flowOn(ioDispatcher)
override suspend fun syncWith(synchronizer: Synchronizer) = true override suspend fun syncWith(synchronizer: Synchronizer) = true
} }

@ -21,18 +21,13 @@ import com.google.samples.apps.nowinandroid.core.data.repository.TopicsRepositor
import com.google.samples.apps.nowinandroid.core.model.data.Topic import com.google.samples.apps.nowinandroid.core.model.data.Topic
import com.google.samples.apps.nowinandroid.core.network.Dispatcher import com.google.samples.apps.nowinandroid.core.network.Dispatcher
import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO
import com.google.samples.apps.nowinandroid.core.network.fake.FakeAssetManager import com.google.samples.apps.nowinandroid.core.network.fake.FakeNiaNetworkDataSource
import com.google.samples.apps.nowinandroid.core.network.fake.FakeDataSource
import com.google.samples.apps.nowinandroid.core.network.model.NetworkTopic
import java.io.InputStream
import javax.inject.Inject import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream
/** /**
* Fake implementation of the [TopicsRepository] that retrieves the topics from a JSON String, and * Fake implementation of the [TopicsRepository] that retrieves the topics from a JSON String, and
@ -43,14 +38,11 @@ import kotlinx.serialization.json.decodeFromStream
*/ */
class FakeTopicsRepository @Inject constructor( class FakeTopicsRepository @Inject constructor(
@Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher, @Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher,
private val networkJson: Json, private val datasource: FakeNiaNetworkDataSource
private val assets: FakeAssetManager,
) : TopicsRepository { ) : TopicsRepository {
override fun getTopicsStream(): Flow<List<Topic>> = flow { override fun getTopicsStream(): Flow<List<Topic>> = flow {
emit( emit(
assets.open(FakeDataSource.TOPICS) datasource.getTopics().map {
.use<InputStream, List<NetworkTopic>>(networkJson::decodeFromStream)
.map {
Topic( Topic(
id = it.id, id = it.id,
name = it.name, name = it.name,
@ -61,8 +53,7 @@ class FakeTopicsRepository @Inject constructor(
) )
} }
) )
} }.flowOn(ioDispatcher)
.flowOn(ioDispatcher)
override fun getTopic(id: String): Flow<Topic> { override fun getTopic(id: String): Flow<Topic> {
return getTopicsStream().map { it.first { topic -> topic.id == id } } return getTopicsStream().map { it.first { topic -> topic.id == id } }

@ -1,23 +0,0 @@
/*
* Copyright 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.samples.apps.nowinandroid.core.network.fake
object FakeDataSource {
const val AUTHORS = "authors.json"
const val DATA = "data.json"
const val TOPICS = "topics.json"
}

@ -27,6 +27,7 @@ import com.google.samples.apps.nowinandroid.core.network.model.NetworkTopic
import javax.inject.Inject import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream import kotlinx.serialization.json.decodeFromStream
@ -38,19 +39,29 @@ class FakeNiaNetworkDataSource @Inject constructor(
private val networkJson: Json, private val networkJson: Json,
private val assets: FakeAssetManager = JvmUnitTestFakeAssetManager, private val assets: FakeAssetManager = JvmUnitTestFakeAssetManager,
) : NiaNetworkDataSource { ) : NiaNetworkDataSource {
companion object {
private const val AUTHORS_ASSET = "authors.json"
private const val NEWS_ASSET = "news.json"
private const val TOPICS_ASSET = "topics.json"
}
@OptIn(ExperimentalSerializationApi::class)
override suspend fun getTopics(ids: List<String>?): List<NetworkTopic> = override suspend fun getTopics(ids: List<String>?): List<NetworkTopic> =
withContext(ioDispatcher) { withContext(ioDispatcher) {
assets.open(FakeDataSource.TOPICS).use(networkJson::decodeFromStream) assets.open(TOPICS_ASSET).use(networkJson::decodeFromStream)
} }
@OptIn(ExperimentalSerializationApi::class)
override suspend fun getNewsResources(ids: List<String>?): List<NetworkNewsResource> = override suspend fun getNewsResources(ids: List<String>?): List<NetworkNewsResource> =
withContext(ioDispatcher) { withContext(ioDispatcher) {
assets.open(FakeDataSource.DATA).use(networkJson::decodeFromStream) assets.open(NEWS_ASSET).use(networkJson::decodeFromStream)
} }
@OptIn(ExperimentalSerializationApi::class)
override suspend fun getAuthors(ids: List<String>?): List<NetworkAuthor> = override suspend fun getAuthors(ids: List<String>?): List<NetworkAuthor> =
withContext(ioDispatcher) { withContext(ioDispatcher) {
assets.open(FakeDataSource.AUTHORS).use(networkJson::decodeFromStream) assets.open(AUTHORS_ASSET).use(networkJson::decodeFromStream)
} }
override suspend fun getTopicChangeList(after: Int?): List<NetworkChangeList> = override suspend fun getTopicChangeList(after: Int?): List<NetworkChangeList> =

Loading…
Cancel
Save