Skip to content

Commit

Permalink
Merge pull request #66 from RajashekarRaju/v0.3.0
Browse files Browse the repository at this point in the history
Merge all completed roadmap tasks into master
  • Loading branch information
RajashekarRaju committed May 11, 2023
2 parents 30fe5b1 + 15f4269 commit ba3dc2f
Show file tree
Hide file tree
Showing 36 changed files with 1,167 additions and 656 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
- [x] Restructure packages and files by introducing new source files.
- [ ] ~Replace every Spacer composable used in code with various custom AppSpacer.~
- [x] Separate the ViewModel param from Screen and UI composables to see previews for all screens.
- [ ] Break composables into smaller for previewing.
- [x] Break composables into smaller and move them to separate composables packages in each screen.
- [x] Break composables into smaller for previewing.
- [x] Separate composables into Screen and UI to separated ViewModel usage and previewing for all screens.
- [x] Add feature for adding actors to favorites like movies.
- [x] Add bottom sheet to home screen to support navigation for various screens.
- [x] Implement paging to upcoming lazy list movies in home tab.
Expand Down
6 changes: 3 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,12 @@ dependencies {

implementation 'androidx.core:core-ktx:1.10.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.8.0'
implementation 'com.google.android.material:material:1.9.0'
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.material:material:$compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation "androidx.compose.ui:ui-tooling:$compose_version"
implementation 'androidx.activity:activity-compose:1.7.0'
implementation 'androidx.activity:activity-compose:1.7.1'

// Observe state and livedata
implementation "androidx.compose.runtime:runtime-livedata:$compose_version"
Expand Down Expand Up @@ -107,7 +107,7 @@ dependencies {
kapt "com.google.dagger:hilt-android-compiler:2.44.2"

// Paging
implementation "androidx.paging:paging-compose:1.0.0-alpha18"
implementation "androidx.paging:paging-compose:1.0.0-alpha19"
implementation "androidx.paging:paging-runtime-ktx:3.1.1"

testImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,18 @@ package com.developersbreach.composeactors.ui.screens.home
import androidx.compose.runtime.Composable
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.paging.PagingData
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.developersbreach.composeactors.data.model.Movie
import com.developersbreach.composeactors.data.datasource.fake.nowPlayingMoviesList
import com.developersbreach.composeactors.data.datasource.fake.popularActorList
import com.developersbreach.composeactors.data.datasource.fake.trendingActorList
import com.developersbreach.composeactors.data.datasource.fake.upcomingMoviesList
import com.developersbreach.composeactors.ui.screens.search.SearchType
import kotlinx.coroutines.flow.flowOf
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
Expand All @@ -19,22 +26,32 @@ class HomeScreenUITest {
@get:Rule
val composeTestRule = createComposeRule()

private val mockHomeUIState: HomeUIState = HomeUIState(
popularActorList = popularActorList,
trendingActorList = trendingActorList,
isFetchingActors = false,
upcomingMoviesList = upcomingMoviesList,
nowPlayingMoviesList = flowOf(PagingData.from(nowPlayingMoviesList))
)

@Composable
private fun HomeScreenUIContent(
selectedActor: (actorId: Int) -> Unit = { },
selectedMovie: (movieId: Int) -> Unit = { },
favoriteMovies: List<Movie> = emptyList(),
updateSearchType: (searchType: SearchType) -> Unit = { },
navigateToSearchBySearchType: SearchType = SearchType.Actors,
homeSheetUIState: HomeSheetUIState = HomeSheetUIState(),
homeUIState: HomeUIState = HomeUIState()
homeUIState: HomeUIState = mockHomeUIState
) {
HomeScreenUI(
selectedActor = selectedActor,
selectedMovie = selectedMovie,
homeSheetUIState = homeSheetUIState,
favoriteMovies = favoriteMovies,
updateSearchType = updateSearchType,
homeUIState = homeUIState,
navigateToSelectedActor = selectedActor,
navigateToSelectedMovie = selectedMovie,
navigateToFavorite = {},
navigateToSearch = {},
navigateToSearchBySearchType = navigateToSearchBySearchType,
uiState = homeUIState,
sheetUiState = homeSheetUIState,
updateHomeSearchType = updateSearchType,
)
}

Expand All @@ -59,4 +76,82 @@ class HomeScreenUITest {
.assertIsDisplayed()
.performClick()
}

@Test
fun assertPopularAndTrendingActorsItemsAreVisibleInHomeScreen() {
composeTestRule.setContent {
HomeScreenUIContent()
}

composeTestRule
.onNodeWithText(text = "Monica Bellucci")
.assertIsDisplayed()

composeTestRule
.onNodeWithText(text = "Daniel Craig")
.assertIsDisplayed()
}

@Test
fun onClickAnyActorItem_InActorsTab_shouldNavigateToActorDetailsScreen() {
composeTestRule.setContent {
HomeScreenUIContent()
}

// We need to be in actors tab for actors list to appear and interact
composeTestRule
.onNodeWithText(text = "Actors")
.assertIsDisplayed()
.performClick()

// Click actor with name on home screen
composeTestRule
.onNodeWithText(text = "Monica Bellucci")
.assertIsDisplayed()
.performClick()

// If actors name visible in details screen, we have navigated to details screen
composeTestRule
.onNodeWithText("Monica Bellucci")
.assertIsDisplayed()
}

@Test
fun onClickAnyMovieItem_InMoviesTab_shouldNavigateToMovieDetailsScreen() {
composeTestRule.setContent {
HomeScreenUIContent()
}

// We need to be in movies tab for movies to appear and interact
composeTestRule
.onNodeWithText(text = "Movies")
.assertIsDisplayed()
.performClick()

// Click movie with name on home screen
composeTestRule
.onNodeWithContentDescription(label = "Oppenheimer")
.assertIsDisplayed()
.performClick()
}

@Test
fun onClickSearchTopAppBar_shouldNavigateToSearchScreen() {
composeTestRule.setContent {
HomeScreenUIContent(
navigateToSearchBySearchType = SearchType.Actors
)
}

// We need to be in actors tab for actors list to appear and interact
composeTestRule
.onNodeWithText(text = "Actors")
.assertIsDisplayed()
.performClick()

composeTestRule
.onNodeWithTag(testTag = "TestTag:HomeTopAppBar")
.assertExists()
.performClick()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package com.developersbreach.composeactors.data.datasource.fake

import com.developersbreach.composeactors.data.model.Actor
import com.developersbreach.composeactors.data.model.ActorDetail
import com.developersbreach.composeactors.data.model.Cast
import com.developersbreach.composeactors.data.model.FavoriteActor

private val actorsData = listOf(
"John travolta",
"Samuel L Jackson",
"Uma Thurman",
"Bruce Willis",
"Ving Rhames",
"Harvey Keitel",
"Tim Roth",
"Amanda Plummer",
"Quentin Tarantino",
"Christopher Walken",
"Eric Stoltz",
"Maria de Medeiros",
"Rosanna Arquette",
"Sophia Lillis",
)

fun fakeActorsList(): MutableList<Actor> {
val actors = mutableListOf<Actor>()
actorsData.forEachIndexed { index, name ->
actors.add(Actor(index, name, ""))
}
return actors
}

fun fakeFavoriteActorsList(): MutableList<FavoriteActor> {
val actors = mutableListOf<FavoriteActor>()
actorsData.forEachIndexed { index, name ->
actors.add(FavoriteActor(index, name, "", "Berlin"))
}
return actors
}

fun fakeMovieCastList(): MutableList<Cast> {
val cast = mutableListOf<Cast>()
actorsData.forEachIndexed { index, name ->
cast.add(Cast(index, name, ""))
}
return cast
}

val popularActorList = listOf(
Actor(
actorId = 28782,
actorName = "Monica Bellucci",
profileUrl = "z3sLuRKP7hQVrvSTsqdLjGSldwG.jpg"
),
Actor(
actorId = 287,
actorName = "Brad Pitt",
profileUrl = "kU3B75TyRiCgE270EyZnHjfivoq.jpg"
)
)

val trendingActorList = listOf(
Actor(
actorId = 8784,
actorName = "Daniel Craig",
profileUrl = "rFuETZeyOAfIqBahOObF7Soq5Dh.jpg"
),
Actor(
actorId = 1892,
actorName = "Matt Damon",
profileUrl = "7wbHIn7GziFlJLPl8Zu1XVl24EG.jpg"
),
)

val fakeActorDetail = ActorDetail(
actorId = 28782,
actorName = "Monica Bellucci",
profileUrl = "z3sLuRKP7hQVrvSTsqdLjGSldwG.jpg",
biography = "This is fake biography for the actor added here to see how the actual preview looks in the screen so don't get any serious about this.",
dateOfBirth = "59",
placeOfBirth = "Italy",
popularity = 43.0
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.developersbreach.composeactors.data.datasource.fake

import com.developersbreach.composeactors.data.model.Genre
import com.developersbreach.composeactors.data.model.Movie
import com.developersbreach.composeactors.data.model.MovieDetail

fun fakeMovieList(): MutableList<Movie> {
val movies = mutableListOf<Movie>()
listOf(
"Pulp Fiction",
"Kill Bill: Volume 1",
"Taxi Driver",
"Goodfellas",
"Kill Bill: Volume 2",
"Heat",
"Scarface",
"Scent of a Woman",
"The Devil's Advocate",
"The Prestige",
"Prisoners",
"American Psycho",
"Logan",
).forEachIndexed { index, name ->
movies.add(Movie(index, name, "", ""))
}

return movies
}

val upcomingMoviesList = listOf(
Movie(
movieId = 363736, movieName = "Oppenheimer", posterPathUrl = "", bannerUrl = ""
),
Movie(
movieId = 123434, movieName = "Dune", posterPathUrl = "", bannerUrl = ""
)
)

val nowPlayingMoviesList = listOf(
Movie(
movieId = 157336, movieName = "Interstellar", posterPathUrl = "", bannerUrl = ""
),
Movie(
movieId = 244786, movieName = "Whiplash", posterPathUrl = "", bannerUrl = ""
)
)

val fakeMovieDetail = MovieDetail(
movieId = 12345,
movieTitle = "Pulp Fiction",
banner = "banner-url.jpeg",
budget = "20 Million",
genres = listOf(Genre(1, "Thriller"), Genre(2, "Crime")),
originalLanguage = "English",
overview = "In the realm of underworld, a series of incidents intertwines the lives of two Los Angeles mobsters, a gangster's wife, a boxer and two small-time criminals.",
popularity = 99.0,
poster = "poster-url.jpeg",
productionCompanies = listOf("Whatever, WhoCares"),
releaseDate = "1994",
revenue = 21400000,
runtime = 154,
status = "Released",
tagline = "You won't know the facts until you've seen the fiction.",
voteAverage = 99.0,
)
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ class AppActions(
) {

// Triggered when user tries to navigate to details of an actor from list with Id.
val selectedActor: (Int) -> Unit = { actorId: Int ->
val navigateToSelectedActor: (Int) -> Unit = { actorId: Int ->
navController.navigate("${routes.ACTOR_DETAIL_ROUTE}/$actorId")
}

// Triggered when user tries to navigate to details of an actor from list with Id.
val selectedMovie: (Int) -> Unit = { movieId: Int ->
val navigateToSelectedMovie: (Int) -> Unit = { movieId: Int ->
navController.navigate("${routes.MOVIE_DETAILS_ROUTE}/$movieId")
}

Expand Down
Loading

0 comments on commit ba3dc2f

Please sign in to comment.