diff --git a/feature/plp/src/main/java/com/mindera/alfie/feature/plp/ProductListTypeMapper.kt b/feature/plp/src/main/java/com/mindera/alfie/feature/plp/ProductListTypeMapper.kt index d9e12765..2765abca 100644 --- a/feature/plp/src/main/java/com/mindera/alfie/feature/plp/ProductListTypeMapper.kt +++ b/feature/plp/src/main/java/com/mindera/alfie/feature/plp/ProductListTypeMapper.kt @@ -4,27 +4,22 @@ import com.mindera.alfie.core.navigation.arguments.productlist.ProductListType import com.mindera.alfie.repository.productlist.model.ProductListQuerySource /** - * The BFF query source backing a [ProductListType]. + * Maps each [ProductListType] to the BFF query source that backs the list. * * [ProductListType.Search] threads its term straight through to `searchProducts`. Every other - * type currently falls back to [collectionHandle] because the BFF does not yet expose a query to - * resolve a collection handle from a category/brand slug or id — when it does, this is the single - * place that mapping needs to change. + * type uses its own slug/id directly as the collection handle for the `productList` query. */ -internal fun ProductListType.toQuerySource(collectionHandle: String): ProductListQuerySource = +internal fun ProductListType.toQuerySource(): ProductListQuerySource = when (this) { is ProductListType.Search -> ProductListQuerySource.Search(term = query) - is ProductListType.Category.Slug, - is ProductListType.Category.Id, - is ProductListType.Brand.Slug, - is ProductListType.Brand.Id -> ProductListQuerySource.Collection(handle = collectionHandle) + is ProductListType.Category.Slug -> ProductListQuerySource.Collection(handle = slug) + is ProductListType.Category.Id -> ProductListQuerySource.Collection(handle = id) + is ProductListType.Brand.Slug -> ProductListQuerySource.Collection(handle = slug) + is ProductListType.Brand.Id -> ProductListQuerySource.Collection(handle = id) } /** * Human-readable title for a [ProductListType], shown in the top bar. - * - * Note: for non-search lists this may not match the products shown while the collection handle is - * still hardcoded (see [toQuerySource]). */ internal val ProductListType.displayTitle: String get() = when (this) { diff --git a/feature/plp/src/main/java/com/mindera/alfie/feature/plp/ProductListViewModel.kt b/feature/plp/src/main/java/com/mindera/alfie/feature/plp/ProductListViewModel.kt index 8e1ae732..c6a61f0c 100644 --- a/feature/plp/src/main/java/com/mindera/alfie/feature/plp/ProductListViewModel.kt +++ b/feature/plp/src/main/java/com/mindera/alfie/feature/plp/ProductListViewModel.kt @@ -80,14 +80,6 @@ internal class ProductListViewModel @Inject constructor( private const val PREVIEW_DEBOUNCE_MS = 300L private const val PREVIEW_PAGE_SIZE = 1 - // Search is backed directly by the BFF `searchProducts` query (the search term comes - // straight from the nav args). For Category/Brand, the BFF does not yet expose a - // navigation/category lookup, so the collection handle falls back to "frontpage" as a - // placeholder until the BFF can resolve a handle from category slug/id or brand. The - // displayed title still uses nav args (see collectionTitle), so for non-search lists the - // title may not match the products shown — a known trade-off until that BFF work lands. - private const val COLLECTION_HANDLE = "frontpage" - private val initialPagerLoadState = LoadStates( refresh = LoadState.Loading, append = LoadState.NotLoading(false), @@ -102,8 +94,7 @@ internal class ProductListViewModel @Inject constructor( */ val collectionTitle: String = navArgs.type.displayTitle - /** The BFF query backing this list (see [toQuerySource]). */ - private val querySource: ProductListQuerySource = navArgs.type.toQuerySource(COLLECTION_HANDLE) + private val querySource: ProductListQuerySource = navArgs.type.toQuerySource() /** Non-null only in search mode; drives the search-specific no-results copy. */ val searchQuery: String? = (querySource as? ProductListQuerySource.Search)?.term diff --git a/feature/plp/src/test/java/com/mindera/alfie/feature/plp/ProductListPreviewCountTest.kt b/feature/plp/src/test/java/com/mindera/alfie/feature/plp/ProductListPreviewCountTest.kt index 28ccd8e2..966f8aae 100644 --- a/feature/plp/src/test/java/com/mindera/alfie/feature/plp/ProductListPreviewCountTest.kt +++ b/feature/plp/src/test/java/com/mindera/alfie/feature/plp/ProductListPreviewCountTest.kt @@ -124,7 +124,7 @@ class ProductListPreviewCountTest { fun `WHEN filters change THEN count is emitted only after the debounce`() = runTest { Dispatchers.setMain(StandardTestDispatcher(testScheduler)) coEvery { - getProductListUseCase(after = null, source = ProductListQuerySource.Collection("frontpage"), filters = previewFilters, sort = any(), limit = 1) + getProductListUseCase(after = null, source = ProductListQuerySource.Collection("women"), filters = previewFilters, sort = any(), limit = 1) } returns UseCaseResult.Success( ProductList(products = emptyList(), pagination = CursorPagination(endCursor = null, hasNextPage = false, totalCount = 42)) ) @@ -161,8 +161,8 @@ class ProductListPreviewCountTest { advanceUntilIdle() assertEquals(7, viewModel.state.value.previewResultCount) - coVerify(exactly = 1) { getProductListUseCase(null, ProductListQuerySource.Collection("frontpage"), previewFilters, any(), 1) } - coVerify(exactly = 0) { getProductListUseCase(null, ProductListQuerySource.Collection("frontpage"), firstFilters, any(), 1) } + coVerify(exactly = 1) { getProductListUseCase(null, ProductListQuerySource.Collection("women"), previewFilters, any(), 1) } + coVerify(exactly = 0) { getProductListUseCase(null, ProductListQuerySource.Collection("women"), firstFilters, any(), 1) } } @Test diff --git a/feature/plp/src/test/java/com/mindera/alfie/feature/plp/ProductListViewModelTest.kt b/feature/plp/src/test/java/com/mindera/alfie/feature/plp/ProductListViewModelTest.kt index b819ef35..78c61fe6 100644 --- a/feature/plp/src/test/java/com/mindera/alfie/feature/plp/ProductListViewModelTest.kt +++ b/feature/plp/src/test/java/com/mindera/alfie/feature/plp/ProductListViewModelTest.kt @@ -145,11 +145,11 @@ class ProductListViewModelTest { } @Test - fun `init - THEN uses hardcoded frontpage collection handle`() = runTest { + fun `init - THEN uses category slug as collection handle`() = runTest { buildViewModel() @Suppress("UnusedFlow") - verify { getPaginatedProductListUseCase(ProductListQuerySource.Collection("frontpage"), any(), any(), any(), any()) } + verify { getPaginatedProductListUseCase(ProductListQuerySource.Collection("women"), any(), any(), any(), any()) } } @Test diff --git a/feature/shop/src/main/java/com/mindera/alfie/feature/shop/ShopScreen.kt b/feature/shop/src/main/java/com/mindera/alfie/feature/shop/ShopScreen.kt index 00d50197..c18c4981 100644 --- a/feature/shop/src/main/java/com/mindera/alfie/feature/shop/ShopScreen.kt +++ b/feature/shop/src/main/java/com/mindera/alfie/feature/shop/ShopScreen.kt @@ -1,53 +1,29 @@ package com.mindera.alfie.feature.shop -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.stringResource -import androidx.compose.ui.tooling.preview.Preview import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavController -import com.mindera.alfie.core.commons.string.StringResource -import com.mindera.alfie.core.deeplink.DeeplinkHandler import com.mindera.alfie.core.navigation.DirectionProvider import com.mindera.alfie.core.navigation.Screen import com.mindera.alfie.core.navigation.arguments.shop.ShopNavArgs -import com.mindera.alfie.core.navigation.arguments.shop.ShopTab import com.mindera.alfie.core.navigation.arguments.wishlist.wishlistNavArgs -import com.mindera.alfie.core.ui.event.ClickEventOneArg -import com.mindera.alfie.core.ui.test.SERVICES_PAGE import com.mindera.alfie.designsystem.component.bottombar.BottomBarState -import com.mindera.alfie.designsystem.component.dialog.error.ErrorType -import com.mindera.alfie.designsystem.component.segmented.SegmentedItem -import com.mindera.alfie.designsystem.component.segmented.SegmentedPage import com.mindera.alfie.designsystem.component.snackbar.SnackbarCustomHostState import com.mindera.alfie.designsystem.component.topbar.TopBarState import com.mindera.alfie.designsystem.component.topbar.action.TopBarAction -import com.mindera.alfie.designsystem.theme.Theme -import com.mindera.alfie.feature.shop.brand.ShopBrandsScreen import com.mindera.alfie.feature.shop.category.ShopCategoriesScreen -import com.mindera.alfie.feature.shop.model.ShopUI import com.mindera.alfie.feature.shop.model.ShopUIState import com.mindera.alfie.feature.shop.ui.ShopErrorScreen -import com.mindera.alfie.feature.uievent.UIEvent import com.mindera.alfie.feature.uievent.handleUIEvent import com.mindera.alfie.feature.uievent.handleUIEvents -import com.mindera.alfie.feature.webview.WebViewContent -import com.mindera.alfie.feature.webview.WebViewEvent import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.navigation.DestinationsNavigator -import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf -import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.launch -import com.mindera.alfie.feature.R as FeatureR @Destination(navArgsDelegate = ShopNavArgs::class) @Composable @@ -57,8 +33,7 @@ internal fun ShopScreen( directionProvider: DirectionProvider, snackbarHostState: SnackbarCustomHostState, topBarState: TopBarState, - bottomBarState: BottomBarState, - shopNavArgs: ShopNavArgs + bottomBarState: BottomBarState ) { val viewModel: ShopViewModel = hiltViewModel() val state by viewModel.state.collectAsStateWithLifecycle() @@ -86,9 +61,7 @@ internal fun ShopScreen( when (state) { is ShopUIState.Data -> { - ShopScreenContent( - state = state as ShopUIState.Data, - initialTab = shopNavArgs.tab, + ShopCategoriesScreen( onUiEvent = { uiEvent -> coroutineScope.launch { uiEvent.handleUIEvent( @@ -98,9 +71,7 @@ internal fun ShopScreen( snackbarHostState = snackbarHostState ) } - }, - deeplinkHandler = viewModel.deeplinkHandler, - onWebViewEvent = { viewModel.run { handleWebViewEvent(it) } } + } ) } is ShopUIState.Error -> { @@ -110,68 +81,3 @@ internal fun ShopScreen( } } } - -@Composable -private fun ShopScreenContent( - state: ShopUIState.Data, - initialTab: ShopTab, - onUiEvent: ClickEventOneArg, - deeplinkHandler: DeeplinkHandler, - onWebViewEvent: ClickEventOneArg -) { - var selectedSegment by rememberSaveable { mutableIntStateOf(ShopTab.entries.indexOf(initialTab)) } - val segments: ImmutableList Unit>> = persistentListOf( - SegmentedItem(label = StringResource.fromId(R.string.shop_segment_categories)) to { - ShopCategoriesScreen( - onUiEvent = onUiEvent - ) - }, - SegmentedItem(label = StringResource.fromId(R.string.shop_segment_brands)) to { - ShopBrandsScreen( - onUiEvent = onUiEvent - ) - }, - SegmentedItem(label = StringResource.fromId(R.string.shop_segment_services)) to { - WebViewContent( - url = state.shopUI.servicesUrl, - queryParameters = emptyMap(), - headers = emptyMap(), - deeplinkHandler = deeplinkHandler, - onEvent = onWebViewEvent, - isBackHandlerEnabled = false, - modifier = Modifier.testTag(SERVICES_PAGE), - errorType = ErrorType( - message = stringResource(FeatureR.string.error_failed_to_load_page), - buttonLabel = stringResource(FeatureR.string.retry) - ) - ) - } - ) - - SegmentedPage( - segments = segments.map { it.first }.toImmutableList(), - selectedSegment = selectedSegment, - onSegmentClick = { selectedSegment = it }, - modifier = Modifier.fillMaxSize() - ) { page -> - segments[page].second() - } -} - -@Preview(showBackground = true) -@Composable -private fun ShopScreenPreview() { - Theme { - ShopScreenContent( - state = ShopUIState.Data( - shopUI = ShopUI( - servicesUrl = "servicesUrl" - ) - ), - initialTab = ShopTab.Categories, - onUiEvent = { }, - deeplinkHandler = DeeplinkHandler(emptySet()), - onWebViewEvent = { } - ) - } -} diff --git a/feature/shop/src/main/java/com/mindera/alfie/feature/shop/category/CategoryViewModel.kt b/feature/shop/src/main/java/com/mindera/alfie/feature/shop/category/CategoryViewModel.kt index 8be24845..4ab469a4 100644 --- a/feature/shop/src/main/java/com/mindera/alfie/feature/shop/category/CategoryViewModel.kt +++ b/feature/shop/src/main/java/com/mindera/alfie/feature/shop/category/CategoryViewModel.kt @@ -1,15 +1,7 @@ package com.mindera.alfie.feature.shop.category import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.mindera.alfie.core.analytics.AnalyticsManager -import com.mindera.alfie.core.analytics.params.EmptyParams import com.mindera.alfie.core.commons.string.StringResource -import com.mindera.alfie.domain.doOnResult -import com.mindera.alfie.domain.usecase.navigation.GetRootNavEntriesUseCase -import com.mindera.alfie.feature.mappers.toApiErrorType -import com.mindera.alfie.feature.mappers.toEventErrorValue -import com.mindera.alfie.feature.shop.category.factory.CategoryUIStateFactory import com.mindera.alfie.feature.shop.category.model.CategoryEntryUI import com.mindera.alfie.feature.shop.category.model.CategoryEvent import com.mindera.alfie.feature.shop.category.model.CategoryUIState @@ -18,31 +10,24 @@ import com.mindera.alfie.feature.shop.delegate.NavigateToEntryDelegate import com.mindera.alfie.feature.uievent.UIEventEmitter import com.mindera.alfie.feature.uievent.UIEventEmitterDelegate import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel internal class CategoryViewModel @Inject constructor( - private val getRootNavEntriesUseCase: GetRootNavEntriesUseCase, - private val uiFactory: CategoryUIStateFactory, - private val analyticsManager: AnalyticsManager, navigateToEntryDelegate: NavigateToEntryDelegate, uiEventEmitterDelegate: UIEventEmitterDelegate ) : ViewModel(), NavigateToEntry by navigateToEntryDelegate, UIEventEmitter by uiEventEmitterDelegate { - private val _state = MutableStateFlow(CategoryUIStateFactory.PLACEHOLDER) + private val _state = MutableStateFlow(STATIC_STATE) val state: StateFlow = _state.asStateFlow() - init { - loadCategories() - } - - fun retry() = loadCategories() + fun retry() = Unit fun handleEvent(event: CategoryEvent) { when (event) { @@ -50,28 +35,6 @@ internal class CategoryViewModel @Inject constructor( } } - private fun loadCategories() { - viewModelScope.launch { - getRootNavEntriesUseCase().doOnResult( - onSuccess = { - _state.value = uiFactory( - title = StringResource.EMPTY, - navEntries = it - ) - }, - onError = { - analyticsManager.trackError( - screenName = SCREEN_NAME, - eventName = EVENT_LOAD_ERROR, - eventErrorValue = it.type.toEventErrorValue(), - params = EmptyParams() - ) - _state.value = CategoryUIState.Error(it.type.toApiErrorType()) - } - ) - } - } - private fun navigateToCategoryEntry(entry: CategoryEntryUI) { val state = _state.value if (state is CategoryUIState.Data && entry.path.isNotEmpty()) { @@ -80,7 +43,22 @@ internal class CategoryViewModel @Inject constructor( } companion object { - private const val SCREEN_NAME = "shop_category" - private const val EVENT_LOAD_ERROR = "load_error" + private val STATIC_ENTRIES = listOf( + CategoryEntryUI(id = 0, title = StringResource.fromText("Women"), path = "women"), + CategoryEntryUI(id = 1, title = StringResource.fromText("Men"), path = "men"), + CategoryEntryUI(id = 2, title = StringResource.fromText("Featured"), path = "frontpage"), + CategoryEntryUI(id = 3, title = StringResource.fromText("Tops"), path = "womens-tops"), + CategoryEntryUI(id = 4, title = StringResource.fromText("Beauty"), path = "spring-summer"), + CategoryEntryUI(id = 5, title = StringResource.fromText("Bags"), path = "womens-bags"), + CategoryEntryUI(id = 6, title = StringResource.fromText("Dresses"), path = "dresses"), + CategoryEntryUI(id = 7, title = StringResource.fromText("Jackets"), path = "womens-jackets"), + CategoryEntryUI(id = 8, title = StringResource.fromText("Jeans"), path = "womens-jeans") + ).toImmutableList() + + private val STATIC_STATE = CategoryUIState.Data( + title = StringResource.EMPTY, + entries = STATIC_ENTRIES, + isLoading = false + ) } } diff --git a/feature/shop/src/main/java/com/mindera/alfie/feature/shop/delegate/NavigateToEntryDelegate.kt b/feature/shop/src/main/java/com/mindera/alfie/feature/shop/delegate/NavigateToEntryDelegate.kt index 5f7f9f2e..9e03ab67 100644 --- a/feature/shop/src/main/java/com/mindera/alfie/feature/shop/delegate/NavigateToEntryDelegate.kt +++ b/feature/shop/src/main/java/com/mindera/alfie/feature/shop/delegate/NavigateToEntryDelegate.kt @@ -5,10 +5,8 @@ import androidx.lifecycle.viewModelScope import com.mindera.alfie.core.deeplink.DeeplinkHandler import com.mindera.alfie.core.environment.EnvironmentManager import com.mindera.alfie.core.navigation.Screen -import com.mindera.alfie.core.navigation.arguments.categoryNavArgs import com.mindera.alfie.core.navigation.arguments.productlist.ProductListNavArgs import com.mindera.alfie.core.navigation.arguments.productlist.ProductListType -import com.mindera.alfie.domain.usecase.navigation.GetNavEntriesByParentIdUseCase import com.mindera.alfie.feature.shop.brand.model.BrandEntryUI import com.mindera.alfie.feature.shop.category.model.CategoryEntryUI import com.mindera.alfie.feature.uievent.UIEventEmitterDelegate @@ -18,7 +16,6 @@ import javax.inject.Inject @ViewModelScoped internal class NavigateToEntryDelegate @Inject constructor( - private val getNavEntriesByParentIdUseCase: GetNavEntriesByParentIdUseCase, private val deeplinkHandler: DeeplinkHandler, private val uiEventEmitterDelegate: UIEventEmitterDelegate, private val environmentManager: EnvironmentManager @@ -30,22 +27,20 @@ internal class NavigateToEntryDelegate @Inject constructor( override fun ViewModel.openCategoryEntry(entry: CategoryEntryUI) { viewModelScope.launch { - val environment = environmentManager.current() - val items = getNavEntriesByParentIdUseCase(parentId = entry.id) - - if (items.isEmpty() || entry.path == BRANDS_FIXED_PATH) { + if (entry.path == BRANDS_FIXED_PATH) { + val environment = environmentManager.current() deeplinkHandler.handle("${environment.webUrl}${entry.path}") - } else { - runUIEvent { - navigateTo( - Screen.Category( - args = categoryNavArgs( - id = entry.id, - title = entry.title - ) + return@launch + } + + runUIEvent { + navigateTo( + Screen.ProductList( + args = ProductListNavArgs( + type = ProductListType.Category.Slug(entry.path) ) ) - } + ) } } } diff --git a/feature/shop/src/test/java/com/mindera/alfie/feature/shop/category/CategoryViewModelTest.kt b/feature/shop/src/test/java/com/mindera/alfie/feature/shop/category/CategoryViewModelTest.kt index f33be15e..80a21723 100644 --- a/feature/shop/src/test/java/com/mindera/alfie/feature/shop/category/CategoryViewModelTest.kt +++ b/feature/shop/src/test/java/com/mindera/alfie/feature/shop/category/CategoryViewModelTest.kt @@ -1,47 +1,24 @@ package com.mindera.alfie.feature.shop.category -import com.mindera.alfie.core.analytics.AnalyticsManager import com.mindera.alfie.core.commons.string.StringResource import com.mindera.alfie.core.test.CoroutineExtension -import com.mindera.alfie.domain.UseCaseResult -import com.mindera.alfie.domain.usecase.navigation.GetRootNavEntriesUseCase -import com.mindera.alfie.feature.shop.category.factory.CategoryUIStateFactory import com.mindera.alfie.feature.shop.category.model.CategoryEntryUI import com.mindera.alfie.feature.shop.category.model.CategoryEvent -import com.mindera.alfie.feature.shop.categoryUiState import com.mindera.alfie.feature.shop.delegate.NavigateToEntryDelegate -import com.mindera.alfie.feature.shop.navEntries import com.mindera.alfie.feature.uievent.UIEventEmitterDelegate -import io.mockk.coEvery import io.mockk.impl.annotations.RelaxedMockK import io.mockk.junit5.MockKExtension import io.mockk.verify import kotlinx.coroutines.test.runTest -import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(MockKExtension::class, CoroutineExtension::class) internal class CategoryViewModelTest { - @RelaxedMockK - private lateinit var getRootNavEntriesUseCase: GetRootNavEntriesUseCase - - @RelaxedMockK - private lateinit var analyticsManager: AnalyticsManager - - @RelaxedMockK - private lateinit var uiFactory: CategoryUIStateFactory - @RelaxedMockK private lateinit var navigateToEntryDelegate: NavigateToEntryDelegate - @BeforeEach - fun setup() { - coEvery { getRootNavEntriesUseCase() } returns UseCaseResult.Success(navEntries) - coEvery { uiFactory(any(), any()) } returns categoryUiState - } - @Test fun `GIVEN OnEntryClickEvent WHEN entry path is not empty THEN should open the entry`() = runTest { val event = CategoryEvent.OnEntryClickEvent( @@ -81,9 +58,6 @@ internal class CategoryViewModelTest { } private fun buildViewModel() = CategoryViewModel( - getRootNavEntriesUseCase = getRootNavEntriesUseCase, - uiFactory = uiFactory, - analyticsManager = analyticsManager, navigateToEntryDelegate = navigateToEntryDelegate, uiEventEmitterDelegate = UIEventEmitterDelegate() ) diff --git a/feature/shop/src/test/java/com/mindera/alfie/feature/shop/delegate/NavigateToEntryDelegateTest.kt b/feature/shop/src/test/java/com/mindera/alfie/feature/shop/delegate/NavigateToEntryDelegateTest.kt index 3eb5976c..f4cf25a9 100644 --- a/feature/shop/src/test/java/com/mindera/alfie/feature/shop/delegate/NavigateToEntryDelegateTest.kt +++ b/feature/shop/src/test/java/com/mindera/alfie/feature/shop/delegate/NavigateToEntryDelegateTest.kt @@ -7,10 +7,8 @@ import com.mindera.alfie.core.environment.EnvironmentManager import com.mindera.alfie.core.environment.model.Environment import com.mindera.alfie.core.navigation.Screen import com.mindera.alfie.core.test.CoroutineExtension -import com.mindera.alfie.domain.usecase.navigation.GetNavEntriesByParentIdUseCase import com.mindera.alfie.feature.shop.brand.model.BrandEntryUI import com.mindera.alfie.feature.shop.category.model.CategoryEntryUI -import com.mindera.alfie.feature.shop.navEntries import com.mindera.alfie.feature.uievent.UIEventEmitter import com.mindera.alfie.feature.uievent.UIEventEmitterDelegate import io.mockk.coEvery @@ -31,9 +29,6 @@ internal class NavigateToEntryDelegateTest { private const val WEB_URL = "https://www.alfie.com" } - @RelaxedMockK - private lateinit var getNavEntriesByParentIdUseCase: GetNavEntriesByParentIdUseCase - @RelaxedMockK private lateinit var deeplinkHandler: DeeplinkHandler @@ -54,27 +49,8 @@ internal class NavigateToEntryDelegateTest { ) } - @Test - fun `GIVEN openCategoryEntry WHEN entry has child entries THEN navigate to category`() = runTest { - coEvery { getNavEntriesByParentIdUseCase(any()) } returns navEntries - val entry = CategoryEntryUI( - id = 1, - title = StringResource.fromText("title"), - path = "https://url.com" - ) - val viewModel = TestViewModel(delegate, uiEventEmitterDelegate) - - with(viewModel) { - openCategoryEntry(entry) - - coVerify(exactly = 0) { deeplinkHandler.handle(any()) } - coVerify { navigateTo(screen = any(Screen.Category::class)) } - } - } - @Test fun `GIVEN openCategoryEntry WHEN entry is brands THEN navigate to Brands shop screen`() = runTest { - coEvery { getNavEntriesByParentIdUseCase(any()) } returns emptyList() coEvery { uiEventEmitterDelegate.uiEvent } coJustRun { deeplinkHandler.handle(any()) } @@ -94,19 +70,18 @@ internal class NavigateToEntryDelegateTest { } @Test - fun `GIVEN openCategoryEntry WHEN entry is childless THEN navigate to plp`() = runTest { - coEvery { getNavEntriesByParentIdUseCase(any()) } returns emptyList() - val path = "/plp/path" + fun `GIVEN openCategoryEntry WHEN entry is a leaf category THEN navigate to plp`() = runTest { val entry = CategoryEntryUI( id = 1, title = StringResource.fromText("title"), - path = path + path = "women" ) val viewModel = TestViewModel(delegate, uiEventEmitterDelegate) with(viewModel) { openCategoryEntry(entry) - coVerify { deeplinkHandler.handle("$WEB_URL$path") } + coVerify(exactly = 0) { deeplinkHandler.handle(any()) } + coVerify { navigateTo(screen = any(Screen.ProductList::class)) } } }