Skip to content
Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package com.randomboxd.feature.random_film.data

import androidx.room.Room
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import com.nacchofer31.randomboxd.core.data.UsernameDatabase
import com.nacchofer31.randomboxd.random_film.data.repository_impl.UserNameRepositoryImpl
import com.nacchofer31.randomboxd.random_film.domain.model.UserName
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import kotlin.test.assertEquals
import kotlin.test.assertTrue

@RunWith(AndroidJUnit4::class)
class UserNameRepositoryImplTest {
private lateinit var database: UsernameDatabase
private lateinit var repository: UserNameRepositoryImpl

@Before
fun setUp() {
val context = InstrumentationRegistry.getInstrumentation().targetContext
database =
Room
.inMemoryDatabaseBuilder(context, UsernameDatabase::class.java)
.allowMainThreadQueries()
.build()
repository = UserNameRepositoryImpl(database)
}

@After
fun tearDown() {
database.close()
}

@Test
fun getAllUserNames_returns_empty_list_initially() =
runBlocking {
val userNames = repository.getAllUserNames().first()
assertEquals(emptyList(), userNames)
}

@Test
fun addUserName_adds_new_username() =
runBlocking {
repository.addUserName("newuser")

val userNames = repository.getAllUserNames().first()

assertEquals(1, userNames.size)
assertEquals("newuser", userNames.first().username)
}

@Test
fun addUserName_does_not_add_duplicate_username() =
runBlocking {
repository.addUserName("existinguser")
repository.addUserName("existinguser")

val userNames = repository.getAllUserNames().first()

assertEquals(1, userNames.size)
}

@Test
fun addUserName_adds_multiple_different_usernames() =
runBlocking {
repository.addUserName("user1")
repository.addUserName("user2")
repository.addUserName("user3")

val userNames = repository.getAllUserNames().first()

assertEquals(3, userNames.size)
}

@Test
fun deleteUserName_removes_existing_username() =
runBlocking {
repository.addUserName("userToDelete")
val userNameToDelete =
database.userNameDao().getUserNameByValue("userToDelete")
?: UserName(username = "userToDelete")

repository.deleteUserName(userNameToDelete)

val userNames = repository.getAllUserNames().first()
assertTrue(userNames.isEmpty())
}

@Test
fun addUserName_does_not_add_same_user_after_delete_duplicate_check() =
runBlocking {
repository.addUserName("user1")
repository.addUserName("user2")
repository.addUserName("user1")

val userNames = repository.getAllUserNames().first()

assertEquals(2, userNames.size)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.randomboxd.feature.random_film.presentation

import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.nacchofer31.randomboxd.core.domain.DataError
import com.nacchofer31.randomboxd.random_film.presentation.components.FilmErrorView
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class FilmErrorViewTest {
@get:Rule
val composeTestRule = createComposeRule()

@Test
fun error_view_shows_no_results_title_for_no_results_error() {
composeTestRule.setContent {
FilmErrorView(error = DataError.Remote.NO_RESULTS)
}

composeTestRule.onNodeWithText("NO RESULTS FOUND").assertIsDisplayed()
}

@Test
fun error_view_shows_no_results_subtitle_for_no_results_error() {
composeTestRule.setContent {
FilmErrorView(error = DataError.Remote.NO_RESULTS)
}

composeTestRule.onNodeWithText("No movie matches the search. Please try again with another one.").assertIsDisplayed()
}

@Test
fun error_view_shows_connection_title_for_no_internet_error() {
composeTestRule.setContent {
FilmErrorView(error = DataError.Remote.NO_INTERNET)
}

composeTestRule.onNodeWithText("CONNECTION LOST").assertIsDisplayed()
}

@Test
fun error_view_shows_generic_title_for_unknown_error() {
composeTestRule.setContent {
FilmErrorView(error = DataError.Remote.UNKNOWN)
}

composeTestRule.onNodeWithText("SOMETHING WENT WRONG!").assertIsDisplayed()
}

@Test
fun error_view_shows_generic_title_for_server_error() {
composeTestRule.setContent {
FilmErrorView(error = DataError.Remote.SERVER)
}

composeTestRule.onNodeWithText("SOMETHING WENT WRONG!").assertIsDisplayed()
}

@Test
fun error_view_has_test_tag() {
composeTestRule.setContent {
FilmErrorView(error = DataError.Remote.NO_RESULTS)
}

composeTestRule.onNodeWithTag("test-film-error").assertIsDisplayed()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.randomboxd.feature.random_film.presentation

import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.nacchofer31.randomboxd.random_film.presentation.components.FilmHeader
import org.junit.Assert.assertTrue
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class FilmHeaderTest {
@get:Rule
val composeTestRule = createComposeRule()

@Test
fun film_header_shows_app_name() {
composeTestRule.setContent {
FilmHeader(onInfoClick = {})
}

composeTestRule.onNodeWithText("RandomBoxd").assertIsDisplayed()
}

@Test
fun film_header_shows_info_button_when_showInfoButton_is_true() {
composeTestRule.setContent {
FilmHeader(onInfoClick = {}, showInfoButton = true)
}

composeTestRule.onNodeWithContentDescription("Info").assertIsDisplayed()
}

@Test
fun film_header_hides_info_button_when_showInfoButton_is_false() {
composeTestRule.setContent {
FilmHeader(onInfoClick = {}, showInfoButton = false)
}

composeTestRule.onNodeWithContentDescription("Info").assertDoesNotExist()
}

@Test
fun film_header_info_button_triggers_callback() {
var clicked = false
composeTestRule.setContent {
FilmHeader(onInfoClick = { clicked = true })
}

composeTestRule.onNodeWithContentDescription("Info").performClick()

assertTrue(clicked)
}

@Test
fun film_header_shows_logo_icon() {
composeTestRule.setContent {
FilmHeader(onInfoClick = {})
}

composeTestRule.onNodeWithContentDescription("Logo").assertIsDisplayed()
}

@Test
fun film_header_hides_info_button_when_showInfoButton_is_null() {
composeTestRule.setContent {
FilmHeader(onInfoClick = {}, showInfoButton = null)
}

composeTestRule.onNodeWithContentDescription("Info").assertDoesNotExist()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package com.randomboxd.feature.random_film.presentation

import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.nacchofer31.randomboxd.random_film.domain.model.FilmSearchMode
import com.nacchofer31.randomboxd.random_film.presentation.components.UnionIntersectionSwitch
import org.junit.Assert.assertEquals
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class FilmSearchModeSwitchTest {
@get:Rule
val composeTestRule = createComposeRule()

@Test
fun switch_shows_intersection_and_union_labels() {
composeTestRule.setContent {
UnionIntersectionSwitch(
searchMode = FilmSearchMode.INTERSECTION,
onModeChange = {},
)
}

composeTestRule.onNodeWithText("INTERSECTION").assertIsDisplayed()
composeTestRule.onNodeWithText("UNION").assertIsDisplayed()
}

@Test
fun click_union_when_in_intersection_mode_calls_on_mode_change() {
var toggled = false
composeTestRule.setContent {
UnionIntersectionSwitch(
searchMode = FilmSearchMode.INTERSECTION,
onModeChange = { toggled = true },
)
}

composeTestRule.onNodeWithText("UNION").performClick()

assertEquals(true, toggled)
}

@Test
fun click_intersection_when_in_union_mode_calls_on_mode_change() {
var toggled = false
composeTestRule.setContent {
UnionIntersectionSwitch(
searchMode = FilmSearchMode.UNION,
onModeChange = { toggled = true },
)
}

composeTestRule.onNodeWithText("INTERSECTION").performClick()

assertEquals(true, toggled)
}

@Test
fun click_active_mode_does_not_call_on_mode_change() {
var toggleCount = 0
composeTestRule.setContent {
UnionIntersectionSwitch(
searchMode = FilmSearchMode.INTERSECTION,
onModeChange = { toggleCount++ },
)
}

composeTestRule.onNodeWithText("INTERSECTION").performClick()

assertEquals(0, toggleCount)
}

@Test
fun toggle_switches_between_modes() {
composeTestRule.setContent {
var mode by remember { mutableStateOf(FilmSearchMode.INTERSECTION) }
UnionIntersectionSwitch(
searchMode = mode,
onModeChange = {
mode =
if (mode == FilmSearchMode.INTERSECTION) {
FilmSearchMode.UNION
} else {
FilmSearchMode.INTERSECTION
}
},
)
}

composeTestRule.onNodeWithText("INTERSECTION").assertIsDisplayed()

composeTestRule.onNodeWithText("UNION").performClick()
composeTestRule.waitForIdle()

composeTestRule.onNodeWithText("UNION").assertIsDisplayed()
}
}
Loading