Skip to content

Commit

Permalink
test: add expandable floating action buttons tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Divinelink committed Oct 13, 2024
1 parent dfe1545 commit f79a15b
Show file tree
Hide file tree
Showing 7 changed files with 260 additions and 59 deletions.
76 changes: 76 additions & 0 deletions app/src/test/kotlin/com/andreolas/ui/details/DetailsContentTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.andreolas.ui.details

import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertIsNotDisplayed
import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.onAllNodesWithText
import androidx.compose.ui.test.onNodeWithContentDescription
Expand All @@ -13,6 +14,7 @@ import com.andreolas.factories.ReviewFactory
import com.andreolas.factories.details.domain.model.account.AccountMediaDetailsFactory
import com.andreolas.factories.details.domain.model.account.AccountMediaDetailsFactory.toWizard
import com.andreolas.movierama.R
import com.divinelink.core.model.details.DetailActionItem
import com.divinelink.core.model.details.DetailsMenuOptions
import com.divinelink.core.model.details.video.Video
import com.divinelink.core.model.details.video.VideoSite
Expand Down Expand Up @@ -516,5 +518,79 @@ class DetailsContentTest : ComposeTest() {
}
}

@Test
fun `test open request dialog for tv show`() {
setContentWithTheme {
DetailsContent(
viewState = DetailsViewState(
mediaId = 0,
mediaType = MediaType.TV,
actionButtons = DetailActionItem.entries,
mediaDetails = MediaDetailsFactory.TheOffice(),
),
onNavigateUp = {},
onMarkAsFavoriteClicked = {},
onSimilarMovieClicked = {},
onConsumeSnackbar = {},
onAddRateClicked = {},
onAddToWatchlistClicked = {},
requestMedia = {},
viewAllCreditsClicked = {},
onPersonClick = {},
)
}
composeTestRule
.onNodeWithText(getString(detailsR.string.feature_details_request))
.assertIsNotDisplayed()

composeTestRule
.onNodeWithTag(TestTags.Components.ExpandableFab.BUTTON)
.performClick()

composeTestRule
.onNodeWithText(getString(detailsR.string.feature_details_request))
.assertIsDisplayed()
.performClick()

composeTestRule.onNodeWithTag(TestTags.Dialogs.SELECT_SEASONS_DIALOG).assertIsDisplayed()
}

@Test
fun `test open request dialog for movie`() {
setContentWithTheme {
DetailsContent(
viewState = DetailsViewState(
mediaId = 0,
mediaType = MediaType.MOVIE,
actionButtons = DetailActionItem.entries,
mediaDetails = MediaDetailsFactory.FightClub(),
),
onNavigateUp = {},
onMarkAsFavoriteClicked = {},
onSimilarMovieClicked = {},
onConsumeSnackbar = {},
onAddRateClicked = {},
onAddToWatchlistClicked = {},
requestMedia = {},
viewAllCreditsClicked = {},
onPersonClick = {},
)
}
composeTestRule
.onNodeWithText(getString(detailsR.string.feature_details_request))
.assertIsNotDisplayed()

composeTestRule
.onNodeWithTag(TestTags.Components.ExpandableFab.BUTTON)
.performClick()

composeTestRule
.onNodeWithText(getString(detailsR.string.feature_details_request))
.assertIsDisplayed()
.performClick()

composeTestRule.onNodeWithTag(TestTags.Dialogs.REQUEST_MOVIE_DIALOG).assertIsDisplayed()
}

private val reviews = ReviewFactory.ReviewList()
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,4 @@ class GetDropdownMenuItemsUseCaseTest {
assertThat(result.getOrNull()).isEqualTo(listOf(DetailsMenuOptions.SHARE))
}
}
//
// @Test
// fun `test dropdown menu items with jellyseerr account`() = runTest {
// val preferenceStorage = FakePreferenceStorage(jellyseerrAccount = "jellyseerr_account")
// val useCase = GetDropdownMenuItemsUseCase(preferenceStorage, testDispatcher)
//
// useCase.invoke(Unit).first().let { result ->
// assertThat(result.isSuccess).isTrue()
// assertThat(result.getOrNull()).isEqualTo(
// listOf(
// DetailsMenuOptions.SHARE,
// DetailsMenuOptions.REQUEST,
// ),
// )
// }
// }
}
5 changes: 5 additions & 0 deletions core/ui/src/main/kotlin/com/divinelink/core/ui/TestTags.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ object TestTags {
const val TOP_APP_BAR = "Top App Bar"
const val TOP_APP_BAR_TITLE = "Top App Bar Title"
}

object ExpandableFab {
const val BACKGROUND = "Floating Button Background"
const val BUTTON = "Expandable Floating Action Button"
}
}

