Skip to content

Commit

Permalink
[#18] Rebase
Browse files Browse the repository at this point in the history
  • Loading branch information
blyscuit committed Dec 9, 2022
1 parent 6cb3ac9 commit 35874ba
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@ data class SurveyApiModel(
val surveyType: String
)

fun SurveyApiModel.toSurvey(): Survey {
return Survey(
id,
coverImageUrl,
title,
description
)
}
fun SurveyApiModel.toSurvey() = Survey(
id,
coverImageUrl,
title,
description
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ package co.nimblehq.blisskmmic.data.network.core
import co.nimblehq.jsonapi.json.JsonApi
import io.github.aakira.napier.DebugAntilog
import io.github.aakira.napier.Napier
import io.github.aakira.napier.LogLevel.DEBUG
import io.ktor.client.*
import io.ktor.client.engine.*
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.client.plugins.logging.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.serialization.kotlinx.json.*
import io.ktor.client.plugins.logging.LogLevel.ALL
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.serialization.json.Json
Expand Down Expand Up @@ -52,19 +54,26 @@ open class NetworkClient {
emit(data)
}
}

open fun clientConfig(): HttpClientConfig<*>.() -> Unit {
return {
install(Logging) {
level = LogLevel.ALL
logger = object : Logger {
override fun log(message: String) {
Napier.log(io.github.aakira.napier.LogLevel.DEBUG, message = message)
}
}
loggingConfig()
}
install(ContentNegotiation) {
json(json)
}
}
}

fun loggingConfig(): Logging.Config.() -> Unit {
return {
level = ALL
logger = object : Logger {
override fun log(message: String) {
Napier.log(DEBUG, message = message)
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ class TokenizedNetworkClient: NetworkClient {

override fun clientConfig(): HttpClientConfig<*>.() -> Unit {
return {
install(Logging)
install(Logging) {
loggingConfig()
}
install(ContentNegotiation) {
json(json)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import kotlinx.serialization.json.Json
import kotlinx.serialization.json.encodeToJsonElement
import kotlinx.serialization.json.jsonObject

interface TargetType<T> {
interface TargetType<BodyType> {

val path: String
val method: HttpMethod
val body: T?
val body: BodyType?
}

internal inline fun <reified T> TargetType<T>.requestBuilder(): HttpRequestBuilder {
internal inline fun <reified BodyType> TargetType<BodyType>.requestBuilder(): HttpRequestBuilder {
val builder = HttpRequestBuilder()
builder.url("${BuildKonfig.BASE_URL}$API_VERSION$path")
builder.method = method
Expand All @@ -27,7 +27,7 @@ internal inline fun <reified T> TargetType<T>.requestBuilder(): HttpRequestBuild
return builder
}

private inline fun <reified T> HttpRequestBuilder.setQueryParameters(parameters: T?) {
private inline fun <reified BodyType> HttpRequestBuilder.setQueryParameters(parameters: BodyType?) {
parameters?.run {
val queryParameters = Json.encodeToJsonElement(this).jsonObject
for ((key, value) in queryParameters) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ import io.ktor.http.*
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

sealed class SurveyTargetType<T>: TargetType<T>

class SurveySelectionTargetType(page: Int = 1, size: Int = 3):
SurveyTargetType<SurveySelectionTargetType.SurveySelectionInput>() {
TargetType<SurveySelectionTargetType.SurveySelectionInput> {

@Serializable
data class SurveySelectionInput(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ import io.ktor.http.*
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

sealed class UserTargetType<T>: TargetType<T>

class LoginTargetType(email: String, password: String):
UserTargetType<LoginTargetType.LoginInput>() {
TargetType<LoginTargetType.LoginInput> {

@Serializable
data class LoginInput(
Expand All @@ -35,7 +33,8 @@ class LoginTargetType(email: String, password: String):
}


class ResetPasswordTargetType(email: String): UserTargetType<ResetPasswordTargetType.ResetPasswordInput>() {
class ResetPasswordTargetType(email: String):
TargetType<ResetPasswordTargetType.ResetPasswordInput> {

@Serializable
data class User(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package co.nimblehq.blisskmmic.data.datasource

import app.cash.turbine.test
import co.nimblehq.blisskmmic.data.network.core.NetworkClient
import co.nimblehq.blisskmmic.data.network.datasource.NetworkDataSourceImpl
import co.nimblehq.blisskmmic.data.network.target.LoginTargetType
Expand All @@ -14,7 +15,6 @@ import co.nimblehq.jsonapi.model.JsonApiException
import io.kotest.matchers.collections.shouldContain
import io.kotest.matchers.shouldBe
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.test.runTest
import kotlin.test.Test
import kotlin.test.fail
Expand All @@ -31,8 +31,9 @@ class NetworkDataSourceTest {
val dataSource = NetworkDataSourceImpl(networkClient)
dataSource
.logIn(LoginTargetType("", ""))
.collect {
it.refreshToken shouldBe "refresh_token"
.test {
awaitItem().refreshToken shouldBe "refresh_token"
awaitComplete()
}
}

Expand All @@ -43,15 +44,12 @@ class NetworkDataSourceTest {
val dataSource = NetworkDataSourceImpl(networkClient)
dataSource
.logIn(LoginTargetType("", ""))
.catch { error ->
when(error) {
.test {
when(val error = awaitError()) {
is JsonApiException -> error.errors.map { it.code } shouldContain "invalid_token"
else -> fail("Should not return incorrect error type")
}
}
.collect {
fail("Should not return object")
}
}

// Reset password
Expand All @@ -63,10 +61,11 @@ class NetworkDataSourceTest {
val dataSource = NetworkDataSourceImpl(networkClient)
dataSource
.resetPassword(ResetPasswordTargetType(""))
.collect {
it.message shouldBe """
.test {
awaitItem().message shouldBe """
If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes.
""".trimIndent()
awaitComplete()
}
}

Expand All @@ -79,10 +78,12 @@ class NetworkDataSourceTest {
val dataSource = NetworkDataSourceImpl(networkClient)
dataSource
.survey(SurveySelectionTargetType())
.collect {
it.first.size shouldBe 2
it.first.first().title shouldBe "Scarlett Bangkok"
it.second.page shouldBe 1
.test {
val response = awaitItem()
response .first.size shouldBe 2
response .first.first().title shouldBe "Scarlett Bangkok"
response .second.page shouldBe 1
awaitComplete()
}
}

Expand All @@ -93,14 +94,11 @@ class NetworkDataSourceTest {
val dataSource = NetworkDataSourceImpl(networkClient)
dataSource
.survey(SurveySelectionTargetType())
.catch { error ->
when(error) {
.test {
when (val error = awaitError()) {
is JsonApiException -> error.errors.map { it.code } shouldContain "invalid_token"
else -> fail("Should not return incorrect error type")
}
}
.collect {
fail("Should not return object")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,11 @@ class NetworkClientTest {
val networkClient = NetworkClient(engine = engine)
networkClient
.fetchWithMeta<NetworkMockModel, NetworkMetaMockModel>(request)
.collect {
it.first.title shouldBe "Hello"
it.second.page shouldBe 1
.test {
val response = awaitItem()
response.first.title shouldBe "Hello"
response.second.page shouldBe 1
awaitComplete()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class TokenizedNetworkClientTest {
fun `when calling fetchWithMeta, it returns correct object`() = runTest {
mocker.every {
localDataSource.getToken()
} returns flow { emit(token) }
} returns flowOf(token)
val engine = jsonTokenizedMockEngine(
NETWORK_META_MOCK_MODEL_RESULT,
token.accessToken,
Expand All @@ -79,9 +79,11 @@ class TokenizedNetworkClientTest {
val networkClient = TokenizedNetworkClient(engine = engine, localDataSource)
networkClient
.fetchWithMeta<NetworkMockModel, NetworkMetaMockModel>(request)
.collect {
it.first.title shouldBe "Hello"
it.second.page shouldBe 1
.test {
val response = awaitItem()
response.first.title shouldBe "Hello"
response.second.page shouldBe 1
awaitComplete()
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
package co.nimblehq.blisskmmic.data.repository

import app.cash.turbine.test
import co.nimblehq.blisskmmic.data.model.PaginationMetaApiModel
import co.nimblehq.blisskmmic.data.model.SurveyApiModel
import co.nimblehq.blisskmmic.data.network.datasource.NetworkDataSource
import io.kotest.matchers.shouldBe
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.runTest
import org.kodein.mock.Fake
import org.kodein.mock.Mock
import org.kodein.mock.tests.TestsWithMocks
import kotlin.test.BeforeTest
import kotlin.test.Test
import kotlin.test.fail

@ExperimentalCoroutinesApi
class SurveyRepositoryTest: TestsWithMocks() {
Expand All @@ -38,12 +38,14 @@ class SurveyRepositoryTest: TestsWithMocks() {
fun `When calling survey with success response, it returns correct object`() = runTest {
mocker.every {
networkDataSource.survey(isAny())
} returns flow { emit(Pair(listOf(survey), meta)) }
} returns flowOf(Pair(listOf(survey), meta))
surveyRepository
.survey(1)
.collect {
it.first.first().title shouldBe survey.title
it.second.page shouldBe meta.page
.test {
val response = awaitItem()
response.first.first().title shouldBe survey.title
response.second.page shouldBe meta.page
awaitComplete()
}
}

Expand All @@ -54,11 +56,8 @@ class SurveyRepositoryTest: TestsWithMocks() {
} returns flow { error("Fail") }
surveyRepository
.survey(1)
.catch {
it.message shouldBe "Fail"
}
.collect {
fail("Should not return object")
.test {
awaitError().message shouldBe "Fail"
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package co.nimblehq.blisskmmic.domain.usecase

import app.cash.turbine.test
import co.nimblehq.blisskmmic.domain.model.PaginationMeta
import co.nimblehq.blisskmmic.domain.model.Survey
import co.nimblehq.blisskmmic.domain.model.fakePaginationMeta
Expand All @@ -10,6 +11,7 @@ import io.kotest.matchers.shouldBe
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.runTest
import org.kodein.mock.Mocker
import org.kodein.mock.UsesFakes
Expand Down Expand Up @@ -38,11 +40,12 @@ class SurveyListUseCaseTest {
fun `When calling surveyList with a success response, it returns correct object`() = runTest {
mocker.every {
surveyRepository.survey(1)
} returns flow { emit(Pair(listOf(survey), paginationMeta)) }
} returns flowOf(Pair(listOf(survey), paginationMeta))

surveyListUseCase(1)
.collect{
it.first().title shouldBe survey.title
.test {
awaitItem().first().title shouldBe survey.title
awaitComplete()
}
}

Expand All @@ -53,11 +56,8 @@ class SurveyListUseCaseTest {
} returns flow { error("Fail") }

surveyListUseCase(1)
.catch {
it.message shouldBe "Fail"
}
.collect{
fail("Should not receive object")
.test {
awaitError().message shouldBe "Fail"
}
}
}

0 comments on commit 35874ba

Please sign in to comment.