model: import API related classes

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
Harsh Shandilya 2020-12-01 22:37:19 +05:30
parent f16d557138
commit c29edfd402
No known key found for this signature in database
GPG key ID: 366D7BBAD1031E80
9 changed files with 10 additions and 4 deletions

View file

@ -83,10 +83,6 @@ dependencies {
implementation(Dependencies.AndroidX.Room.runtime)
implementation(Dependencies.AndroidX.Room.ktx)
implementation(Dependencies.Kotlin.Coroutines.android)
implementation(Dependencies.Kotlin.Ktor.clientCore)
implementation(Dependencies.Kotlin.Ktor.clientJson)
implementation(Dependencies.Kotlin.Ktor.clientOkHttp)
implementation(Dependencies.Kotlin.Ktor.clientSerialization)
implementation(Dependencies.Kotlin.Serialization.json)
implementation(Dependencies.ThirdParty.accompanist)
implementation(Dependencies.ThirdParty.customtabs)

View file

@ -1,16 +0,0 @@
package dev.msfjarvis.lobsters.data.api
import dev.msfjarvis.lobsters.data.api.LobstersApi.Companion.BASE_URL
import dev.msfjarvis.lobsters.model.LobstersPost
import io.ktor.client.HttpClient
import io.ktor.client.request.get
import javax.inject.Inject
/**
* Ktor backed implementation of [LobstersApi]
*/
class KtorLobstersApi @Inject constructor(private val client: HttpClient) : LobstersApi {
override suspend fun getHottestPosts(page: Int): List<LobstersPost> {
return client.get("${BASE_URL}/hottest.json?page=$page")
}
}

View file

@ -1,15 +0,0 @@
package dev.msfjarvis.lobsters.data.api
import dev.msfjarvis.lobsters.model.LobstersPost
/**
* Simple interface defining an API for lobste.rs
*/
interface LobstersApi {
suspend fun getHottestPosts(page: Int): List<LobstersPost>
companion object {
const val BASE_URL = "https://lobste.rs"
}
}

View file

@ -1,14 +0,0 @@
package dev.msfjarvis.lobsters.injection
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityComponent
import dev.msfjarvis.lobsters.data.api.KtorLobstersApi
import dev.msfjarvis.lobsters.data.api.LobstersApi
@Module
@InstallIn(ActivityComponent::class)
abstract class KtorApiModule {
@Binds abstract fun bindLobstersApi(realApi: KtorLobstersApi): LobstersApi
}

View file

@ -1,26 +0,0 @@
package dev.msfjarvis.lobsters.injection
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import io.ktor.client.HttpClient
import io.ktor.client.engine.okhttp.OkHttp
import io.ktor.client.features.json.JsonFeature
import io.ktor.client.features.json.serializer.KotlinxSerializer
@Module
@InstallIn(SingletonComponent::class)
object KtorClientModule {
@Provides
fun provideClient() = HttpClient(OkHttp) {
install(JsonFeature) {
serializer = KotlinxSerializer()
}
engine {
config {
followSslRedirects(true)
}
}
}
}

View file

@ -1,78 +0,0 @@
package dev.msfjarvis.lobsters.data.api
import dev.msfjarvis.lobsters.util.TestUtils
import io.ktor.client.HttpClient
import io.ktor.client.engine.mock.MockEngine
import io.ktor.client.engine.mock.respond
import io.ktor.client.features.json.JsonFeature
import io.ktor.client.features.json.serializer.KotlinxSerializer
import io.ktor.http.fullPath
import io.ktor.http.headersOf
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import kotlinx.coroutines.runBlocking
import org.junit.AfterClass
import org.junit.BeforeClass
import org.junit.Test
class KtorLobstersApiTest {
companion object {
@JvmStatic
private lateinit var client: HttpClient
@JvmStatic
private lateinit var apiClient: LobstersApi
@JvmStatic
@BeforeClass
fun setUp() {
client = HttpClient(MockEngine) {
install(JsonFeature) {
serializer = KotlinxSerializer()
}
engine {
addHandler { request ->
when (request.url.fullPath) {
"/hottest.json?page=1" -> {
val responseHeaders = headersOf("Content-Type" to listOf("application/json"))
respond(TestUtils.getJson("hottest.json"), headers = responseHeaders)
}
else -> error("Unhandled ${request.url.fullPath}")
}
}
}
}
apiClient = KtorLobstersApi(client)
}
@JvmStatic
@AfterClass
fun tearDown() {
client.close()
}
}
@Test
fun `api gets correct number of items`() = runBlocking {
val posts = apiClient.getHottestPosts(1)
assertEquals(25, posts.size)
}
@Test
fun `no moderator posts in test data`() = runBlocking {
val posts = apiClient.getHottestPosts(1)
val moderatorPosts = posts.asSequence()
.filter { it.submitterUser.isModerator }
.toSet()
assertTrue(moderatorPosts.isEmpty())
}
@Test
fun `posts with no urls`() = runBlocking {
val posts = apiClient.getHottestPosts(1)
val commentsOnlyPosts = posts.asSequence()
.filter { it.url.isEmpty() }
.toSet()
assertEquals(2, commentsOnlyPosts.size)
}
}

View file

@ -1,12 +0,0 @@
package dev.msfjarvis.lobsters.util
import java.io.File
object TestUtils {
fun getJson(path: String): String {
// Load the JSON response
val uri = javaClass.classLoader.getResource(path)
val file = File(uri.path)
return String(file.readBytes())
}
}

File diff suppressed because one or more lines are too long