Random Joke is a simple app to read random jokes, some of them are really good. This project was created with the objective of demonstrating the use of good practices in Android development using MVVM + Clean architecture + Coroutines + Kotlin Flow + Hilt + Retrofit + SplashScreen API
- Get a categorized joke from a public API.
- Quick jump to other jokes
- Share jokes with other people
Data source used for this project:
- JokesAPI - Jokes public API
Unit tests were applied to the use case with the possible edge cases that could occur. In this example, a test case is designed for when the request response is satisfactory.
@Test
fun `when the response is successful then return the mapped object`() = runBlocking {
//given
val flags = Flags(
nsfw = false,
religious = false,
political = false,
racist = false,
sexist = false,
explicit = false
)
val jokeTest = JokeResponseModel(
error = false,
category = "Programming",
type = "twopart",
setup = "Why does no one like SQLrillex?",
delivery = "He keeps dropping the database.",
flags = flags,
id = 239,
safe = false,
lang = "en"
)
coEvery {
jokeRepository.getJoke()
} returns flowOf(BaseResult.Success(jokeTest))
lateinit var data: JokeResponseModel
//when
val response = getRandomJokeUseCase.invoke()
response.collect {
when (it) {
is BaseResult.Success -> {
data = it.data
}
else -> {}
}
}
//then
coVerify(exactly = 1) {
jokeRepository.getJoke()
}
assert(jokeTest == data)
}
A complete verification of possible errors was carried out, so that the app reacts to any change in status or response from the server
override suspend fun getJoke(): Flow<BaseResult<JokeResponseModel, ErrorModel, Exception>> {
return flow {
try {
val response = jokeApi.getRandomJoke()
if (response.isSuccessful && response.code() == 200) {
val body = response.body()!!
emit(BaseResult.Success(body))
} else {
val type = object : TypeToken<ErrorModel>() {}.type
val err = Gson().fromJson<ErrorModel>(
response.errorBody()!!.charStream(),
type
)!!
emit(BaseResult.Error(err))
}
} catch (e: Exception) {
emit(BaseResult.Exception(e))
}
}
}