const val LOADING_CONTENT = "LOADING_CONTENT"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,14 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.IntOffset
import com.divinelink.core.designsystem.theme.AppTheme
import com.divinelink.core.designsystem.theme.dimensions
import com.divinelink.core.ui.IconWrapper
import com.divinelink.core.ui.Previews
import com.divinelink.core.ui.TestTags
import com.divinelink.core.ui.UIText
import com.divinelink.core.ui.getString
import com.divinelink.core.ui.snackbar.controller.LocalSnackbarController
Expand Down Expand Up @@ -95,6 +97,7 @@ fun ExpandableFloatActionButton(
Box(
modifier = Modifier
.background(MaterialTheme.colorScheme.surface.copy(alpha = 0.9f))
.testTag(TestTags.Components.ExpandableFab.BACKGROUND)
.fillMaxSize()
.clickable(
interactionSource = null,
Expand All @@ -121,9 +124,14 @@ fun ExpandableFloatActionButton(

FloatingActionButton(
onClick = { expanded = !expanded },
modifier = Modifier.rotate(rotationState),
modifier = Modifier
.testTag(TestTags.Components.ExpandableFab.BUTTON)
.rotate(rotationState),
) {
Icon(Icons.Rounded.Add, contentDescription = "Expandable FAB")
Icon(
imageVector = Icons.Rounded.Add,
contentDescription = "Expandable FAB",
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,44 +25,4 @@ class DetailsDropDownMenuTest : ComposeTest() {
TestTags.Menu.MENU_ITEM.format(getString(R.string.core_ui_share)),
).assertIsDisplayed()
}

// @Test
// fun `test open request dialog for tv show`() {
// composeTestRule.setContent {
// DetailsDropdownMenu(
// mediaDetails = MediaDetailsFactory.TheOffice(),
// menuOptions = listOf(DetailsMenuOptions.SHARE, DetailsMenuOptions.REQUEST),
// expanded = true,
// requestMedia = {},
// onDismissDropdown = {},
// )
// }
// composeTestRule.onNodeWithTag(
// TestTags.Menu.MENU_ITEM.format(getString(R.string.core_ui_dropdown_menu_request)),
// )
// .assertIsDisplayed()
// .performClick()
//
// composeTestRule.onNodeWithTag(TestTags.Dialogs.SELECT_SEASONS_DIALOG).assertIsDisplayed()
// }

// @Test
// fun `test open request dialog for movie`() {
// composeTestRule.setContent {
// DetailsDropdownMenu(
// mediaDetails = MediaDetailsFactory.FightClub(),
// menuOptions = listOf(DetailsMenuOptions.SHARE, DetailsMenuOptions.REQUEST),
// expanded = true,
// requestMedia = {},
// onDismissDropdown = {},
// )
// }
// composeTestRule.onNodeWithTag(
// TestTags.Menu.MENU_ITEM.format(getString(R.string.core_ui_dropdown_menu_request)),
// )
// .assertIsDisplayed()
// .performClick()
//
// composeTestRule.onNodeWithTag(TestTags.Dialogs.REQUEST_MOVIE_DIALOG).assertIsDisplayed()
// }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
package com.divinelink.core.ui.components.expandablefab

import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Add
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertIsNotDisplayed
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performClick
import com.divinelink.core.testing.ComposeTest
import com.divinelink.core.testing.setContentWithTheme
import com.divinelink.core.ui.IconWrapper
import com.divinelink.core.ui.R
import com.divinelink.core.ui.TestTags
import com.divinelink.core.ui.UIText
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test

class ExpandableFloatingActionButtonTest : ComposeTest() {

@Test
fun `test buttons are shown when fab button is clicked`() {
var extraActionIsClicked = false

val actionButtons = listOf(
FloatingActionButtonItem(
icon = IconWrapper.Vector(Icons.Rounded.Add),
label = UIText.StringText("Add"),
contentDescription = UIText.StringText("Add Button"),
onClick = { extraActionIsClicked = true },
),
FloatingActionButtonItem(
icon = IconWrapper.Image(R.drawable.core_ui_ic_jellyseerr),
label = UIText.StringText("Delete"),
contentDescription = UIText.StringText("Delete Button"),
onClick = { extraActionIsClicked = true },
),
FloatingActionButtonItem(
icon = IconWrapper.Icon(R.drawable.core_ui_ic_error_64),
label = UIText.StringText("Close"),
contentDescription = UIText.StringText("Close Button"),
onClick = { extraActionIsClicked = true },
),
)

setContentWithTheme {
ExpandableFloatActionButton(
buttons = actionButtons,
)
}

with(composeTestRule) {
onNodeWithTag(TestTags.Components.ExpandableFab.BUTTON).assertIsDisplayed()
onNodeWithContentDescription("Add Button").assertIsNotDisplayed()
onNodeWithContentDescription("Delete Button").assertIsNotDisplayed()
onNodeWithContentDescription("Close Button").assertIsNotDisplayed()

onNodeWithTag(TestTags.Components.ExpandableFab.BUTTON).performClick()

onNodeWithContentDescription("Add Button").assertIsDisplayed()
onNodeWithContentDescription("Delete Button").assertIsDisplayed()
onNodeWithContentDescription("Close Button").assertIsDisplayed()

assertThat(extraActionIsClicked).isFalse()

onNodeWithContentDescription("Add Button").performClick()

onNodeWithTag(TestTags.Components.ExpandableFab.BUTTON).assertIsDisplayed()

onNodeWithContentDescription("Add Button").assertIsNotDisplayed()
onNodeWithContentDescription("Delete Button").assertIsNotDisplayed()
onNodeWithContentDescription("Close Button").assertIsNotDisplayed()
assertThat(extraActionIsClicked).isTrue()
}
}

@Test
fun `test icons are displayed`() {
val actionButtons = listOf(
FloatingActionButtonItem(
icon = IconWrapper.Vector(Icons.Rounded.Add),
label = UIText.StringText("Add"),
contentDescription = UIText.StringText("Add Button"),
onClick = { },
),
FloatingActionButtonItem(
icon = IconWrapper.Image(R.drawable.core_ui_ic_jellyseerr),
label = UIText.StringText("Delete"),
contentDescription = UIText.StringText("Delete Button"),
onClick = { },
),
FloatingActionButtonItem(
icon = IconWrapper.Icon(R.drawable.core_ui_ic_error_64),
label = UIText.StringText("Close"),
contentDescription = UIText.StringText("Close Button"),
onClick = { },
),
)

setContentWithTheme {
ExpandableFloatActionButton(
buttons = actionButtons,
)
}

with(composeTestRule) {
onNodeWithTag(TestTags.Components.ExpandableFab.BUTTON).assertIsDisplayed()

onNodeWithContentDescription("Add Button").assertIsNotDisplayed()
onNodeWithContentDescription("Delete Button").assertIsNotDisplayed()
onNodeWithContentDescription("Close Button").assertIsNotDisplayed()

onNodeWithTag(TestTags.Components.ExpandableFab.BUTTON).performClick()

onNodeWithContentDescription("Add Button").assertIsDisplayed()
onNodeWithContentDescription("Delete Button").assertIsDisplayed()
onNodeWithContentDescription("Close Button").assertIsDisplayed()
}
}

@Test
fun `test clicking on background dismisses actions`() {
val actionButtons = listOf(
FloatingActionButtonItem(
icon = IconWrapper.Vector(Icons.Rounded.Add),
label = UIText.StringText("Add"),
contentDescription = UIText.StringText("Add Button"),
onClick = { },
),
FloatingActionButtonItem(
icon = IconWrapper.Image(R.drawable.core_ui_ic_jellyseerr),
label = UIText.StringText("Delete"),
contentDescription = UIText.StringText("Delete Button"),
onClick = { },
),
FloatingActionButtonItem(
icon = IconWrapper.Icon(R.drawable.core_ui_ic_error_64),
label = UIText.StringText("Close"),
contentDescription = UIText.StringText("Close Button"),
onClick = { },
),
)

setContentWithTheme {
ExpandableFloatActionButton(
buttons = actionButtons,
)
}

with(composeTestRule) {
onNodeWithTag(TestTags.Components.ExpandableFab.BUTTON).assertIsDisplayed()
onNodeWithContentDescription("Add Button").assertIsNotDisplayed()
onNodeWithContentDescription("Delete Button").assertIsNotDisplayed()
onNodeWithContentDescription("Close Button").assertIsNotDisplayed()

onNodeWithTag(TestTags.Components.ExpandableFab.BUTTON).performClick()

onNodeWithContentDescription("Add Button").assertIsDisplayed()
onNodeWithContentDescription("Delete Button").assertIsDisplayed()
onNodeWithContentDescription("Close Button").assertIsDisplayed()

onNodeWithTag(TestTags.Components.ExpandableFab.BACKGROUND).performClick()
onNodeWithContentDescription("Add Button").assertIsNotDisplayed()
onNodeWithContentDescription("Delete Button").assertIsNotDisplayed()
onNodeWithContentDescription("Close Button").assertIsNotDisplayed()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ fun DetailsContent(

SnackbarMessageHandler(
snackbarMessage = viewState.snackbarMessage,
onDismissSnackbar = { onConsumeSnackbar() },
onDismissSnackbar = onConsumeSnackbar,
)

var showRequestDialog by remember { mutableStateOf(false) }
Expand Down

0 comments on commit f79a15b

Please sign in to comment.