Skip to content

Commit

Permalink
Merge branch 'main' into #18-cleaning-up-code
Browse files Browse the repository at this point in the history
# Conflicts:
#	library/data/src/main/java/id/apwdevs/app/data/mediator/PopularMovieRemoteMediator.kt
#	library/data/src/main/java/id/apwdevs/app/data/source/local/entity/items/MovieEntity.kt
  • Loading branch information
AlexzPurewoko committed May 2, 2021
2 parents 04d3ada + 7df8b99 commit 50bcca8
Show file tree
Hide file tree
Showing 43 changed files with 1,636 additions and 381 deletions.
34 changes: 1 addition & 33 deletions feature/detail/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,12 @@ android {
versionCode = Apps.versionCode
versionName = Apps.versionName

testInstrumentationRunner = "id.apwdevs.app.movieshow.runner.AppTestRunner"
testInstrumentationRunner = "id.apwdevs.app.test.androdtest.runner.AppTestRunner"
testApplicationId = applicationId
}

buildFeatures.viewBinding = true

sourceSets {
// ["${project('match the module name that is currently in the dependencies').projectDir}/src/androidTest/java"]
// getByName("androidTest").apply {
// val src = java.srcDirs.toMutableSet()
// src.add(File(project(":app").projectDir, "src/androidTest/java"))
// java.setSrcDirs(src)
// }
}

compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
Expand All @@ -62,27 +53,4 @@ dependencies {
isTransitive = false
}
androidTestImplementation(project(":test:androidtestlibs"))

testImplementation(TestLibs.junit)

listOf(
AndroidTestLibs.navigation,
AndroidTestLibs.androidxJunit,
AndroidTestLibs.androidxAnnotatation,
TestLibs.mockWebServer

).forEach { androidTestImplementation(it) }



// debugImplementation(AndroidTestLibs.fragment)
// androidTestImplementation(Libs.coreKtx)
androidTestImplementation(project(":app"))
debugImplementation(project(":app"))
// androidTestImplementation(TestLibs.junit)
//// androidTestImplementation(project(":res"))
// androidTestImplementation("androidx.test.ext:junit:1.1.2")
// androidTestImplementation("androidx.test.espresso:espresso-core:3.3.0")
// androidTestImplementation("androidx.test:rules:1.3.0")
// androidTestImplementation ("androidx.annotation:annotation:1.1.0")
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,36 +1,23 @@
package id.apwdevs.app.detail.dispatcher

import android.content.Context
import android.util.Log
import id.apwdevs.app.data.utils.Config
import id.apwdevs.app.detail.data.AssetData
import id.apwdevs.app.libs.util.provideResponse
import okhttp3.mockwebserver.Dispatcher
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.RecordedRequest
import id.apwdevs.app.libs.util.ScopeDispatcher

/**
* Dispatch all the network request needed for scope DetailItemFragment
* Must meet all the test case.
*/

