diff --git a/app/src/main/java/org/mozilla/fenix/library/LibrarySiteItemView.kt b/app/src/main/java/org/mozilla/fenix/library/LibrarySiteItemView.kt index caf269920..c444c0489 100644 --- a/app/src/main/java/org/mozilla/fenix/library/LibrarySiteItemView.kt +++ b/app/src/main/java/org/mozilla/fenix/library/LibrarySiteItemView.kt @@ -63,8 +63,6 @@ class LibrarySiteItemView @JvmOverloads constructor( val overflowView: ImageButton get() = overflow_menu - private var iconUrl: String? = null - init { LayoutInflater.from(context).inflate(R.layout.library_site_item, this, true) @@ -86,9 +84,6 @@ class LibrarySiteItemView @JvmOverloads constructor( } fun loadFavicon(url: String) { - if (iconUrl == url) return - - iconUrl = url context.components.core.icons.loadIntoView(favicon, url) } diff --git a/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkAdapter.kt b/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkAdapter.kt index da3d60526..2843bc443 100644 --- a/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkAdapter.kt +++ b/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkAdapter.kt @@ -14,10 +14,7 @@ import androidx.recyclerview.widget.RecyclerView import mozilla.appservices.places.BookmarkRoot import mozilla.components.concept.storage.BookmarkNode import mozilla.components.concept.storage.BookmarkNodeType -import org.mozilla.fenix.R import org.mozilla.fenix.library.LibrarySiteItemView -import org.mozilla.fenix.library.bookmarks.viewholders.BookmarkFolderViewHolder -import org.mozilla.fenix.library.bookmarks.viewholders.BookmarkItemViewHolder import org.mozilla.fenix.library.bookmarks.viewholders.BookmarkNodeViewHolder import org.mozilla.fenix.library.bookmarks.viewholders.BookmarkSeparatorViewHolder @@ -70,7 +67,8 @@ class BookmarkAdapter(private val emptyView: View, private val interactor: Bookm titleChanged = oldItem.title != newItem.title, urlChanged = oldItem.url != newItem.url, selectedChanged = oldItem in oldMode.selectedItems != newItem in newMode.selectedItems, - modeChanged = oldMode::class != newMode::class + modeChanged = oldMode::class != newMode::class, + iconChanged = oldItem.type != newItem.type || oldItem.url != newItem.url ) } @@ -79,24 +77,20 @@ class BookmarkAdapter(private val emptyView: View, private val interactor: Bookm } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { - val view = LayoutInflater.from(parent.context) - .inflate(R.layout.bookmark_list_item, parent, false) as LibrarySiteItemView + val view = LayoutInflater.from(parent.context).inflate(viewType, parent, false) return when (viewType) { - LibrarySiteItemView.ItemType.SITE.ordinal -> BookmarkItemViewHolder(view, interactor) - LibrarySiteItemView.ItemType.FOLDER.ordinal -> BookmarkFolderViewHolder(view, interactor) - BookmarkSeparatorViewHolder.LAYOUT_ID -> BookmarkSeparatorViewHolder(view) + BookmarkNodeViewHolder.LAYOUT_ID -> + BookmarkNodeViewHolder(view as LibrarySiteItemView, interactor) + BookmarkSeparatorViewHolder.LAYOUT_ID -> + BookmarkSeparatorViewHolder(view) else -> throw IllegalStateException("ViewType $viewType does not match to a ViewHolder") } } - override fun getItemViewType(position: Int): Int { - return when (tree[position].type) { - BookmarkNodeType.ITEM -> LibrarySiteItemView.ItemType.SITE.ordinal - BookmarkNodeType.FOLDER -> LibrarySiteItemView.ItemType.FOLDER.ordinal - BookmarkNodeType.SEPARATOR -> BookmarkSeparatorViewHolder.LAYOUT_ID - else -> throw IllegalStateException("Item $tree[position] does not match to a ViewType") - } + override fun getItemViewType(position: Int) = when (tree[position].type) { + BookmarkNodeType.ITEM, BookmarkNodeType.FOLDER -> BookmarkNodeViewHolder.LAYOUT_ID + BookmarkNodeType.SEPARATOR -> BookmarkSeparatorViewHolder.LAYOUT_ID } override fun getItemCount(): Int = tree.size @@ -106,16 +100,18 @@ class BookmarkAdapter(private val emptyView: View, private val interactor: Bookm position: Int, payloads: MutableList ) { - if (payloads.isNotEmpty() && payloads[0] is BookmarkPayload) { - (holder as? BookmarkNodeViewHolder) - ?.bind(tree[position], mode, payloads[0] as BookmarkPayload) - } else { - super.onBindViewHolder(holder, position, payloads) + (holder as? BookmarkNodeViewHolder)?.apply { + val diffPayload = if (payloads.isNotEmpty() && payloads[0] is BookmarkPayload) { + payloads[0] as BookmarkPayload + } else { + BookmarkPayload() + } + bind(tree[position], mode, diffPayload) } } override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { - (holder as? BookmarkNodeViewHolder)?.bind(tree[position], mode) + (holder as? BookmarkNodeViewHolder)?.bind(tree[position], mode, BookmarkPayload()) } } @@ -126,12 +122,22 @@ class BookmarkAdapter(private val emptyView: View, private val interactor: Bookm * @property urlChanged true if there has been a change to [BookmarkNode.url]. * @property selectedChanged true if there has been a change in the BookmarkNode's selected state. * @property modeChanged true if there has been a change in the state's mode type. + * @property iconChanged true if the icon displayed for the node should be changed. */ data class BookmarkPayload( val titleChanged: Boolean, val urlChanged: Boolean, val selectedChanged: Boolean, - val modeChanged: Boolean -) + val modeChanged: Boolean, + val iconChanged: Boolean +) { + constructor() : this( + titleChanged = true, + urlChanged = true, + selectedChanged = true, + modeChanged = true, + iconChanged = true + ) +} fun BookmarkNode.inRoots() = enumValues().any { it.id == guid } diff --git a/app/src/main/java/org/mozilla/fenix/library/bookmarks/viewholders/BookmarkFolderViewHolder.kt b/app/src/main/java/org/mozilla/fenix/library/bookmarks/viewholders/BookmarkFolderViewHolder.kt deleted file mode 100644 index 9d62e3bcd..000000000 --- a/app/src/main/java/org/mozilla/fenix/library/bookmarks/viewholders/BookmarkFolderViewHolder.kt +++ /dev/null @@ -1,81 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.fenix.library.bookmarks.viewholders - -import android.view.View -import androidx.appcompat.content.res.AppCompatResources -import androidx.core.content.ContextCompat -import mozilla.components.concept.storage.BookmarkNode -import org.mozilla.fenix.R -import org.mozilla.fenix.ext.hideAndDisable -import org.mozilla.fenix.ext.showAndEnable -import org.mozilla.fenix.library.LibrarySiteItemView -import org.mozilla.fenix.library.bookmarks.BookmarkFragmentState -import org.mozilla.fenix.library.bookmarks.BookmarkPayload -import org.mozilla.fenix.library.bookmarks.BookmarkViewInteractor -import org.mozilla.fenix.library.bookmarks.inRoots - -/** - * Represents a folder with other bookmarks inside. - */ -class BookmarkFolderViewHolder( - view: LibrarySiteItemView, - interactor: BookmarkViewInteractor -) : BookmarkNodeViewHolder(view, interactor) { - - override var item: BookmarkNode? = null - - init { - containerView.displayAs(LibrarySiteItemView.ItemType.FOLDER) - } - - override fun bind( - item: BookmarkNode, - mode: BookmarkFragmentState.Mode - ) { - bind(item, mode, BookmarkPayload(true, true, true, true)) - } - - override fun bind(item: BookmarkNode, mode: BookmarkFragmentState.Mode, payload: BookmarkPayload) { - this.item = item - - setSelectionListeners(item, mode) - - if (!item.inRoots()) { - updateMenu(item.type) - if (payload.modeChanged) { - if (mode is BookmarkFragmentState.Mode.Selecting) { - containerView.overflowView.hideAndDisable() - } else { - containerView.overflowView.showAndEnable() - } - } - } else { - containerView.overflowView.visibility = View.GONE - } - - if (payload.selectedChanged) { - containerView.changeSelected(item in mode.selectedItems) - } - - containerView.iconView.setImageDrawable( - AppCompatResources.getDrawable( - containerView.context, - R.drawable.ic_folder_icon - )?.apply { - setTint( - ContextCompat.getColor( - containerView.context, - R.color.primary_text_light_theme - ) - ) - } - ) - - if (payload.titleChanged) { - containerView.titleView.text = item.title - } - } -} diff --git a/app/src/main/java/org/mozilla/fenix/library/bookmarks/viewholders/BookmarkItemViewHolder.kt b/app/src/main/java/org/mozilla/fenix/library/bookmarks/viewholders/BookmarkItemViewHolder.kt deleted file mode 100644 index 1af60ec26..000000000 --- a/app/src/main/java/org/mozilla/fenix/library/bookmarks/viewholders/BookmarkItemViewHolder.kt +++ /dev/null @@ -1,76 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.fenix.library.bookmarks.viewholders - -import androidx.annotation.VisibleForTesting -import mozilla.components.concept.storage.BookmarkNode -import org.mozilla.fenix.ext.hideAndDisable -import org.mozilla.fenix.ext.showAndEnable -import org.mozilla.fenix.library.LibrarySiteItemView -import org.mozilla.fenix.library.bookmarks.BookmarkFragmentState -import org.mozilla.fenix.library.bookmarks.BookmarkPayload -import org.mozilla.fenix.library.bookmarks.BookmarkViewInteractor - -/** - * Represents a bookmarked website in the bookmarks page. - */ -class BookmarkItemViewHolder( - view: LibrarySiteItemView, - interactor: BookmarkViewInteractor -) : BookmarkNodeViewHolder(view, interactor) { - - override var item: BookmarkNode? = null - - init { - containerView.displayAs(LibrarySiteItemView.ItemType.SITE) - } - - override fun bind( - item: BookmarkNode, - mode: BookmarkFragmentState.Mode - ) { - bind(item, mode, BookmarkPayload(true, true, true, true)) - } - - override fun bind(item: BookmarkNode, mode: BookmarkFragmentState.Mode, payload: BookmarkPayload) { - this.item = item - - updateMenu(item.type) - - if (payload.modeChanged) { - if (mode is BookmarkFragmentState.Mode.Selecting) { - containerView.overflowView.hideAndDisable() - } else { - containerView.overflowView.showAndEnable() - } - } - - if (payload.selectedChanged) { - containerView.changeSelected(item in mode.selectedItems) - } - - if (payload.titleChanged) { - containerView.titleView.text = if (item.title.isNullOrBlank()) item.url else item.title - } else if (payload.urlChanged && item.title.isNullOrBlank()) { - containerView.titleView.text = item.url - } - - if (payload.urlChanged) { - containerView.urlView.text = item.url - setColorsAndIcons(item.url) - } - - setSelectionListeners(item, mode) - } - - @VisibleForTesting - internal fun setColorsAndIcons(url: String?) { - if (url != null && url.startsWith("http")) { - containerView.loadFavicon(url) - } else { - containerView.iconView.setImageDrawable(null) - } - } -} diff --git a/app/src/main/java/org/mozilla/fenix/library/bookmarks/viewholders/BookmarkNodeViewHolder.kt b/app/src/main/java/org/mozilla/fenix/library/bookmarks/viewholders/BookmarkNodeViewHolder.kt index e04f713fa..e7ab7ca5b 100644 --- a/app/src/main/java/org/mozilla/fenix/library/bookmarks/viewholders/BookmarkNodeViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/library/bookmarks/viewholders/BookmarkNodeViewHolder.kt @@ -4,45 +4,38 @@ package org.mozilla.fenix.library.bookmarks.viewholders +import android.view.View +import androidx.core.content.ContextCompat +import androidx.core.view.isVisible import androidx.recyclerview.widget.RecyclerView import mozilla.components.concept.storage.BookmarkNode import mozilla.components.concept.storage.BookmarkNodeType +import mozilla.components.support.ktx.android.content.getDrawableWithTint +import org.mozilla.fenix.R +import org.mozilla.fenix.ext.components +import org.mozilla.fenix.ext.hideAndDisable +import org.mozilla.fenix.ext.loadIntoView +import org.mozilla.fenix.ext.showAndEnable import org.mozilla.fenix.library.LibrarySiteItemView -import org.mozilla.fenix.library.SelectionHolder import org.mozilla.fenix.library.bookmarks.BookmarkFragmentState import org.mozilla.fenix.library.bookmarks.BookmarkItemMenu import org.mozilla.fenix.library.bookmarks.BookmarkPayload import org.mozilla.fenix.library.bookmarks.BookmarkViewInteractor +import org.mozilla.fenix.library.bookmarks.inRoots import org.mozilla.fenix.utils.Do /** * Base class for bookmark node view holders. */ -abstract class BookmarkNodeViewHolder( - protected val containerView: LibrarySiteItemView, +class BookmarkNodeViewHolder( + private val containerView: LibrarySiteItemView, private val interactor: BookmarkViewInteractor ) : RecyclerView.ViewHolder(containerView) { - abstract var item: BookmarkNode? - private lateinit var menu: BookmarkItemMenu + var item: BookmarkNode? = null + private val menu: BookmarkItemMenu init { - setupMenu() - } - - abstract fun bind(item: BookmarkNode, mode: BookmarkFragmentState.Mode) - - abstract fun bind( - item: BookmarkNode, - mode: BookmarkFragmentState.Mode, - payload: BookmarkPayload - ) - - protected fun setSelectionListeners(item: BookmarkNode, selectionHolder: SelectionHolder) { - containerView.setSelectionInteractor(item, selectionHolder, interactor) - } - - private fun setupMenu() { menu = BookmarkItemMenu(containerView.context) { menuItem -> val item = this.item ?: return@BookmarkItemMenu Do exhaustive when (menuItem) { @@ -58,5 +51,71 @@ abstract class BookmarkNodeViewHolder( containerView.attachMenu(menu.menuController) } - protected fun updateMenu(itemType: BookmarkNodeType) = menu.updateMenu(itemType) + fun bind( + item: BookmarkNode, + mode: BookmarkFragmentState.Mode, + payload: BookmarkPayload + ) { + this.item = item + + containerView.urlView.isVisible = item.type == BookmarkNodeType.ITEM + containerView.setSelectionInteractor(item, mode, interactor) + menu.updateMenu(item.type) + + // Hide menu button if this item is a root folder or is selected + if (item.type == BookmarkNodeType.FOLDER && item.inRoots()) { + containerView.overflowView.visibility = View.GONE + } else if (payload.modeChanged) { + if (mode is BookmarkFragmentState.Mode.Selecting) { + containerView.overflowView.hideAndDisable() + } else { + containerView.overflowView.showAndEnable() + } + } + + if (payload.selectedChanged) { + containerView.changeSelected(item in mode.selectedItems) + } + + val useTitleFallback = item.type == BookmarkNodeType.ITEM && item.title.isNullOrBlank() + if (payload.titleChanged) { + containerView.titleView.text = if (useTitleFallback) item.url else item.title + } else if (payload.urlChanged && useTitleFallback) { + containerView.titleView.text = item.url + } + + if (payload.urlChanged) { + containerView.urlView.text = item.url + } + + if (payload.iconChanged) { + updateIcon(item) + } + } + + private fun updateIcon(item: BookmarkNode) { + val context = containerView.context + val iconView = containerView.iconView + val url = item.url + + when { + // Item is a folder + item.type == BookmarkNodeType.FOLDER -> + iconView.setImageDrawable( + context.getDrawableWithTint( + R.drawable.ic_folder_icon, + ContextCompat.getColor(context, R.color.primary_text_light_theme) + ) + ) + // Item has a http/https URL + url != null && url.startsWith("http") -> + context.components.core.icons.loadIntoView(iconView, url) + else -> + iconView.setImageDrawable(null) + } + } + + companion object { + const val LAYOUT_ID = R.layout.bookmark_list_item + } } diff --git a/app/src/test/java/org/mozilla/fenix/library/bookmarks/viewholders/BookmarkFolderViewHolderTest.kt b/app/src/test/java/org/mozilla/fenix/library/bookmarks/viewholders/BookmarkFolderViewHolderTest.kt deleted file mode 100644 index 64d1c914e..000000000 --- a/app/src/test/java/org/mozilla/fenix/library/bookmarks/viewholders/BookmarkFolderViewHolderTest.kt +++ /dev/null @@ -1,87 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.fenix.library.bookmarks.viewholders - -import androidx.appcompat.content.res.AppCompatResources -import io.mockk.MockKAnnotations -import io.mockk.every -import io.mockk.impl.annotations.MockK -import io.mockk.mockk -import io.mockk.mockkStatic -import io.mockk.verify -import mozilla.components.concept.storage.BookmarkNode -import mozilla.components.concept.storage.BookmarkNodeType -import org.junit.Before -import org.junit.Test -import org.mozilla.fenix.ext.hideAndDisable -import org.mozilla.fenix.ext.showAndEnable -import org.mozilla.fenix.library.LibrarySiteItemView -import org.mozilla.fenix.library.bookmarks.BookmarkFragmentInteractor -import org.mozilla.fenix.library.bookmarks.BookmarkFragmentState -import org.mozilla.fenix.library.bookmarks.BookmarkPayload - -class BookmarkFolderViewHolderTest { - - @MockK - private lateinit var interactor: BookmarkFragmentInteractor - @MockK(relaxed = true) - private lateinit var siteItemView: LibrarySiteItemView - private lateinit var holder: BookmarkFolderViewHolder - - private val folder = BookmarkNode( - type = BookmarkNodeType.FOLDER, - guid = "456", - parentGuid = "123", - position = 0, - title = "Folder", - url = null, - children = listOf() - ) - - @Before - fun setup() { - MockKAnnotations.init(this) - - mockkStatic(AppCompatResources::class) - every { AppCompatResources.getDrawable(any(), any()) } returns mockk(relaxed = true) - - holder = BookmarkFolderViewHolder(siteItemView, interactor) - } - - @Test - fun `binds title and selected state`() { - holder.bind(folder, BookmarkFragmentState.Mode.Normal()) - - verify { - siteItemView.titleView.text = folder.title - siteItemView.overflowView.showAndEnable() - siteItemView.changeSelected(false) - } - - holder.bind(folder, BookmarkFragmentState.Mode.Selecting(setOf(folder))) - - verify { - siteItemView.titleView.text = folder.title - siteItemView.overflowView.hideAndDisable() - siteItemView.changeSelected(true) - } - } - - @Test - fun `bind with payload of no changes does not rebind views`() { - holder.bind( - folder, - BookmarkFragmentState.Mode.Normal(), - BookmarkPayload(false, false, false, false) - ) - - verify(inverse = true) { - siteItemView.titleView.text = folder.title - siteItemView.overflowView.showAndEnable() - siteItemView.overflowView.hideAndDisable() - siteItemView.changeSelected(any()) - } - } -} diff --git a/app/src/test/java/org/mozilla/fenix/library/bookmarks/viewholders/BookmarkItemViewHolderTest.kt b/app/src/test/java/org/mozilla/fenix/library/bookmarks/viewholders/BookmarkNodeViewHolderTest.kt similarity index 51% rename from app/src/test/java/org/mozilla/fenix/library/bookmarks/viewholders/BookmarkItemViewHolderTest.kt rename to app/src/test/java/org/mozilla/fenix/library/bookmarks/viewholders/BookmarkNodeViewHolderTest.kt index 0a1cd2f2d..7f0fbb21a 100644 --- a/app/src/test/java/org/mozilla/fenix/library/bookmarks/viewholders/BookmarkItemViewHolderTest.kt +++ b/app/src/test/java/org/mozilla/fenix/library/bookmarks/viewholders/BookmarkNodeViewHolderTest.kt @@ -4,13 +4,23 @@ package org.mozilla.fenix.library.bookmarks.viewholders +import androidx.appcompat.content.res.AppCompatResources +import io.mockk.Called import io.mockk.MockKAnnotations +import io.mockk.every import io.mockk.impl.annotations.MockK +import io.mockk.mockk +import io.mockk.mockkStatic +import io.mockk.unmockkStatic import io.mockk.verify +import mozilla.components.browser.icons.BrowserIcons +import mozilla.components.browser.icons.IconRequest import mozilla.components.concept.storage.BookmarkNode import mozilla.components.concept.storage.BookmarkNodeType +import org.junit.After import org.junit.Before import org.junit.Test +import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.hideAndDisable import org.mozilla.fenix.ext.showAndEnable import org.mozilla.fenix.library.LibrarySiteItemView @@ -18,15 +28,12 @@ import org.mozilla.fenix.library.bookmarks.BookmarkFragmentInteractor import org.mozilla.fenix.library.bookmarks.BookmarkFragmentState import org.mozilla.fenix.library.bookmarks.BookmarkPayload -class BookmarkItemViewHolderTest { +class BookmarkNodeViewHolderTest { - @MockK - private lateinit var interactor: BookmarkFragmentInteractor - - @MockK(relaxed = true) - private lateinit var siteItemView: LibrarySiteItemView - - private lateinit var holder: BookmarkItemViewHolder + @MockK private lateinit var interactor: BookmarkFragmentInteractor + @MockK(relaxed = true) private lateinit var siteItemView: LibrarySiteItemView + @MockK private lateinit var icons: BrowserIcons + private lateinit var holder: BookmarkNodeViewHolder private val item = BookmarkNode( type = BookmarkNodeType.ITEM, @@ -37,17 +44,45 @@ class BookmarkItemViewHolderTest { url = "https://www.mozilla.org", children = listOf() ) + private val folder = BookmarkNode( + type = BookmarkNodeType.FOLDER, + guid = "456", + parentGuid = "123", + position = 0, + title = "Folder", + url = null, + children = listOf() + ) + + private val falsePayload = BookmarkPayload( + titleChanged = false, + urlChanged = false, + selectedChanged = false, + modeChanged = false, + iconChanged = false + ) @Before fun setup() { MockKAnnotations.init(this) - holder = BookmarkItemViewHolder(siteItemView, interactor) + + mockkStatic(AppCompatResources::class) + every { AppCompatResources.getDrawable(any(), any()) } returns mockk(relaxed = true) + every { siteItemView.context.components.core.icons } returns icons + every { icons.loadIntoView(siteItemView.iconView, any()) } returns mockk() + + holder = BookmarkNodeViewHolder(siteItemView, interactor) + } + + @After + fun teardown() { + unmockkStatic(AppCompatResources::class) } @Test fun `binds views for unselected item`() { val mode = BookmarkFragmentState.Mode.Normal() - holder.bind(item, mode) + holder.bind(item, mode, BookmarkPayload()) verify { siteItemView.setSelectionInteractor(item, mode, interactor) @@ -55,14 +90,14 @@ class BookmarkItemViewHolderTest { siteItemView.urlView.text = item.url siteItemView.overflowView.showAndEnable() siteItemView.changeSelected(false) - holder.setColorsAndIcons(item.url) + icons.loadIntoView(siteItemView.iconView, IconRequest(item.url!!)) } } @Test - fun `binds views for selected item`() { + fun `binds views for selected item for item`() { val mode = BookmarkFragmentState.Mode.Selecting(setOf(item)) - holder.bind(item, mode) + holder.bind(item, mode, BookmarkPayload()) verify { siteItemView.setSelectionInteractor(item, mode, interactor) @@ -70,16 +105,15 @@ class BookmarkItemViewHolderTest { siteItemView.urlView.text = item.url siteItemView.overflowView.hideAndDisable() siteItemView.changeSelected(true) - holder.setColorsAndIcons(item.url) } } @Test - fun `bind with payload of no changes does not rebind views`() { + fun `bind with payload of no changes does not rebind views for item`() { holder.bind( item, BookmarkFragmentState.Mode.Normal(), - BookmarkPayload(false, false, false, false) + falsePayload ) verify(inverse = true) { @@ -88,28 +122,28 @@ class BookmarkItemViewHolderTest { siteItemView.overflowView.showAndEnable() siteItemView.overflowView.hideAndDisable() siteItemView.changeSelected(any()) - holder.setColorsAndIcons(item.url) } + verify { siteItemView.iconView wasNot Called } } @Test - fun `binding an item with a null title uses the url as the title`() { + fun `binding an item with a null title uses the url as the title for item`() { val item = item.copy(title = null) - holder.bind(item, BookmarkFragmentState.Mode.Normal()) + holder.bind(item, BookmarkFragmentState.Mode.Normal(), BookmarkPayload()) verify { siteItemView.titleView.text = item.url } } @Test - fun `binding an item with a blank title uses the url as the title`() { + fun `binding an item with a blank title uses the url as the title for item`() { val item = item.copy(title = " ") - holder.bind(item, BookmarkFragmentState.Mode.Normal()) + holder.bind(item, BookmarkFragmentState.Mode.Normal(), BookmarkPayload()) verify { siteItemView.titleView.text = item.url } } @Test - fun `rebinds title if item title is null and the item url has changed`() { + fun `rebinds title if item title is null and the item url has changed for item`() { val item = item.copy(title = null) holder.bind( item, @@ -118,7 +152,8 @@ class BookmarkItemViewHolderTest { titleChanged = false, urlChanged = true, selectedChanged = false, - modeChanged = false + modeChanged = false, + iconChanged = false ) ) @@ -126,7 +161,7 @@ class BookmarkItemViewHolderTest { } @Test - fun `rebinds title if item title is blank and the item url has changed`() { + fun `rebinds title if item title is blank and the item url has changed for item`() { val item = item.copy(title = " ") holder.bind( item, @@ -135,10 +170,46 @@ class BookmarkItemViewHolderTest { titleChanged = false, urlChanged = true, selectedChanged = false, - modeChanged = false + modeChanged = false, + iconChanged = false ) ) verify { siteItemView.titleView.text = item.url } } + + @Test + fun `binds title and selected state for folder`() { + holder.bind(folder, BookmarkFragmentState.Mode.Normal(), BookmarkPayload()) + + verify { + siteItemView.titleView.text = folder.title + siteItemView.overflowView.showAndEnable() + siteItemView.changeSelected(false) + } + + holder.bind(folder, BookmarkFragmentState.Mode.Selecting(setOf(folder)), BookmarkPayload()) + + verify { + siteItemView.titleView.text = folder.title + siteItemView.overflowView.hideAndDisable() + siteItemView.changeSelected(true) + } + } + + @Test + fun `bind with payload of no changes does not rebind views for folder`() { + holder.bind( + folder, + BookmarkFragmentState.Mode.Normal(), + falsePayload + ) + + verify(inverse = true) { + siteItemView.titleView.text = folder.title + siteItemView.overflowView.showAndEnable() + siteItemView.overflowView.hideAndDisable() + siteItemView.changeSelected(any()) + } + } }