class DetailScopeMockDispatcher(
private val context: Context
) : Dispatcher() {
context: Context
) : ScopeDispatcher(context) {

private val mappingRequest = mapOf(
override val mappingRequest = mapOf(
"/movie/791373?api_key=${Config.TOKEN}&language=en-US" to AssetData.DETAIL_MOVIE_OK,
"/tv/88396?api_key=${Config.TOKEN}&language=en-US" to AssetData.DETAIL_TVSHOW_OK,
"/genre/movie/list?api_key=${Config.TOKEN}&language=en-US" to AssetData.GENRE_MOVIE_OK,
"/genre/tv/list?api_key=${Config.TOKEN}&language=en-US" to AssetData.GENRE_TVSHOW_OK
)

override fun dispatch(request: RecordedRequest): MockResponse {
Log.d("MockDispatcher", "Received Request Path: ${request.path}")
val req = mappingRequest[request.path]
return req?.let {
context.provideResponse(it, 200)
} ?: context.provideResponse(AssetData.DETAIL_404, 404)
}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,27 +1,31 @@
package id.apwdevs.app.detail.ui

import androidx.appcompat.widget.AppCompatRatingBar
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.matcher.ViewMatchers.withResourceName
import androidx.test.ext.junit.runners.AndroidJUnit4
import id.apwdevs.app.data.source.remote.response.moviedetail.MovieDetailResponse
import id.apwdevs.app.data.source.remote.response.tvdetail.TvDetailResponse
import id.apwdevs.app.detail.dispatcher.DetailScopeMockDispatcher
import id.apwdevs.app.detail.ui.case.DetailItemFragmentCase
import id.apwdevs.app.detail.ui.helper.DetailMovieHelper
import id.apwdevs.app.res.util.PageType
import id.apwdevs.app.test.androdtest.utils.ViewAssertionRunner
import id.apwdevs.app.test.androdtest.utils.mustBeDisplayed
import id.apwdevs.app.test.androdtest.utils.mustDisplayedOnView
import id.apwdevs.app.test.androdtest.utils.swipeUp
import id.apwdevs.app.test.androdtest.utils.*
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.QueueDispatcher
import org.junit.Assert
import org.junit.runner.RunWith


@RunWith(AndroidJUnit4::class)
class DetailItemMovieCaseTest : DetailFragmentBaseCase() {
class DetailItemMovieCaseTest : DetailItemFragmentCase() {

override val defaultPageType: PageType
get() = PageType.MOVIES
override val defaultItemId: Int
get() = 791373

override fun setup() {
super.setup()
mockWebServer.dispatcher = DetailScopeMockDispatcher(context)
}

override fun should_decide_the_right_ui_helper_from_intent() {
launchFragment(itemId = 587807).apply {
Assert.assertTrue(detailHelper is DetailMovieHelper)
Expand All @@ -30,20 +34,82 @@ class DetailItemMovieCaseTest : DetailFragmentBaseCase() {

override fun should_display_data_when_success() {
val data = getDefaultData<MovieDetailResponse>()
super.should_display_data_when_success()
swipeUp()
launchFragment()

"title".thisViewMustBeDisplayed()
"poster_image".thisViewMustBeDisplayed()
"error_display".viewMustBeHidden()
"favorite_fab".thisViewMustBeDisplayed()

with(data) {
title.mustDisplayedOnView("title")
overview!!.mustDisplayedOnView("overview")
genres.forEach { it.name.mustBeDisplayed() }
onView(withResourceName("rating_bar")).check(ViewAssertionRunner {
Assert.assertNotNull(it)
Assert.assertEquals(voteAverage.toFloat(), (it as AppCompatRatingBar).rating)
})
}
}

override fun should_display_error_when_request_failing() {
mockWebServer.dispatcher = QueueDispatcher()
mockWebServer.enqueue(MockResponse().setResponseCode(404))
launchFragment(itemId = 76767)
"error_display".thisViewMustBeDisplayed()
"error_text".thisViewMustContainTextExactly("Failed to load resource. Try Again ?")
"btn_retry".thisViewMustBeDisplayed()
}

@Suppress("IMPLICIT_CAST_TO_ANY")
override fun should_reload_data_when_click_retry_button() {
val data = when (defaultPageType) {
PageType.MOVIES -> getDefaultData<MovieDetailResponse>()
PageType.TV_SHOW -> getDefaultData<TvDetailResponse>()
}

mockWebServer.dispatcher = QueueDispatcher()
mockWebServer.enqueue(MockResponse().setResponseCode(404))
launchFragment()
"error_display".thisViewMustBeDisplayed()

}
mockWebServer.dispatcher = DetailScopeMockDispatcher(context)

"btn_retry".clickThis()
data.let {
when (it) {
is MovieDetailResponse -> it.title.mustDisplayedOnView("title")
is TvDetailResponse -> it.name.mustDisplayedOnView("title")
}
}
}

override fun should_favorite_button_hide_and_favoritemenu_show_when_scroll_up() {
mockWebServer.dispatcher = DetailScopeMockDispatcher(context)

launchFragment()
"favorite_fab".thisViewMustBeDisplayed()
"favorite_menu".viewDoesNotExists()

// scroll up
swipeUp()

"favorite_fab".viewMustBeHidden()
"favorite_menu".thisViewMustBeDisplayed()
}

override fun should_change_favorite_icon_after_adding_and_remove_favorite() {
mockWebServer.dispatcher = DetailScopeMockDispatcher(context)

launchFragment()
// add to favorite
"favorite_fab".thisViewMustBeDisplayed()
"favorite_fab".clickThis()

// check, is the favorite ever shown, or toggle drawable changed ?
// for image view test, we need to check tag state on image view.
"favorite_fab".mustContainTagsExactly("favorited")

// cleanup
"favorite_fab".clickThis()
"favorite_fab".mustContainTagsExactly("unfavorited")
}


}
Loading

0 comments on commit 50bcca8

Please sign in to comment.